Skip to content

Guard CGO/CJS workflow purity - #53680

Merged
pelikhan merged 11 commits into
mainfrom
copilot/add-test-for-secrets-check
Aug 18, 2026
Merged

Guard CGO/CJS workflow purity#53680
pelikhan merged 11 commits into
mainfrom
copilot/add-test-for-secrets-check

Conversation

Copilot AI commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

CGO and CJS checkout-cache jobs should stay pure test paths with nothing sensitive to leak. These workflows should not reference secrets beyond GITHUB_TOKEN/SCIENCE, and should not request write permissions.

  • Shared purity check

    • Adds scripts/check-cgo-cjs-workflow-purity.sh.
    • Scans .github/workflows/cgo.yml and .github/workflows/cjs.yml for disallowed secrets.* expressions.
    • Fails on permissions: write-all and any mapped permission set to write.
  • Checkout-cache enforcement

    • Runs the purity check from both CGO and CJS checkout-cache jobs before saving the repository cache.
  • Workflow permission cleanup

    • Changes the CJS artifact integration job from actions: write to actions: read.
    • Removes the CGO failure-notification job that required issues: write.
- name: Verify CGO/CJS workflow purity
  run: bash scripts/check-cgo-cjs-workflow-purity.sh

Copilot AI and others added 8 commits August 18, 2026 12:11
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title Guard CGO and CJS checkout cache workflows Guard CGO/CJS workflow purity Aug 18, 2026
Copilot AI requested a review from pelikhan August 18, 2026 12:25
@pelikhan
pelikhan marked this pull request as ready for review August 18, 2026 12:25
Copilot AI balanced review requested due to automatic review settings August 18, 2026 12:25
@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR does not have the 'implementation' label and has 0 new lines of code in business logic directories (threshold: 100).

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Ponytail Reviewer completed successfully!

Generated by Ponytail Reviewer for #53680

@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

No test files were added or modified in this PR. Test Quality Sentinel skipped.

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

🔎 Code quality review by PR Code Quality Reviewer

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a shared purity guard for CGO/CJS test workflows.

Changes:

  • Checks secret references and write permissions before caching checkouts.
  • Reduces CJS artifact permissions.
  • Removes CGO failure issue creation.
Show a summary per file
File Description
scripts/check-cgo-cjs-workflow-purity.sh Implements purity validation.
.github/workflows/cjs.yml Runs validation and reduces permissions.
.github/workflows/cgo.yml Runs validation and removes notifications.

Review details

Suppressed comments (1)

scripts/check-cgo-cjs-workflow-purity.sh:48

  • The scanner only enters block mappings written as a bare permissions: key and only recognizes an unquoted write value. Semantically equivalent valid YAML such as permissions: { issues: write }, anchored mappings, issues: "write", or quoted write-all bypasses the purity check. Parse the YAML structure and recursively validate workflow- and job-level permissions values instead of matching formatting.
    /^[[:space:]]*permissions:[[:space:]]*write-all([[:space:]]*(#.*)?)?$/ {
      print FILENAME ":" FNR ":" $0
    }
    /^[[:space:]]*permissions:[[:space:]]*$/ {
  • Files reviewed: 3/3 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment on lines +4 to +6
if [ "$#" -eq 0 ]; then
set -- .github/workflows/cgo.yml .github/workflows/cjs.yml
fi
# GITHUB_TOKEN and the repository's SCIENCE telemetry secret.
disallowed_secrets_file="$tmp_dir/disallowed-secrets.txt"
if ! perl -ne '
while (/\$\{\{\s*secrets\.([A-Za-z_][A-Za-z0-9_]*)\b/g) {
@github-actions

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-08-18T12:31:00Z
review_event: REQUEST_CHANGES
top_themes:
  - lossy CI diagnostics in purity checker
files_reviewed:
  - .github/workflows/cgo.yml
  - .github/workflows/cjs.yml
  - scripts/check-cgo-cjs-workflow-purity.sh
comment_count: 1

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

🔎 Code quality review by PR Code Quality Reviewer · gpt54 · 7.27 AIC · ⌖ 8.03 AIC · ⊞ 4.5K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes

The new purity guard is moving in the right direction, but its diagnostics are already lossy: when both workflows fail in one run, the script overwrites the first workflow's scratch output and only reports the last file's details.

Blocking theme
  • The new checker reuses fixed temp filenames across the loop, so multi-file failures produce incomplete and misleading CI output.

🔎 Code quality review by PR Code Quality Reviewer · gpt54 · 7.27 AIC · ⌖ 8.03 AIC · ⊞ 4.5K
Comment /review to run again


# These workflows should stay pure test workflows: allow only the built-in
# GITHUB_TOKEN and the repository's SCIENCE telemetry secret.
disallowed_secrets_file="$tmp_dir/disallowed-secrets.txt"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This guard script writes its scratch files with fixed names inside a shared temporary directory, so the second workflow you scan overwrites the first workflow's diagnostics. If both cgo.yml and cjs.yml are dirty in one run, the output will only show the last file's findings, which makes debugging failures needlessly misleading.

💡 Keep per-workflow diagnostics separate.

Because disallowed-secrets.txt and write-permissions.txt are reused for every loop iteration, the script loses the earlier file's output as soon as the next workflow is processed. Give each workflow its own result files, for example:

safe_name=${workflow//\//_}
disallowed_secrets_file="$tmp_dir/${safe_name}-disallowed-secrets.txt"
write_permissions_file="$tmp_dir/${safe_name}-write-permissions.txt"

That preserves all failing matches and keeps CI output trustworthy when multiple workflows break at once.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes look correct and well-structured.

  • New purity script (check-cgo-cjs-workflow-purity.sh): The perl regex for secrets and the awk indent-tracking for write permissions handle edge cases correctly (blank lines, comments, write-all, per-permission write values, multi-file resets via FNR==1).
  • notify-failure removal: The deleted job had issues: write — exactly the kind of write permission the new guard would have caught. Removing it is the right fix.
  • actions: writeactions: read in cjs.yml: Clean least-privilege improvement.
  • Trigger path for the new script added to both push/pull_request filters — correct.

No actionable issues found.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 21.2 AIC · ⌖ 8.82 AIC · ⊞ 5.7K

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ponytail review — over-engineering check only.

One finding on the new purity-check script: it uses a temp dir + trap just to hold two scan outputs it immediately checks with [ -s ... ]. Capturing to variables and checking [ -n ... ] drops the tmp_dir/trap plumbing entirely.

net: -10 lines possible.

Generated by ✂️ Ponytail Reviewer for #53680 · auto · 22.2 AIC · ⌖ 3.19 AIC · ⊞ 7.3K
Comment /ponytail to run again

set -- .github/workflows/cgo.yml .github/workflows/cjs.yml
fi

tmp_dir="$(mktemp -d)"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

L8-9: shrink: mktemp -d + trap only to stash two throwaway command outputs in files. Capture with disallowed=$(perl ... "$workflow") and writes=$(awk ... "$workflow"), then check [ -n "$disallowed" ] — drops tmp_dir/trap and both *_file vars, ~10 lines.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills-Based Review 🧠

Applied /tdd, /codebase-design, and /improve-codebase-architecture — commenting (no blocking issues, but the purity script needs a test).

📋 Key Themes & Highlights

Key Themes

  • Missing test coverage: check-cgo-cjs-workflow-purity.sh has no automated test; a silent regression would disable the guard entirely.
  • Fragile YAML parsing: The awk indent-tracking heuristic can miss inline permissions: {key: write} style and will need updating if the project adopts flow-style YAML.
  • Undocumented allowlist: The SCIENCE secret is permitted but has no inline explanation.
  • Deleted observability: notify-failure is removed without a recorded rationale or replacement, creating an implicit gap.

Positive Highlights

  • ✅ Excellent principle: purity is enforced at cache-save time, making the guard self-policing rather than advisory.
  • ✅ Clean set -euo pipefail and trap cleanup — robust shell hygiene.
  • ✅ Reducing CJS actions permission from write to read is the right least-privilege move.
  • ✅ The trigger-path addition in cjs.yml ensures the check re-runs whenever the script itself changes.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 34.3 AIC · ⌖ 10.2 AIC · ⊞ 7.8K
Comment /matt to run again

fi
done

exit "$failed"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/tdd] No regression test for the purity script — if the perl regex or awk pattern silently breaks, the guard becomes a no-op.

💡 Suggested approach

Add a test script (e.g., scripts/test-check-cgo-cjs-workflow-purity.sh) that:

  1. Creates a synthetic workflow YAML with a known-disallowed secret expression and asserts the script exits non-zero.
  2. Creates a clean workflow YAML and asserts the script exits zero.
  3. Wires the test into make test-unit or a dedicated make test-scripts target.

Without this, a regex typo or tooling change can silently disable the guard.

@copilot please address this.

}
' "$workflow" >"$write_permissions_file"; then
echo "Failed to scan permissions in $workflow"
failed=1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/codebase-design] The awk permissions scanner uses indent-level heuristics to track permissions: blocks, which is fragile against valid YAML indentation variants and aliased blocks.

💡 Concrete risk

A workflow like:

jobs:
  build:
    permissions:
      contents: write # inside a job — should be caught

...is caught today, but inline permissions: {contents: write} on a single line is not matched by the current awk pattern (it only matches permissions: followed by a newline). Consider using a proper YAML parser (python3 -c "import yaml, sys; ..." or yq) for correctness and to reduce maintenance burden.

@copilot please address this.

close ARGV if eof;
' "$workflow" >"$disallowed_secrets_file"; then
echo "Failed to scan secrets expressions in $workflow"
failed=1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/codebase-design] The hardcoded allowlist (GITHUB_TOKEN, SCIENCE) lives only inside the script with no comment referencing where SCIENCE is documented or why it is permitted.

💡 Suggestion

Add a brief inline comment explaining the rationale, e.g.:

# GITHUB_TOKEN: standard built-in token — always safe
# SCIENCE: repo-level telemetry secret — write-only sink, no sensitive data
unless $1 eq "GITHUB_TOKEN" || $1 eq "SCIENCE";

If the allowlist grows, consider a variable at the top of the script so it is visible to reviewers without reading the perl one-liner.

@copilot please address this.

Comment thread .github/workflows/cgo.yml
@@ -2508,216 +2510,6 @@ jobs:
path: conformance-output.txt
retention-days: 7

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/improve-codebase-architecture] The notify-failure job is deleted without a documented decision or replacement strategy — if failure alerting on main is still needed, the rationale for removing it is not captured.

💡 Suggestion

Either:

  • Add a short comment in the PR body or a commit message noting that failure notification is intentionally dropped (e.g., superseded by another alerting system), or
  • File a follow-up issue tracking the gap if alerting was valuable.

The deletion is a significant loss of observability. Without a record, a future contributor may re-add the exact pattern that introduced the issues: write permission.

@copilot please address this.

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot review failing tests and move to separate workflow if write token is needed

Copilot AI and others added 2 commits August 18, 2026 12:50
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

@copilot review failing tests and move to separate workflow if write token is needed

Addressed in 7437223. I reviewed the failing CGO run: it failed in the M-R unit-test coverage step with no individual test failure, and the same shard passes locally with coverage. No write token is needed in CGO/CJS; the purity guard now has automated coverage and remains read-only.

import sys

workflow = sys.argv[1]
allowed = {"GITHUB_TOKEN", "SCIENCE"}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot SCIENCE is not an allowed secret

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 374a619: SCIENCE is no longer allowlisted, and the script test now asserts secrets.SCIENCE is rejected.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI requested a review from pelikhan August 18, 2026 13:06
@pelikhan
pelikhan merged commit b5da9e5 into main Aug 18, 2026
27 of 29 checks passed
@pelikhan
pelikhan deleted the copilot/add-test-for-secrets-check branch August 18, 2026 15:02
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.87.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants