diff options
Diffstat (limited to '.github/workflows/openapi')
| -rw-r--r-- | .github/workflows/openapi/__generate.yml | 44 | ||||
| -rw-r--r-- | .github/workflows/openapi/merge.yml | 140 | ||||
| -rw-r--r-- | .github/workflows/openapi/pull-request.yml | 72 | ||||
| -rw-r--r-- | .github/workflows/openapi/workflow-run.yml | 59 |
4 files changed, 315 insertions, 0 deletions
diff --git a/.github/workflows/openapi/__generate.yml b/.github/workflows/openapi/__generate.yml new file mode 100644 index 000000000..255cc49e8 --- /dev/null +++ b/.github/workflows/openapi/__generate.yml @@ -0,0 +1,44 @@ +name: OpenAPI Generate + +on: + workflow_call: + inputs: + ref: + required: true + type: string + repository: + required: true + type: string + artifact: + required: true + type: string + +permissions: + contents: read + +jobs: + main: + name: Main + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ inputs.ref }} + repository: ${{ inputs.repository }} + + - name: Configure .NET + uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0 + with: + dotnet-version: '10.0.x' + + - name: Create File + run: dotnet test tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj -c Release --filter Jellyfin.Server.Integration.Tests.OpenApiSpecTests + + - name: Upload Artifact + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + name: ${{ inputs.artifact }} + path: tests/Jellyfin.Server.Integration.Tests/bin/Release/net10.0/openapi.json + retention-days: 14 + if-no-files-found: error diff --git a/.github/workflows/openapi/merge.yml b/.github/workflows/openapi/merge.yml new file mode 100644 index 000000000..a996b2da6 --- /dev/null +++ b/.github/workflows/openapi/merge.yml @@ -0,0 +1,140 @@ +name: OpenAPI Publish +on: + push: + branches: + - master + tags: + - 'v*' + +permissions: {} + +jobs: + publish-openapi: + name: OpenAPI - Publish Artifact + uses: ./.github/workflows/openapi/__generate.yml + with: + ref: ${{ github.sha }} + repository: ${{ github.repository }} + artifact: openapi-head + + publish-unstable: + name: OpenAPI - Publish Unstable Spec + if: ${{ github.event_name != 'pull_request' && !startsWith(github.ref, 'refs/tags/v') && contains(github.repository_owner, 'jellyfin') }} + runs-on: ubuntu-latest + needs: + - publish-openapi + steps: + - name: Set unstable dated version + id: version + run: |- + echo "JELLYFIN_VERSION=$(date +'%Y%m%d%H%M%S')" >> $GITHUB_ENV + - name: Download openapi-head + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: openapi-head + path: openapi-head + - name: Upload openapi.json (unstable) to repository server + uses: appleboy/scp-action@ff85246acaad7bdce478db94a363cd2bf7c90345 # v1.0.0 + with: + host: "${{ secrets.REPO_HOST }}" + username: "${{ secrets.REPO_USER }}" + key: "${{ secrets.REPO_KEY }}" + source: openapi-head/openapi.json + strip_components: 1 + target: "/srv/incoming/openapi/unstable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }}" + - name: Move openapi.json (unstable) into place + uses: appleboy/ssh-action@0ff4204d59e8e51228ff73bce53f80d53301dee2 # v1.2.5 + with: + host: "${{ secrets.REPO_HOST }}" + username: "${{ secrets.REPO_USER }}" + key: "${{ secrets.REPO_KEY }}" + debug: false + script: | + if ! test -d /run/workflows; then + sudo mkdir -p /run/workflows + sudo chown ${{ secrets.REPO_USER }} /run/workflows + fi + ( + flock -x -w 300 200 || exit 1 + TGT_DIR="/srv/repository/main/openapi" + LAST_SPEC="$( ls -lt ${TGT_DIR}/unstable/ | grep 'jellyfin-openapi' | head -1 | awk '{ print $NF }' )" + # If new and previous spec don't differ (diff retcode 0), remove incoming and finish + if diff /srv/incoming/openapi/unstable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }}/openapi.json ${TGT_DIR}/unstable/${LAST_SPEC} &>/dev/null; then + rm -r /srv/incoming/openapi/unstable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }} + exit 0 + fi + # Move new spec into place + sudo mv /srv/incoming/openapi/unstable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }}/openapi.json ${TGT_DIR}/unstable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }}.json + # Delete previous jellyfin-openapi-unstable_previous.json + sudo rm ${TGT_DIR}/jellyfin-openapi-unstable_previous.json + # Move current jellyfin-openapi-unstable.json symlink to jellyfin-openapi-unstable_previous.json + sudo mv ${TGT_DIR}/jellyfin-openapi-unstable.json ${TGT_DIR}/jellyfin-openapi-unstable_previous.json + # Create new jellyfin-openapi-unstable.json symlink + sudo ln -s unstable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }}.json ${TGT_DIR}/jellyfin-openapi-unstable.json + # Check that the previous openapi unstable spec link is correct + if [[ "$( readlink ${TGT_DIR}/jellyfin-openapi-unstable_previous.json )" != "unstable/${LAST_SPEC}" ]]; then + sudo rm ${TGT_DIR}/jellyfin-openapi-unstable_previous.json + sudo ln -s unstable/${LAST_SPEC} ${TGT_DIR}/jellyfin-openapi-unstable_previous.json + fi + ) 200>/run/workflows/openapi-unstable.lock + + publish-stable: + name: OpenAPI - Publish Stable Spec + if: ${{ startsWith(github.ref, 'refs/tags/v') && contains(github.repository_owner, 'jellyfin') }} + runs-on: ubuntu-latest + needs: + - publish-openapi + steps: + - name: Set version number + id: version + run: |- + echo "JELLYFIN_VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV + - name: Download openapi-head + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: openapi-head + path: openapi-head + - name: Upload openapi.json (stable) to repository server + uses: appleboy/scp-action@ff85246acaad7bdce478db94a363cd2bf7c90345 # v1.0.0 + with: + host: "${{ secrets.REPO_HOST }}" + username: "${{ secrets.REPO_USER }}" + key: "${{ secrets.REPO_KEY }}" + source: openapi-head/openapi.json + strip_components: 1 + target: "/srv/incoming/openapi/stable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }}" + - name: Move openapi.json (stable) into place + uses: appleboy/ssh-action@0ff4204d59e8e51228ff73bce53f80d53301dee2 # v1.2.5 + with: + host: "${{ secrets.REPO_HOST }}" + username: "${{ secrets.REPO_USER }}" + key: "${{ secrets.REPO_KEY }}" + debug: false + script: | + if ! test -d /run/workflows; then + sudo mkdir -p /run/workflows + sudo chown ${{ secrets.REPO_USER }} /run/workflows + fi + ( + flock -x -w 300 200 || exit 1 + TGT_DIR="/srv/repository/main/openapi" + LAST_SPEC="$( ls -lt ${TGT_DIR}/stable/ | grep 'jellyfin-openapi' | head -1 | awk '{ print $NF }' )" + # If new and previous spec don't differ (diff retcode 0), remove incoming and finish + if diff /srv/incoming/openapi/stable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }}/openapi.json ${TGT_DIR}/stable/${LAST_SPEC} &>/dev/null; then + rm -r /srv/incoming/openapi/stable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }} + exit 0 + fi + # Move new spec into place + sudo mv /srv/incoming/openapi/stable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }}/openapi.json ${TGT_DIR}/stable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }}.json + # Delete previous jellyfin-openapi-stable_previous.json + sudo rm ${TGT_DIR}/jellyfin-openapi-stable_previous.json + # Move current jellyfin-openapi-stable.json symlink to jellyfin-openapi-stable_previous.json + sudo mv ${TGT_DIR}/jellyfin-openapi-stable.json ${TGT_DIR}/jellyfin-openapi-stable_previous.json + # Create new jellyfin-openapi-stable.json symlink + sudo ln -s stable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }}.json ${TGT_DIR}/jellyfin-openapi-stable.json + # Check that the previous openapi stable spec link is correct + if [[ "$( readlink ${TGT_DIR}/jellyfin-openapi-stable_previous.json )" != "stable/${LAST_SPEC}" ]]; then + sudo rm ${TGT_DIR}/jellyfin-openapi-stable_previous.json + sudo ln -s stable/${LAST_SPEC} ${TGT_DIR}/jellyfin-openapi-stable_previous.json + fi + ) 200>/run/workflows/openapi-stable.lock diff --git a/.github/workflows/openapi/pull-request.yml b/.github/workflows/openapi/pull-request.yml new file mode 100644 index 000000000..307102782 --- /dev/null +++ b/.github/workflows/openapi/pull-request.yml @@ -0,0 +1,72 @@ +name: OpenAPI Check +on: + pull_request: + +jobs: + ancestor: + name: Common Ancestor + runs-on: ubuntu-latest + outputs: + base_ref: ${{ steps.ancestor.outputs.base_ref }} + steps: + - name: Checkout Repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ github.event.pull_request.head.sha }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + fetch-depth: 0 + - name: Search History + id: ancestor + run: | + git remote add upstream https://github.com/${{ github.event.pull_request.base.repo.full_name }} + git fetch --prune --progress --no-recurse-submodules upstream +refs/heads/*:refs/remotes/upstream/* +refs/tags/*:refs/tags/* + + ANCESTOR_REF=$(git merge-base upstream/${{ github.base_ref }} HEAD) + + echo "ref: ${ANCESTOR_REF}" + + echo "base_ref=${ANCESTOR_REF}" >> "$GITHUB_OUTPUT" + + head: + name: Head Artifact + uses: ./.github/workflows/openapi/__generate.yml + with: + ref: ${{ github.event.pull_request.head.sha }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + artifact: openapi-head + + base: + name: Base Artifact + uses: ./.github/workflows/openapi/__generate.yml + needs: + - ancestor + with: + ref: ${{ needs.ancestor.outputs.base_ref }} + repository: ${{ github.event.pull_request.base.repo.full_name }} + artifact: openapi-base + + diff: + name: Generate Report + runs-on: ubuntu-latest + needs: + - head + - base + steps: + - name: Download Head + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: openapi-head + path: openapi-head + - name: Download Base + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: openapi-base + path: openapi-base + - name: Detect Changes + uses: jellyfin/openapi-diff-action@9274f6bda9d01ab091942a4a8334baa53692e8a4 # v1.0.0 + id: openapi-diff + with: + old-spec: openapi-base/openapi.json + new-spec: openapi-head/openapi.json + markdown: openapi-changelog.md + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/openapi/workflow-run.yml b/.github/workflows/openapi/workflow-run.yml new file mode 100644 index 000000000..9dbd2c40a --- /dev/null +++ b/.github/workflows/openapi/workflow-run.yml @@ -0,0 +1,59 @@ +name: OpenAPI Report + +on: + workflow_run: + workflows: + - OpenAPI Check + types: + - completed + +jobs: + metadata: + name: Generate Metadata + runs-on: ubuntu-latest + if: ${{ github.event.workflow_run.conclusion == 'success' }} + outputs: + pr_number: ${{ steps.pr_number.outputs.pr_number }} + steps: + - name: Get Pull Request Number + id: pr_number + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + HEAD_SHA: ${{ github.event.workflow_run.head_sha }} + run: | + API_RESPONSE=$(gh pr list --repo "${GITHUB_REPOSITORY}" --search "${HEAD_SHA}" --state open --json number) + PR_NUMBER=$(echo "${API_RESPONSE}" | jq '.[0].number') + + echo "repository: ${GITHUB_REPOSITORY}" + echo "sha: ${HEAD_SHA}" + echo "response: ${API_RESPONSE}" + echo "pr: ${PR_NUMBER}" + + echo "pr_number=${PR_NUMBER}" >> "${GITHUB_OUTPUT}" + + comment: + name: Pull Request Comment + runs-on: ubuntu-latest + if: ${{ github.event.workflow_run.conclusion == 'success' }} + needs: + - metadata + permissions: + pull-requests: write + actions: read + contents: read + steps: + - name: Download OpenAPI Report + id: download_report + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: openapi-diff-report + path: openapi-diff-report + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Push Comment + uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b # v3.0.1 + with: + github-token: ${{ secrets.JF_BOT_TOKEN }} + file-path: ${{ steps.download_report.outputs.download-path }}/openapi-changelog.md + pr-number: ${{ needs.metadata.outputs.pr_number }} + comment-tag: openapi-report |
