diff --git a/.github/workflows/tsc.yml b/.github/workflows/build.yml similarity index 56% rename from .github/workflows/tsc.yml rename to .github/workflows/build.yml index 35bde340f..e6d71a240 100644 --- a/.github/workflows/tsc.yml +++ b/.github/workflows/build.yml @@ -1,14 +1,19 @@ -name: TypeScript Build Check +name: Build + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true on: push: branches: [ master, release* ] pull_request: branches: [ master, release* ] + workflow_dispatch: jobs: - tsc: - name: Run TypeScript build check + run-build-prod: + name: Run production build runs-on: ubuntu-latest steps: @@ -25,8 +30,12 @@ jobs: - name: Install Node.js dependencies run: npm ci --no-audit - - name: Run tsc - run: npm run build:check + - name: Run a production build + run: npm run build:production - - name: Run test suite - run: npm run test + - name: Upload artifact + uses: actions/upload-artifact@v3.1.3 + with: + name: jellyfin-web__prod + path: | + dist diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql.yml similarity index 70% rename from .github/workflows/codeql-analysis.yml rename to .github/workflows/codeql.yml index 6c8ffdbbf..34d1fafbf 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql.yml @@ -1,31 +1,34 @@ -name: "CodeQL" +name: CodeQL + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true on: push: - branches: [ master ] + branches: [ master, release* ] pull_request: - branches: [ master ] + branches: [ master, release* ] schedule: - cron: '30 7 * * 6' jobs: - analyze: - name: Analyze + codeql: + name: Run CodeQL runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - language: [ 'javascript' ] steps: - name: Checkout repository uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - name: Initialize CodeQL uses: github/codeql-action/init@46ed16ded91731b2df79a2893d3aea8e9f03b5c4 # v2.20.3 with: - languages: ${{ matrix.language }} + languages: javascript queries: +security-extended + - name: Autobuild uses: github/codeql-action/autobuild@46ed16ded91731b2df79a2893d3aea8e9f03b5c4 # v2.20.3 + - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@46ed16ded91731b2df79a2893d3aea8e9f03b5c4 # v2.20.3 diff --git a/.github/workflows/job-messages.yml b/.github/workflows/job-messages.yml new file mode 100644 index 000000000..7a58ecce7 --- /dev/null +++ b/.github/workflows/job-messages.yml @@ -0,0 +1,65 @@ +name: Job messages + +on: + workflow_call: + inputs: + branch: + required: false + type: string + commit: + required: true + type: string + preview_url: + required: false + type: string + build_workflow_run_id: + required: false + type: number + commenting_workflow_run_id: + required: true + type: string + in_progress: + required: true + type: boolean + outputs: + msg: + description: The composed message + value: ${{ jobs.msg.outputs.msg }} + marker: + description: Hidden marker to detect PR comments composed by the bot + value: "CFPages-deployment" + +jobs: + msg: + name: Deployment status + runs-on: ubuntu-latest + outputs: + msg: ${{ env.msg }} + + steps: + - name: Compose message + if: ${{ always() }} + id: compose + env: + COMMIT: ${{ inputs.commit }} + PREVIEW_URL: ${{ inputs.preview_url != '' && (inputs.branch != 'master' && inputs.preview_url || format('https://jellyfin-web.pages.dev ({0})', inputs.preview_url)) || 'Not available' }} + DEPLOY_STATUS: ${{ inputs.in_progress && '🔄 Deploying...' || (inputs.preview_url != '' && '✅ Deployed!' || '❌ Failure. Check workflow logs for details') }} + DEPLOYMENT_TYPE: ${{ inputs.branch != 'master' && '🔀 Preview' || '⚙️ Production' }} + BUILD_WORKFLOW_RUN: ${{ !inputs.in_progress && format('**[View build logs](https://github.com/{0}/actions/runs/{1})**', 'jellyfin/jellyfin-web', inputs.build_workflow_run_id) || '' }} + COMMENTING_WORKFLOW_RUN: ${{ format('**[View bot logs](https://github.com/{0}/actions/runs/{1})**', 'jellyfin/jellyfin-web', inputs.commenting_workflow_run_id) }} + # EOF is needed for multiline environment variables in a GitHub Actions context + run: | + echo "## Cloudflare Pages deployment" > $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "| **Latest commit** | ${COMMIT::7} |" >> $GITHUB_STEP_SUMMARY + echo "|------------------------- |:----------------------------: |" >> $GITHUB_STEP_SUMMARY + echo "| **Status** | $DEPLOY_STATUS |" >> $GITHUB_STEP_SUMMARY + echo "| **Preview URL** | $PREVIEW_URL |" >> $GITHUB_STEP_SUMMARY + echo "| **Type** | $DEPLOYMENT_TYPE |" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "$BUILD_WORKFLOW_RUN" >> $GITHUB_STEP_SUMMARY + echo "$COMMENTING_WORKFLOW_RUN" >> $GITHUB_STEP_SUMMARY + COMPOSED_MSG=$(cat $GITHUB_STEP_SUMMARY) + echo "msg<> $GITHUB_ENV + echo "$COMPOSED_MSG" >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 000000000..1fcf65711 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,94 @@ +on: + workflow_run: + workflows: + - Build + types: + - completed + +jobs: + publish: + permissions: + contents: read + deployments: write + + name: Deploy to Cloudflare Pages + runs-on: ubuntu-latest + outputs: + url: ${{ steps.cf.outputs.url }} + + steps: + - name: Download workflow artifact + uses: dawidd6/action-download-artifact@v2.27.0 + with: + run_id: ${{ github.event.workflow_run.id }} + name: jellyfin-web__prod + path: dist + + - name: Publish + id: cf + uses: cloudflare/pages-action@1 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + projectName: jellyfin-web + directory: dist + gitHubToken: ${{ secrets.GITHUB_TOKEN }} + + pr-context: + name: PR context + if: ${{ always() && github.event.workflow_run.event == 'pull_request' }} + runs-on: ubuntu-latest + outputs: + commit: ${{ env.pr_sha }} + pr_number: ${{ env.pr_number }} + + steps: + - name: Get PR context + uses: dawidd6/action-download-artifact@v2.27.0 + id: pr_context + with: + run_id: ${{ github.event.workflow_run.id }} + name: PR_context + + - name: Set PR context environment variables + if: ${{ steps.pr_context.conclusion == 'success' }} + run: | + echo "pr_number=$(cat PR_number)" >> $GITHUB_ENV + echo "pr_sha=$(cat PR_sha)" >> $GITHUB_ENV + + compose-comment: + name: Compose comment + if: ${{ always() }} + uses: ./.github/workflows/job-messages.yml + needs: + - publish + - pr-context + + with: + branch: ${{ github.event.workflow_run.head_branch }} + commit: ${{ needs.pr-context.outputs.commit != '' && needs.pr-context.outputs.commit || github.event.workflow_run.head_sha }} + preview_url: ${{ needs.publish.outputs.url }} + build_workflow_run_id: ${{ github.event.workflow_run.id }} + commenting_workflow_run_id: ${{ github.run_id }} + in_progress: false + + comment-status: + name: Create comment status + if: | + always() && + github.event.workflow_run.event == 'pull_request' && + needs.pr-context.outputs.pr_number != '' + runs-on: ubuntu-latest + needs: + - compose-comment + - pr-context + + steps: + - name: Update job summary in PR comment + uses: thollander/actions-comment-pull-request@v2.4.2 + with: + GITHUB_TOKEN: ${{ secrets.JF_BOT_TOKEN }} + message: ${{ needs.compose-comment.outputs.msg }} + pr_number: ${{ needs.pr-context.outputs.pr_number }} + comment_tag: ${{ needs.compose-comment.outputs.marker }} + mode: recreate diff --git a/.github/workflows/lint.yml b/.github/workflows/quality.yml similarity index 68% rename from .github/workflows/lint.yml rename to .github/workflows/quality.yml index b754665bc..b4840d90c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/quality.yml @@ -1,4 +1,8 @@ -name: Lint +name: Quality checks + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true on: push: @@ -99,3 +103,45 @@ jobs: - name: Run stylelint run: npm run stylelint:scss + + run-tsc: + name: Run TypeScript build check + runs-on: ubuntu-latest + + steps: + - name: Check out Git repository + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + + - name: Setup node environment + uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + with: + node-version: 20 + check-latest: true + cache: npm + + - name: Install Node.js dependencies + run: npm ci --no-audit + + - name: Run tsc + run: npm run build:check + + run-test: + name: Run tests + runs-on: ubuntu-latest + + steps: + - name: Check out Git repository + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + + - name: Setup node environment + uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + with: + node-version: 20 + check-latest: true + cache: npm + + - name: Install Node.js dependencies + run: npm ci --no-audit + + - name: Run test suite + run: npm run test diff --git a/.github/workflows/repo-stale.yaml b/.github/workflows/stale.yml similarity index 100% rename from .github/workflows/repo-stale.yaml rename to .github/workflows/stale.yml