|
| 1 | +name: "Maintenance: Lint scripts (post)" |
| 2 | +# |
| 3 | +# Second phase of the two-phase lint pipeline. Triggered by the |
| 4 | +# completion of maintenance-lint-scripts.yml ("Maintenance: Lint |
| 5 | +# scripts"), runs in the BASE repository's context with a full write |
| 6 | +# token — so review comments and suggestion blocks can be posted to |
| 7 | +# pull requests originating from forks too. |
| 8 | +# |
| 9 | +# Security boundary: this workflow never checks out PR code. It only |
| 10 | +# downloads the lint job's artifacts (text findings + unified diffs + |
| 11 | +# PR metadata) and feeds them to reviewdog. CodeQL's |
| 12 | +# actions/untrusted-checkout rule stays quiet because no |
| 13 | +# `actions/checkout` runs with `ref: ${{ github.event.pull_request.head.sha }}` |
| 14 | +# (or equivalent untrusted ref). |
| 15 | +# |
| 16 | +# Note: GitHub always runs `workflow_run` workflows from the default |
| 17 | +# branch's copy of this file, so changes to the post pipeline take |
| 18 | +# effect only after merging into the default branch. |
| 19 | +# |
| 20 | +# Runs on every fork of armbian/build by default. If a fork doesn't |
| 21 | +# want PR comments — disable Settings → Actions → Workflows → |
| 22 | +# "Maintenance: Lint scripts (post)". Disabling only the post leaves |
| 23 | +# the red-cross Check still working (Maintenance: Lint scripts itself); |
| 24 | +# disabling both leaves the fork lint-free. |
| 25 | + |
| 26 | +on: |
| 27 | + workflow_run: |
| 28 | + workflows: ["Maintenance: Lint scripts"] |
| 29 | + types: [completed] |
| 30 | + |
| 31 | +permissions: |
| 32 | + contents: read |
| 33 | + actions: read # required by actions/download-artifact@v4 when downloading from another workflow run via `run-id` |
| 34 | + pull-requests: write |
| 35 | + checks: write |
| 36 | + issues: write # documented requirement of reviewdog for PR-comment APIs |
| 37 | + |
| 38 | +jobs: |
| 39 | + Post: |
| 40 | + name: Post ShellCheck and shfmt diagnostics |
| 41 | + runs-on: ubuntu-latest |
| 42 | + # Run even on red-cross lint conclusions (`failure`) — the |
| 43 | + # artifact is uploaded via `if: always()` in the lint workflow, |
| 44 | + # and we want to surface diagnostics in the PR even when the |
| 45 | + # gate failed. Skip the conclusions where no artifact is |
| 46 | + # produced (cancelled / timed_out / skipped / action_required). |
| 47 | + if: >- |
| 48 | + ${{ github.event.workflow_run.conclusion != 'cancelled' |
| 49 | + && github.event.workflow_run.conclusion != 'timed_out' |
| 50 | + && github.event.workflow_run.conclusion != 'skipped' |
| 51 | + && github.event.workflow_run.conclusion != 'action_required' }} |
| 52 | + steps: |
| 53 | + - name: Checkout BASE for reviewdog's local git context |
| 54 | + # reviewdog requires a `.git` to be present even when its |
| 55 | + # reporter (`github-pr-review`) computes the PR diff via API. |
| 56 | + # Checking out BASE (the workflow's default branch — our own |
| 57 | + # trusted code) gives it what it needs without ever pulling PR |
| 58 | + # code into the privileged context; CodeQL's untrusted-checkout |
| 59 | + # rule stays quiet because there is no `ref: ...head.sha`. |
| 60 | + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 |
| 61 | + with: |
| 62 | + fetch-depth: 1 |
| 63 | + persist-credentials: false # defense-in-depth: post-step uses REVIEWDOG_GITHUB_API_TOKEN, not the on-disk extraheader |
| 64 | + |
| 65 | + - name: Surface workflow purpose + disable instructions in the Check summary |
| 66 | + run: | |
| 67 | + cat >>"$GITHUB_STEP_SUMMARY" <<'EOF' |
| 68 | + ## What this Check does |
| 69 | +
|
| 70 | + `Maintenance: Lint scripts (post)` is the second phase of the lint pipeline. It downloads diagnostic artifacts produced by `Maintenance: Lint scripts` and posts them as inline review comments and auto-fix `suggestion` blocks on the PR via [reviewdog](https://github.com/reviewdog/reviewdog). |
| 71 | +
|
| 72 | + ### Don't want PR comments? |
| 73 | +
|
| 74 | + This workflow runs on every fork of `armbian/build` by default. To stop the PR-comment spam: |
| 75 | +
|
| 76 | + * **Just the comments** — Settings → Actions → Workflows → "Maintenance: Lint scripts (post)" → "Disable workflow". The lint Check itself (red cross / green check) keeps working. |
| 77 | + * **Disable both phases** — disable `Maintenance: Lint scripts` instead; the post phase becomes a no-op automatically because there are no artifacts. |
| 78 | +
|
| 79 | + EOF |
| 80 | +
|
| 81 | + - name: Download lint artifacts (no checkout of PR code) |
| 82 | + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 |
| 83 | + with: |
| 84 | + name: lint-scripts-results |
| 85 | + run-id: ${{ github.event.workflow_run.id }} |
| 86 | + github-token: ${{ secrets.GITHUB_TOKEN }} |
| 87 | + |
| 88 | + - name: Synthesize pull_request event JSON for reviewdog |
| 89 | + run: | |
| 90 | + # reviewdog in a workflow_run context cannot find PR info on |
| 91 | + # its own — GITHUB_EVENT_NAME is `workflow_run` and |
| 92 | + # GITHUB_EVENT_PATH points to a workflow_run payload, not a |
| 93 | + # pull_request event. CI_* fallback env vars are bypassed when |
| 94 | + # GitHub Actions context is detected. Workaround: synthesize a |
| 95 | + # minimal pull_request event JSON, then override |
| 96 | + # GITHUB_EVENT_NAME and GITHUB_EVENT_PATH at the step level |
| 97 | + # for each subsequent reviewdog invocation. |
| 98 | + PR_NUMBER=$(cat pr-number.txt) |
| 99 | + HEAD_SHA=$(cat head-sha.txt) |
| 100 | + BASE_SHA=$(cat base-sha.txt) |
| 101 | + BASE_REF=$(cat base-ref.txt) |
| 102 | + BASE_REPO=$(cat base-repo.txt) |
| 103 | + OWNER="${BASE_REPO%/*}" |
| 104 | + NAME="${BASE_REPO##*/}" |
| 105 | + jq -n \ |
| 106 | + --argjson number "$PR_NUMBER" \ |
| 107 | + --arg head_sha "$HEAD_SHA" \ |
| 108 | + --arg base_sha "$BASE_SHA" \ |
| 109 | + --arg base_ref "$BASE_REF" \ |
| 110 | + --arg owner "$OWNER" \ |
| 111 | + --arg name "$NAME" \ |
| 112 | + --arg full "$BASE_REPO" \ |
| 113 | + '{ |
| 114 | + "action": "synchronize", |
| 115 | + "number": $number, |
| 116 | + "repository": { |
| 117 | + "name": $name, |
| 118 | + "full_name": $full, |
| 119 | + "owner": { "login": $owner } |
| 120 | + }, |
| 121 | + "pull_request": { |
| 122 | + "number": $number, |
| 123 | + "head": { |
| 124 | + "sha": $head_sha, |
| 125 | + "ref": "pr-head", |
| 126 | + "repo": { "full_name": $full, "name": $name, "owner": { "login": $owner } } |
| 127 | + }, |
| 128 | + "base": { |
| 129 | + "sha": $base_sha, |
| 130 | + "ref": $base_ref, |
| 131 | + "repo": { "full_name": $full, "name": $name, "owner": { "login": $owner } } |
| 132 | + } |
| 133 | + } |
| 134 | + }' > /tmp/pr-event.json |
| 135 | + cat /tmp/pr-event.json |
| 136 | + echo "FAKE_PR_EVENT_PATH=/tmp/pr-event.json" >> "$GITHUB_ENV" |
| 137 | +
|
| 138 | + - uses: reviewdog/action-setup@d8a7baabd7f3e8544ee4dbde3ee41d0011c3a93f # v1.4.0 |
| 139 | + with: |
| 140 | + reviewdog_version: latest |
| 141 | + |
| 142 | + # GitHub Actions strips `GITHUB_*` overrides from step-level |
| 143 | + # `env:` blocks (documented), so we apply the overrides inline as |
| 144 | + # bash command-environment variables — GitHub can't touch those. |
| 145 | + - name: Post ShellCheck findings as inline review comments |
| 146 | + env: |
| 147 | + REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 148 | + run: | |
| 149 | + # reviewdog has no built-in `gcc` parser; supply vim |
| 150 | + # errorformat (-efm) patterns matching |
| 151 | + # `file:line:col: severity: message`. Three patterns cover |
| 152 | + # error / warning / note outputs. |
| 153 | + cat shellcheck-findings.txt | env \ |
| 154 | + GITHUB_EVENT_NAME=pull_request \ |
| 155 | + GITHUB_EVENT_PATH="$FAKE_PR_EVENT_PATH" \ |
| 156 | + reviewdog \ |
| 157 | + -name=shellcheck-findings \ |
| 158 | + -efm='%f:%l:%c: %trror: %m' \ |
| 159 | + -efm='%f:%l:%c: %tarning: %m' \ |
| 160 | + -efm='%f:%l:%c: %tote: %m' \ |
| 161 | + -reporter=github-pr-review \ |
| 162 | + -filter-mode=added \ |
| 163 | + -fail-level=none |
| 164 | +
|
| 165 | + - name: Post ShellCheck auto-fix as suggestion blocks |
| 166 | + env: |
| 167 | + REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 168 | + run: | |
| 169 | + # `-f=diff` parses unified-diff input and emits `suggestion` |
| 170 | + # blocks for each hunk on PR-added lines (filter_mode=added). |
| 171 | + # Replaces reviewdog/action-suggester (which needs a checked- |
| 172 | + # out worktree to compute the diff itself). |
| 173 | + cat shellcheck-fix.diff | env \ |
| 174 | + GITHUB_EVENT_NAME=pull_request \ |
| 175 | + GITHUB_EVENT_PATH="$FAKE_PR_EVENT_PATH" \ |
| 176 | + reviewdog \ |
| 177 | + -name=shellcheck-fix \ |
| 178 | + -f=diff \ |
| 179 | + -filter-mode=added \ |
| 180 | + -reporter=github-pr-review \ |
| 181 | + -fail-level=none |
| 182 | +
|
| 183 | + - name: Post shfmt drift as suggestion blocks |
| 184 | + env: |
| 185 | + REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 186 | + run: | |
| 187 | + cat shfmt.diff | env \ |
| 188 | + GITHUB_EVENT_NAME=pull_request \ |
| 189 | + GITHUB_EVENT_PATH="$FAKE_PR_EVENT_PATH" \ |
| 190 | + reviewdog \ |
| 191 | + -name=shfmt \ |
| 192 | + -f=diff \ |
| 193 | + -filter-mode=added \ |
| 194 | + -reporter=github-pr-review \ |
| 195 | + -fail-level=none |
0 commit comments