ci-openapi.yml 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. name: OpenAPI
  2. on:
  3. push:
  4. branches:
  5. - master
  6. pull_request_target:
  7. permissions: {}
  8. jobs:
  9. openapi-head:
  10. name: OpenAPI - HEAD
  11. runs-on: ubuntu-latest
  12. permissions: read-all
  13. steps:
  14. - name: Checkout repository
  15. uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
  16. with:
  17. ref: ${{ github.event.pull_request.head.sha }}
  18. repository: ${{ github.event.pull_request.head.repo.full_name }}
  19. - name: Setup .NET
  20. uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3 # v4.0.0
  21. with:
  22. dotnet-version: '8.0.x'
  23. - name: Generate openapi.json
  24. run: dotnet test tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj -c Release --filter "Jellyfin.Server.Integration.Tests.OpenApiSpecTests"
  25. - name: Upload openapi.json
  26. uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
  27. with:
  28. name: openapi-head
  29. retention-days: 14
  30. if-no-files-found: error
  31. path: tests/Jellyfin.Server.Integration.Tests/bin/Release/net8.0/openapi.json
  32. openapi-base:
  33. name: OpenAPI - BASE
  34. if: ${{ github.base_ref != '' }}
  35. runs-on: ubuntu-latest
  36. permissions: read-all
  37. steps:
  38. - name: Checkout repository
  39. uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
  40. with:
  41. ref: ${{ github.event.pull_request.head.sha }}
  42. repository: ${{ github.event.pull_request.head.repo.full_name }}
  43. fetch-depth: 0
  44. - name: Checkout common ancestor
  45. env:
  46. HEAD_REF: ${{ github.head_ref }}
  47. run: |
  48. git remote add upstream https://github.com/${{ github.event.pull_request.base.repo.full_name }}
  49. git -c protocol.version=2 fetch --prune --progress --no-recurse-submodules upstream +refs/heads/*:refs/remotes/upstream/* +refs/tags/*:refs/tags/*
  50. ANCESTOR_REF=$(git merge-base upstream/${{ github.base_ref }} origin/$HEAD_REF)
  51. git checkout --progress --force $ANCESTOR_REF
  52. - name: Setup .NET
  53. uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3 # v4.0.0
  54. with:
  55. dotnet-version: '8.0.x'
  56. - name: Generate openapi.json
  57. run: dotnet test tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj -c Release --filter "Jellyfin.Server.Integration.Tests.OpenApiSpecTests"
  58. - name: Upload openapi.json
  59. uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
  60. with:
  61. name: openapi-base
  62. retention-days: 14
  63. if-no-files-found: error
  64. path: tests/Jellyfin.Server.Integration.Tests/bin/Release/net8.0/openapi.json
  65. openapi-diff:
  66. permissions:
  67. pull-requests: write # to create or update comment (peter-evans/create-or-update-comment)
  68. name: OpenAPI - Difference
  69. if: ${{ github.event_name == 'pull_request_target' }}
  70. runs-on: ubuntu-latest
  71. needs:
  72. - openapi-head
  73. - openapi-base
  74. steps:
  75. - name: Download openapi-head
  76. uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
  77. with:
  78. name: openapi-head
  79. path: openapi-head
  80. - name: Download openapi-base
  81. uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
  82. with:
  83. name: openapi-base
  84. path: openapi-base
  85. - name: Workaround openapi-diff issue
  86. run: |
  87. sed -i 's/"allOf"/"oneOf"/g' openapi-head/openapi.json
  88. sed -i 's/"allOf"/"oneOf"/g' openapi-base/openapi.json
  89. - name: Calculate OpenAPI difference
  90. uses: docker://openapitools/openapi-diff
  91. continue-on-error: true
  92. with:
  93. args: --fail-on-changed --markdown openapi-changes.md openapi-base/openapi.json openapi-head/openapi.json
  94. - id: read-diff
  95. name: Read openapi-diff output
  96. run: |
  97. body=$(cat openapi-changes.md)
  98. body="${body//'%'/'%25'}"
  99. body="${body//$'\n'/'%0A'}"
  100. body="${body//$'\r'/'%0D'}"
  101. echo ::set-output name=body::$body
  102. - name: Find difference comment
  103. uses: peter-evans/find-comment@d5fe37641ad8451bdd80312415672ba26c86575e # v3.0.0
  104. id: find-comment
  105. with:
  106. issue-number: ${{ github.event.pull_request.number }}
  107. direction: last
  108. body-includes: openapi-diff-workflow-comment
  109. - name: Reply or edit difference comment (changed)
  110. uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0
  111. if: ${{ steps.read-diff.outputs.body != '' }}
  112. with:
  113. issue-number: ${{ github.event.pull_request.number }}
  114. comment-id: ${{ steps.find-comment.outputs.comment-id }}
  115. edit-mode: replace
  116. body: |
  117. <!--openapi-diff-workflow-comment-->
  118. <details>
  119. <summary>Changes in OpenAPI specification found. Expand to see details.</summary>
  120. ${{ steps.read-diff.outputs.body }}
  121. </details>
  122. - name: Edit difference comment (unchanged)
  123. uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0
  124. if: ${{ steps.read-diff.outputs.body == '' && steps.find-comment.outputs.comment-id != '' }}
  125. with:
  126. issue-number: ${{ github.event.pull_request.number }}
  127. comment-id: ${{ steps.find-comment.outputs.comment-id }}
  128. edit-mode: replace
  129. body: |
  130. <!--openapi-diff-workflow-comment-->
  131. No changes to OpenAPI specification found. See history of this comment for previous changes.
  132. publish:
  133. name: OpenAPI - Publish Unstable Spec
  134. if: |
  135. github.event_name != 'pull_request' &&
  136. contains(github.repository_owner, 'jellyfin')
  137. runs-on: ubuntu-latest
  138. needs:
  139. - openapi-head
  140. steps:
  141. - name: Set unstable dated version
  142. id: version
  143. run: |-
  144. echo "JELLYFIN_VERSION=$(date +'%Y%m%d%H')" >> $GITHUB_ENV
  145. - name: Download openapi-head
  146. uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
  147. with:
  148. name: openapi-head
  149. path: openapi-head
  150. - name: Upload openapi.json (unstable) to repository server
  151. uses: appleboy/scp-action@917f8b81dfc1ccd331fef9e2d61bdc6c8be94634 # v0.1.7
  152. with:
  153. host: "${{ secrets.REPO_HOST }}"
  154. username: "${{ secrets.REPO_USER }}"
  155. key: "${{ secrets.REPO_KEY }}"
  156. source: openapi-head/openapi.json
  157. strip_components: 1
  158. target: "/srv/incoming/openapi/unstable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }}.json"
  159. - name: Move openapi.json (unstable) into place
  160. uses: appleboy/ssh-action@029f5b4aeeeb58fdfe1410a5d17f967dacf36262 # v1.0.3
  161. with:
  162. host: "${{ secrets.REPO_HOST }}"
  163. username: "${{ secrets.REPO_USER }}"
  164. key: "${{ secrets.REPO_KEY }}"
  165. debug: false
  166. script_stop: false
  167. script: |
  168. TGT_DIR="/srv/repository/main/openapi"
  169. LAST_SPEC="$( ls -lt ${TGT_DIR} | grep 'jellyfin-openapi' | head -1 | awk '{ print $NF }' )"
  170. sudo mv /srv/incoming/openapi/unstable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }}.json ${TGT_DIR}/unstable/ jellyfin-openapi-${{ env.JELLYFIN_VERSION }}.json
  171. # Delete previous jellyfin-openapi-unstable_previous.json
  172. sudo rm ${TGT_DIR}/jellyfin-openapi-unstable_previous.json
  173. # Move current jellyfin-openapi-unstable.json symlink to jellyfin-openapi-unstable_previous.json
  174. sudo mv ${TGT_DIR}/jellyfin-openapi-unstable.json ${TGT_DIR}/jellyfin-openapi-unstable_previous.json
  175. # Create new jellyfin-openapi-stable.json symlink
  176. sudo ln -s unstable/jellyfin-openapi-${{ env.JELLYFIN_VERSION }}.json ${TGT_DIR}/jellyfin-openapi-unstable.json
  177. # Check that the previous openapi spec is correct
  178. if [[ "$( readlink ${TGT_DIR}/jellyfin-openapi-unstable_previous.json )" != "unstable/${LAST_SPEC}" ]]; then
  179. sudo rm ${TGT_DIR}/jellyfin-openapi-unstable_previous.json
  180. sudo ln -s unstable/${LAST_SPEC} ${TGT_DIR}/jellyfin-openapi-unstable_previous.json
  181. fi