diff options
| author | Yuriy Andamasov <yuriy@vyos.io> | 2026-05-11 01:13:44 +0300 |
|---|---|---|
| committer | Yuriy Andamasov <yuriy@vyos.io> | 2026-05-11 01:13:44 +0300 |
| commit | 8b5c867897bad4278b29b318b493f2ceee8015e0 (patch) | |
| tree | cb5b0b34764694e6c4ba2ddc482e6917c86dfa56 | |
| parent | 41967202c380114f5c042f410393f6a07e174109 (diff) | |
| download | vyos-documentation-8b5c867897bad4278b29b318b493f2ceee8015e0.tar.gz vyos-documentation-8b5c867897bad4278b29b318b493f2ceee8015e0.zip | |
ci(ai-validation): address 4 CR findings — SHA pins, NUL guard, DB pin, drop id-token
Follow-up on the now-merged #1957 (ubuntu-latest switch). CodeRabbit
raised these findings on the paired add-to-circinus PR #1959 (where
the same file was being added to the circinus branch); since the file
contents are byte-identical across rolling/circinus/sagitta, applying
the same fixes here.
1. SHA-pin actions/checkout@v6 (x4), actions/upload-artifact@v4,
actions/download-artifact@v4, anthropics/claude-code-action@v1.
pull_request_target has secrets + repo write — GitHub security
guidance recommends full commit SHAs as the only immutable
release form.
2. Reject paths containing control characters (NUL/CR/LF) in
changed-md.z and changed-rst.z before `tr '\0' '\n'` converts
them to newline-delimited manifests. A fork PR committing
`docs/foo<LF>bar.md` would otherwise split into two logical
lines, masking the real file from line-based consumers.
3. Pin reference-DB download to `tag: ${{ env.REVIEWER_REF }}`
(was `latest: true`). Aligns DB version with the pinned
reviewer code; a future reviewer-v1.x.x release with a DB schema
change can't be silently picked up.
4. Drop `id-token: write` from validate job permissions. No OIDC
usage; copy-paste leftover.
Paired PRs on release branches (byte-identical file contents):
* circinus: #1959 (commit 025319ea)
* sagitta: #1960 (commit e5506317)
| -rw-r--r-- | .github/workflows/ai-validation.yml | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/.github/workflows/ai-validation.yml b/.github/workflows/ai-validation.yml index 44952092..36f5cb6c 100644 --- a/.github/workflows/ai-validation.yml +++ b/.github/workflows/ai-validation.yml @@ -51,7 +51,7 @@ jobs: contents: read steps: - name: Checkout PR merge ref (NO credentials) - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: refs/pull/${{ github.event.number }}/merge persist-credentials: false @@ -69,6 +69,21 @@ jobs: # in changed-md.txt (which drives the bundling step). git diff "$BASE...HEAD" --name-only --diff-filter=ACMRT -z -- 'docs/**/*.md' > changed-md.z git diff "$BASE...HEAD" --name-only --diff-filter=ACMRT -z -- 'docs/**/*.rst' > changed-rst.z + # Reject paths containing control chars (newlines, CR, NUL inside the + # name, escape sequences etc) before generating the newline-delimited + # *.txt manifests. Without this guard, `tr '\0' '\n'` on a path like + # `docs/foo\nbar.md` would split it into two logical lines — + # downstream consumers reading line-by-line would miss validation + # coverage on the real file (or worse, attempt to act on a synthetic + # path). Filesystems and porcelain git typically reject these but a + # fork PR can still commit such a tree entry; fail fast. + for z in changed-md.z changed-rst.z; do + if LC_ALL=C tr -d '\0\n\r' < "$z" \ + | LC_ALL=C grep -Pq '[\x00-\x1F\x7F]'; then + echo "::error::Refusing to bundle: path in $z contains a control character. Reject the offending file name in the PR." + exit 1 + fi + done tr '\0' '\n' < changed-md.z > changed-md.txt tr '\0' '\n' < changed-rst.z > changed-rst.txt git diff "$BASE...HEAD" -- 'docs/**/*.md' > diff-md.patch @@ -123,7 +138,7 @@ jobs: done < changed-md.z - name: Upload PR input artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: pr-input path: | @@ -138,7 +153,6 @@ jobs: permissions: contents: read pull-requests: write - id-token: write steps: # Pass secrets via env: rather than inlining ${{ secrets.X }} into the # shell script. GitHub Actions template-expands ${{ ... }} BEFORE bash @@ -182,7 +196,7 @@ jobs: - name: Download PR input if: steps.secrets-check.outputs.skip != 'true' - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: name: pr-input @@ -198,7 +212,7 @@ jobs: - name: Sparse-checkout branches.json from reviewer if: steps.secrets-check.outputs.skip != 'true' - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: repository: VyOS-Networks/vyos-docs-opus-reviewer ref: ${{ env.REVIEWER_REF }} @@ -229,7 +243,7 @@ jobs: - name: Checkout vyos-1x at mapped branch if: steps.secrets-check.outputs.skip != 'true' - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: repository: vyos-networks/vyos-1x ref: ${{ steps.branch.outputs.vyos1x }} @@ -248,7 +262,11 @@ jobs: uses: robinraju/release-downloader@28fc21f50d76778e7023361aa1f863e717d3d56f # v1.13 with: repository: VyOS-Networks/vyos-docs-opus-reviewer - latest: true + # Pin the DB to the same release tag as REVIEWER_REF so a future + # reviewer-v1.x.x release with a schema change can't be silently + # picked up while the pinned reviewer code still expects the + # old schema. Reproducibility > recency for this artifact. + tag: ${{ env.REVIEWER_REF }} fileName: reference-db-${{ steps.branch.outputs.vyos1x }}.tar.gz out-file-path: .reference-db token: ${{ steps.app.outputs.token }} @@ -293,7 +311,7 @@ jobs: # reviewer-src/.git/config where the Pass 2 LLM step could read it. - name: Checkout reviewer package source (pinned to REVIEWER_REF) if: steps.secrets-check.outputs.skip != 'true' - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: repository: VyOS-Networks/vyos-docs-opus-reviewer ref: ${{ env.REVIEWER_REF }} @@ -322,7 +340,7 @@ jobs: - name: Pass 2 — Claude review if: steps.secrets-check.outputs.skip != 'true' - uses: anthropics/claude-code-action@v1 + uses: anthropics/claude-code-action@476e359e6203e73dad705c8b322e333fabbd7416 # v1.0.119 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} # claude-code-action@v1 removed the top-level `model` input; CLI |
