Migrate CI to github actions
This commit is contained in:
@@ -1,22 +0,0 @@
|
||||
trigger:
|
||||
batch: true
|
||||
branches:
|
||||
include:
|
||||
- '*'
|
||||
tags:
|
||||
include:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
- job: Build
|
||||
steps:
|
||||
# On every PR, build the addon and make it available for download as an artifact
|
||||
- template: build.yml
|
||||
parameters:
|
||||
py_versions: [ 'py2', 'py3' ]
|
||||
|
||||
# When triggered by a tag, publish the built addon to the repo server
|
||||
- ${{ if startsWith(variables['Build.SourceBranch'], 'refs/tags') }}:
|
||||
- template: publish.yml
|
||||
parameters:
|
||||
py_versions: [ 'py2', 'py3' ]
|
||||
@@ -1,45 +0,0 @@
|
||||
parameters:
|
||||
python_versions : []
|
||||
|
||||
steps:
|
||||
- ${{ each py_version in parameters.py_versions }}:
|
||||
- task: usePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '3.6'
|
||||
|
||||
- checkout: self
|
||||
clean: true
|
||||
|
||||
- script: python3 -m pip install --user -r jellycon/requirements-dev.txt
|
||||
displayName: 'Install dev dependencies'
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Create clean addon directory'
|
||||
inputs:
|
||||
sourceFolder: 'jellycon'
|
||||
cleanTargetFolder: true
|
||||
contents: |
|
||||
**/*
|
||||
!.ci/*
|
||||
!.git/**/*
|
||||
!.github/*
|
||||
TargetFolder: '$(Build.ArtifactStagingDirectory)/plugin.video.jellycon'
|
||||
|
||||
- script: python3 '$(Build.ArtifactStagingDirectory)/plugin.video.jellycon/build.py' --version ${{ py_version }} --target '$(Build.ArtifactStagingDirectory)/'
|
||||
displayName: 'Create ${{ py_version }} addon.xml'
|
||||
|
||||
- task: ArchiveFiles@2
|
||||
displayName: 'Create ${{ py_version }} zip file'
|
||||
inputs:
|
||||
rootFolderOrFile: '$(Build.ArtifactStagingDirectory)/plugin.video.jellycon'
|
||||
includeRootFolder: True
|
||||
archiveType: 'zip'
|
||||
tarCompression: 'none'
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/plugin.video.jellycon-${{ py_version }}.zip'
|
||||
|
||||
- task: PublishPipelineArtifact@1
|
||||
displayName: 'Publish ${{ py_version }} artifact'
|
||||
inputs:
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)/plugin.video.jellycon'
|
||||
artifactName: 'plugin.video.jellycon-${{ py_version }}-$(Build.BuildNumber)'
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
parameters:
|
||||
python_version : []
|
||||
|
||||
steps:
|
||||
- ${{ each py_version in parameters.py_versions }}:
|
||||
- task: CopyFilesOverSSH@0
|
||||
displayName: 'Upload to repo server'
|
||||
inputs:
|
||||
sshEndpoint: repository
|
||||
sourceFolder: '$(Build.ArtifactStagingDirectory)'
|
||||
contents: 'plugin.video.jellycon-${{ py_version }}.zip'
|
||||
targetFolder: '/srv/repository/incoming/kodi'
|
||||
|
||||
- task: SSH@0
|
||||
displayName: 'Add to Kodi repo'
|
||||
inputs:
|
||||
sshEndpoint: repository
|
||||
runOptions: 'commands'
|
||||
commands: 'python3 /usr/local/bin/kodirepo add /srv/repository/incoming/kodi/plugin.video.jellycon-${{ py_version }}.zip --datadir /srv/repository/releases/client/kodi/${{ py_version }}'
|
||||
failOnStdErr: false
|
||||
|
||||
- task: SSH@0
|
||||
displayName: 'Clean up zip files'
|
||||
inputs:
|
||||
sshEndpoint: repository
|
||||
runOptions: 'commands'
|
||||
commands: 'rm /srv/repository/incoming/kodi/plugin.video.jellycon-${{ py_version }}.zip'
|
||||
16
.github/dependabot.yaml
vendored
Normal file
16
.github/dependabot.yaml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
labels:
|
||||
- ci
|
||||
- github-actions
|
||||
- package-ecosystem: pip
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
labels:
|
||||
- pip
|
||||
- dependencies
|
||||
22
.github/release-drafter.yml
vendored
Normal file
22
.github/release-drafter.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
_extends: jellyfin/jellyfin-meta-plugins
|
||||
|
||||
name-template: "Release $RESOLVED_VERSION"
|
||||
tag-template: "v$RESOLVED_VERSION"
|
||||
version-template: "$MAJOR.$MINOR.$PATCH"
|
||||
|
||||
version-resolver:
|
||||
major:
|
||||
labels:
|
||||
- 'major'
|
||||
minor:
|
||||
labels:
|
||||
- 'minor'
|
||||
patch:
|
||||
labels:
|
||||
- 'patch'
|
||||
default: patch
|
||||
|
||||
template: |
|
||||
## :sparkles: What's New
|
||||
|
||||
$CHANGES
|
||||
12
.github/releasing.md
vendored
Normal file
12
.github/releasing.md
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# Releasing a new Version via GitHub Actions
|
||||
|
||||
0. (optional) label the PRs you want to include in this release (if you want to group them in the GH release based on topics). \
|
||||
Supported labels can be found in the Release Drafter [config-file](https://github.com/jellyfin/jellyfin-meta-plugins/blob/master/.github/release-drafter.yml) (currently inherited from `jellyfin/jellyfin-meta-plugins`)
|
||||
1. ensure you have merged the PRs you want to include in the release and that the so far drafted GitHub release has captured them
|
||||
2. Create a `release-prep` PR by manually triggering the 'Create Prepare-Release PR' Workflow from the Actions tab on GitHub
|
||||
3. check the newly created `Prepare for release vx.y.z` PR if updated the `release.yaml` properly (update it manually if need be)
|
||||
4. merge the `Prepare for release vx.y.z` and let the Actions triggered by doing that finis (should just be a couple of seconds)
|
||||
5. FINALLY, trigger the `Publish JellyCon` manually from the Actions tab on GitHub.
|
||||
1. this will release the up to that point drafted GitHub Release and tag the default branch accordingly
|
||||
2. this will package and deploy `JellyCon` in the new version to the deployment server and trigger the 'kodirepo' script on it
|
||||
6. Done, assuming everything ran successfully, you have now successfully published a new version! :tada:
|
||||
87
.github/tools/reformat_changelog.py
vendored
Executable file
87
.github/tools/reformat_changelog.py
vendored
Executable file
@@ -0,0 +1,87 @@
|
||||
#!/usr/bin/env python3.8
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import re
|
||||
from typing import Dict, List, Pattern, Union, TypedDict
|
||||
|
||||
from emoji.core import emojize, demojize, replace_emoji
|
||||
|
||||
|
||||
ITEM_FORMAT = "+ {title} (#{issue}) @{username}"
|
||||
OUTPUT_EMOJI = False
|
||||
|
||||
ITEM_PATTERN: Pattern = re.compile(
|
||||
r"^\s*(?P<old_listchar>[-*+])\s*(?P<title>.*?)\s*\(#(?P<issue>[0-9]+)\)\s*@(?P<username>[^\s]*)$"
|
||||
)
|
||||
|
||||
|
||||
class SectionType(TypedDict):
|
||||
title: str
|
||||
items: List[Dict[str, str]]
|
||||
|
||||
|
||||
def reformat(item_format: str, output_emoji: bool) -> None:
|
||||
data = [
|
||||
emojize(x.strip(), use_aliases=True, variant="emoji_type")
|
||||
for x in sys.stdin.readlines()
|
||||
if x.strip()
|
||||
]
|
||||
|
||||
sections = []
|
||||
|
||||
section: Union[SectionType, Dict] = {}
|
||||
for line in data:
|
||||
if line.startswith("## "):
|
||||
pass
|
||||
if line.startswith("### "):
|
||||
if section:
|
||||
sections.append(section)
|
||||
_section: SectionType = {
|
||||
"title": line.strip("# "),
|
||||
"items": [],
|
||||
}
|
||||
section = _section
|
||||
|
||||
m = ITEM_PATTERN.match(line)
|
||||
if m:
|
||||
gd = m.groupdict()
|
||||
section["items"].append(gd)
|
||||
|
||||
sections.append(section)
|
||||
|
||||
first = True
|
||||
|
||||
for section in sections:
|
||||
if not section:
|
||||
continue
|
||||
if first:
|
||||
first = False
|
||||
else:
|
||||
print()
|
||||
|
||||
title = section["title"]
|
||||
if not output_emoji:
|
||||
title = replace_emoji(title).strip()
|
||||
|
||||
print(title)
|
||||
print("-" * len(title))
|
||||
|
||||
for item in section["items"]:
|
||||
formatted_item = item_format.format(**item)
|
||||
if not output_emoji:
|
||||
formatted_item = demojize(formatted_item)
|
||||
print(formatted_item)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--format", type=str, default=ITEM_FORMAT)
|
||||
|
||||
parser.add_argument("--no-emoji", dest="emoji", action="store_false")
|
||||
parser.add_argument("--emoji", dest="emoji", action="store_true")
|
||||
parser.set_defaults(emoji=OUTPUT_EMOJI)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
reformat(args.format, args.emoji)
|
||||
39
.github/workflows/build.yaml
vendored
Normal file
39
.github/workflows/build.yaml
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
name: Build JellyCon
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
py_version: [ 'py2', 'py3' ]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Python 3.x
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.9
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install pyyaml
|
||||
|
||||
- name: Create ${{ matrix.py_version }} addon.xml
|
||||
run: python build.py --version ${{ matrix.py_version }}
|
||||
|
||||
- name: Publish Build Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
retention-days: 14
|
||||
name: ${{ matrix.py_version }}-build-artifact
|
||||
path: |
|
||||
*.zip
|
||||
41
.github/workflows/codeql.yaml
vendored
Normal file
41
.github/workflows/codeql.yaml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
name: CodeQL Analysis
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
schedule:
|
||||
- cron: '38 8 * * 6'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'jellyfin/jellycon' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'python' ]
|
||||
version: ['2.7', '3.9']
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
queries: +security-and-quality
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.version }}
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
72
.github/workflows/create-prepare-release-pr.yaml
vendored
Normal file
72
.github/workflows/create-prepare-release-pr.yaml
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
name: Create Prepare-Release PR
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
create_pr:
|
||||
name: "Create Pump Version PR"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Update Draft
|
||||
uses: release-drafter/release-drafter@v5.15.0
|
||||
id: draft
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.JF_BOT_TOKEN }}
|
||||
|
||||
- name: Setup YQ
|
||||
uses: chrisdickinson/setup-yq@latest
|
||||
with:
|
||||
yq-version: v4.9.1
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Parse Changlog
|
||||
run: |
|
||||
pip install emoji
|
||||
cat << EOF >> cl.md
|
||||
${{ steps.draft.outputs.body }}
|
||||
EOF
|
||||
TAG="${{ steps.draft.outputs.tag_name }}"
|
||||
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
|
||||
echo "YAML_CHANGELOG<<EOF" >> $GITHUB_ENV
|
||||
cat cl.md | python .github/tools/reformat_changelog.py --no-emoji >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
echo "CHANGELOG<<EOF" >> $GITHUB_ENV
|
||||
cat cl.md | python .github/tools/reformat_changelog.py --emoji --format='+ #{issue} by @{username}' >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
rm cl.md
|
||||
|
||||
- name: Update release.yaml
|
||||
run: |
|
||||
yq eval '.version = env(VERSION) | .changelog = strenv(YAML_CHANGELOG) | .changelog style="literal"' -i release.yaml
|
||||
|
||||
- name: Commit Changes
|
||||
run: |
|
||||
git config user.name "jellyfin-bot"
|
||||
git config user.email "team@jellyfin.org"
|
||||
|
||||
git checkout -b prepare-${{ env.VERSION }}
|
||||
git commit -am "bump version to ${{ env.VERSION }}"
|
||||
|
||||
if [[ -z "$(git ls-remote --heads origin prepare-${{ env.VERSION }})" ]]; then
|
||||
git push origin prepare-${{ env.VERSION }}
|
||||
else
|
||||
git push -f origin prepare-${{ env.VERSION }}
|
||||
fi
|
||||
|
||||
- name: Create or Update PR
|
||||
uses: k3rnels-actions/pr-update@v1
|
||||
with:
|
||||
token: ${{ secrets.JF_BOT_TOKEN }}
|
||||
pr_title: Prepare for release ${{ steps.draft.outputs.tag_name }}
|
||||
pr_source: prepare-${{ env.VERSION }}
|
||||
pr_labels: 'release-prep,skip-changelog'
|
||||
pr_body: |
|
||||
:robot: This is a generated PR to bump the `release.yaml` version and update the changelog.
|
||||
|
||||
---
|
||||
|
||||
${{ env.CHANGELOG }}
|
||||
64
.github/workflows/publish.yaml
vendored
Normal file
64
.github/workflows/publish.yaml
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
name: Publish JellyCon
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
py_version: [ 'py2', 'py3' ]
|
||||
steps:
|
||||
- name: Update Draft
|
||||
uses: release-drafter/release-drafter@v5.15.0
|
||||
if: ${{ matrix.py_version == 'py3' }}
|
||||
with:
|
||||
publish: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.JF_BOT_TOKEN }}
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Python 3.x
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.9
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install pyyaml
|
||||
|
||||
- name: Create ${{ matrix.py_version }} addon.xml
|
||||
run: python build.py --version ${{ matrix.py_version }}
|
||||
|
||||
- name: Publish Build Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
retention-days: 14
|
||||
name: ${{ matrix.py_version }}-build-artifact
|
||||
path: |
|
||||
*.zip
|
||||
|
||||
- name: Upload to repo server
|
||||
uses: burnett01/rsync-deployments@5.1
|
||||
with:
|
||||
switches: -vrptz
|
||||
path: '*.zip'
|
||||
remote_path: /srv/repository/incoming/kodi
|
||||
remote_host: ${{ secrets.DEPLOY_HOST }}
|
||||
remote_user: ${{ secrets.DEPLOY_USER }}
|
||||
remote_key: ${{ secrets.DEPLOY_KEY }}
|
||||
|
||||
- name: Add to Kodi repo and clean up
|
||||
uses: appleboy/ssh-action@v0.1.4
|
||||
with:
|
||||
host: ${{ secrets.DEPLOY_HOST }}
|
||||
username: ${{ secrets.DEPLOY_USER }}
|
||||
key: ${{ secrets.DEPLOY_KEY }}
|
||||
script_stop: true
|
||||
script: |
|
||||
python3 /usr/local/bin/kodirepo add /srv/repository/incoming/kodi/plugin.video.jellycon+${{ matrix.py_version }}.zip --datadir /srv/repository/releases/client/kodi/${{ matrix.py_version }};
|
||||
rm /srv/repository/incoming/kodi/plugin.video.jellycon+${{ matrix.py_version }}.zip;
|
||||
16
.github/workflows/release-drafter.yaml
vendored
Normal file
16
.github/workflows/release-drafter.yaml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
name: Release Drafter
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
update_release_draft:
|
||||
name: Update release draft
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Update Release Draft
|
||||
uses: release-drafter/release-drafter@v5.15.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.JF_BOT_TOKEN }}
|
||||
49
.github/workflows/test.yaml
vendored
Normal file
49
.github/workflows/test.yaml
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
name: Test JellyCon
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
env:
|
||||
PR_TRIGGERED: ${{ github.event_name == 'pull_request' && github.repository == 'jellyfin/jellycon' }}
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
py_version: ['2.7', '3.9']
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Python ${{ matrix.py_version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.py_version }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install -r requirements-dev.txt
|
||||
|
||||
- name: Lint with flake8
|
||||
run: |
|
||||
# stop the build if there are Python syntax errors or undefined names
|
||||
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
|
||||
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --output-file=flake8.output
|
||||
cat flake8.output
|
||||
|
||||
- name: Publish Test Atrifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
retention-days: 14
|
||||
name: ${{ matrix.py_version }}-test-results
|
||||
path: |
|
||||
flake8.output
|
||||
Reference in New Issue
Block a user