feat(desktop): redesign UI around install and usage jobs (#814) #189
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Coverage Badge | |
| # Updates the README coverage badge gist after a merge to main, without | |
| # re-running the coverage pipeline. The coverage numbers that ship with main | |
| # are the ones computed on the PR's merge commit (coverage.yml runs on every | |
| # PR), so we just locate that PR's coverage-summary artifact and push it to | |
| # the gist. | |
| on: | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| inputs: | |
| run_id: | |
| description: "Coverage Summary run ID to pull artifact from (optional; defaults to latest success on main)" | |
| required: false | |
| type: string | |
| permissions: | |
| contents: read | |
| actions: read | |
| jobs: | |
| update-badge: | |
| runs-on: ubuntu-latest | |
| # Skip release automation commits — they don't change coverage. | |
| if: ${{ !contains(github.event.head_commit.message, '[skip ci]') }} | |
| steps: | |
| - name: Resolve Coverage Summary run ID for this merge | |
| id: resolve | |
| uses: actions/github-script@v7 | |
| env: | |
| OVERRIDE_RUN_ID: ${{ github.event.inputs.run_id }} | |
| with: | |
| script: | | |
| const override = process.env.OVERRIDE_RUN_ID; | |
| if (override) { | |
| core.info(`Using override run_id=${override}`); | |
| core.setOutput('run_id', override); | |
| return; | |
| } | |
| // Find the PR associated with the merge commit. Merge commits to | |
| // main are produced by either squash/rebase (one PR) or a merge | |
| // commit (one PR); the associated-PRs endpoint handles all three. | |
| const { data: prs } = await github.rest.repos.listPullRequestsAssociatedWithCommit({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| commit_sha: context.sha, | |
| }); | |
| // Prefer a PR whose base is main and that is closed/merged. | |
| const pr = prs.find(p => p.base && p.base.ref === 'main') || prs[0]; | |
| if (!pr) { | |
| core.warning(`No PR associated with ${context.sha}; skipping badge update.`); | |
| core.setOutput('skip', 'true'); | |
| return; | |
| } | |
| core.info(`Associated PR #${pr.number} head_sha=${pr.head.sha}`); | |
| // Find the most recent successful Coverage Summary run whose head | |
| // SHA matches the PR's head. That run's artifact reflects coverage | |
| // against main at merge time. | |
| const { data: runs } = await github.rest.actions.listWorkflowRuns({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| workflow_id: 'coverage.yml', | |
| head_sha: pr.head.sha, | |
| status: 'success', | |
| per_page: 10, | |
| }); | |
| if (runs.workflow_runs.length === 0) { | |
| core.warning(`No successful Coverage Summary run found for PR #${pr.number} (${pr.head.sha}); skipping badge update.`); | |
| core.setOutput('skip', 'true'); | |
| return; | |
| } | |
| const run = runs.workflow_runs[0]; | |
| core.info(`Using Coverage Summary run ${run.id} (${run.html_url})`); | |
| core.setOutput('run_id', run.id.toString()); | |
| core.setOutput('pr_number', pr.number.toString()); | |
| - name: Confirm artifact exists | |
| if: steps.resolve.outputs.skip != 'true' | |
| id: artifact | |
| uses: actions/github-script@v7 | |
| env: | |
| RUN_ID: ${{ steps.resolve.outputs.run_id }} | |
| with: | |
| script: | | |
| const run_id = Number(process.env.RUN_ID); | |
| const { data } = await github.rest.actions.listWorkflowRunArtifacts({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| run_id, | |
| }); | |
| const artifact = data.artifacts.find(a => a.name === 'coverage-summary'); | |
| if (!artifact) { | |
| core.warning(`Run ${run_id} has no coverage-summary artifact (likely a docs-only PR); skipping badge update.`); | |
| core.setOutput('skip', 'true'); | |
| return; | |
| } | |
| if (artifact.expired) { | |
| core.warning(`coverage-summary artifact on run ${run_id} has expired; skipping badge update.`); | |
| core.setOutput('skip', 'true'); | |
| return; | |
| } | |
| - name: Download coverage-summary artifact | |
| if: steps.resolve.outputs.skip != 'true' && steps.artifact.outputs.skip != 'true' | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: coverage-summary | |
| run-id: ${{ steps.resolve.outputs.run_id }} | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| path: coverage | |
| - name: Update coverage badge gist | |
| # GitHub Actions does not allow secrets.* inside if: expressions, so | |
| # surface them through env and gate on that to keep this a no-op on | |
| # forks / repos without the secrets configured. | |
| if: steps.resolve.outputs.skip != 'true' && steps.artifact.outputs.skip != 'true' && env.COVERAGE_GIST_ID != '' && env.GIST_TOKEN != '' | |
| uses: actions/github-script@v7 | |
| env: | |
| COVERAGE_GIST_ID: ${{ secrets.COVERAGE_GIST_ID }} | |
| GIST_TOKEN: ${{ secrets.GIST_TOKEN }} | |
| with: | |
| github-token: ${{ secrets.GIST_TOKEN }} | |
| script: | | |
| const fs = require('fs'); | |
| const badge = fs.readFileSync('coverage/badge.json', 'utf8'); | |
| const summary = fs.readFileSync('coverage/summary.json', 'utf8'); | |
| await github.rest.gists.update({ | |
| gist_id: process.env.COVERAGE_GIST_ID, | |
| files: { | |
| 'badge.json': { content: badge }, | |
| 'coverage-summary.json': { content: summary }, | |
| }, | |
| }); | |
| core.info('Coverage badge gist updated.'); |