| 1 | name: (Runtime) Sizebot Comment |
| 2 | |
| 3 | # Posts the build size comparison comment on pull requests. |
| 4 | # |
| 5 | # This has to be a separate `workflow_run` workflow rather than a job inside |
| 6 | # (Runtime) Build and Test: that workflow runs on the `pull_request` trigger, so |
| 7 | # a pull request from a fork gets a read-only token and cannot comment. A |
| 8 | # `workflow_run` workflow always runs in the context of this repository, on the |
| 9 | # default branch, with a writable token. |
| 10 | # |
| 11 | # The measurement happens on the other side of that boundary, in the unprivileged |
| 12 | # sizebot job, which uploads a `sizebot-results` artifact. This workflow only |
| 13 | # downloads that small JSON file and renders it. It deliberately never unpacks a |
| 14 | # build produced by a fork, because it holds a token that can write to the |
| 15 | # repository. |
| 16 | |
| 17 | on: |
| 18 | workflow_run: |
| 19 | workflows: ['(Runtime) Build and Test'] |
| 20 | types: [requested, completed] |
| 21 | |
| 22 | permissions: {} |
| 23 | |
| 24 | concurrency: |
| 25 | # Serialize per pull request. Both the requested and completed handlers read |
| 26 | # the existing comment, decide against it and write it back, so they must not |
| 27 | # interleave. Never cancel: every event either updates the comment or is |
| 28 | # deliberately skipped, and dropping one loses a state transition. |
| 29 | group: ${{ github.workflow }}-${{ github.event.workflow_run.head_repository.full_name }}-${{ github.event.workflow_run.head_branch }} |
| 30 | cancel-in-progress: false |
| 31 | |
| 32 | env: |
| 33 | TZ: /usr/share/zoneinfo/America/Los_Angeles |
| 34 | |
| 35 | jobs: |
| 36 | comment: |
| 37 | # Only pull request builds get a size comment. Runs from `push` and |
| 38 | # `workflow_dispatch` have no pull request to comment on. |
| 39 | if: ${{ github.event.workflow_run.event == 'pull_request' }} |
| 40 | name: Comment with size changes |
| 41 | runs-on: ubuntu-latest |
| 42 | permissions: |
| 43 | # We use github.token to download the sizebot results artifact from the |
| 44 | # triggering runtime_build_and_test.yml run |
| 45 | actions: read |
| 46 | # Used to check out the renderer this workflow runs |
| 47 | contents: read |
| 48 | # Used to create and update the sizebot comment on the pull request |
| 49 | pull-requests: write |
| 50 | steps: |
| 51 | # No `ref`, so this is the default branch rather than the pull request. |
| 52 | # The thresholds, the critical bundle list and the comment template all |
| 53 | # come from here and cannot be changed by the pull request being measured. |
| 54 | - uses: actions/checkout@v4 |
| 55 | with: |
| 56 | # This job holds a token that can write to the repository, and it has |
| 57 | # no use for git credentials after the checkout. |
| 58 | persist-credentials: false |
| 59 | |
| 60 | - name: Resolve pull request and existing comment |
| 61 | id: resolve |
| 62 | uses: actions/github-script@v7 |
| 63 | with: |
| 64 | script: | |
| 65 | const {resolve} = require(`${process.env.GITHUB_WORKSPACE}/scripts/sizebot/pull-request-comment.js`); |
| 66 | await resolve({github, context, core}); |
| 67 | |
| 68 | - name: Download sizebot results |
| 69 | if: ${{ steps.resolve.outputs.action == 'continue' && steps.resolve.outputs.download_results == 'true' }} |
| 70 | continue-on-error: true |
| 71 | uses: actions/download-artifact@v4 |
| 72 | with: |
| 73 | name: sizebot-results |
| 74 | run-id: ${{ github.event.workflow_run.id }} |
| 75 | github-token: ${{ github.token }} |
| 76 | |
| 77 | - name: Render comment |
| 78 | if: ${{ steps.resolve.outputs.action == 'continue' }} |
| 79 | run: node ./scripts/sizebot/render-comment.js |
| 80 | |
| 81 | - name: Archive full size report |
| 82 | # Only written when the report is too large to fit in a comment, in which |
| 83 | # case the comment links to this artifact. |
| 84 | if: ${{ steps.resolve.outputs.action == 'continue' && hashFiles('sizebot-message.md') != '' }} |
| 85 | uses: actions/upload-artifact@v4 |
| 86 | with: |
| 87 | name: sizebot-message |
| 88 | path: sizebot-message.md |
| 89 | |
| 90 | - name: Post comment |
| 91 | if: ${{ steps.resolve.outputs.action == 'continue' }} |
| 92 | uses: actions/github-script@v7 |
| 93 | with: |
| 94 | script: | |
| 95 | const {post} = require(`${process.env.GITHUB_WORKSPACE}/scripts/sizebot/pull-request-comment.js`); |
| 96 | await post({github, context, core}); |
| 97 | |
| 98 | - name: Fail if the build configuration drifted |
| 99 | # The comment is posted first, so it explains the problem on the pull |
| 100 | # request itself. This step exists so the drift also shows up as a failed |
| 101 | # run rather than only in a comment. |
| 102 | if: ${{ steps.resolve.outputs.action == 'continue' && hashFiles('sizebot-problem.txt') != '' }} |
| 103 | run: | |
| 104 | cat sizebot-problem.txt |
| 105 | exit 1 |