Skip to content

Commit 714b63c

Browse files
committed
ci(pr-checks): report Go dependency status in the AI review comment
1 parent c3c9b7b commit 714b63c

4 files changed

Lines changed: 97 additions & 27 deletions

File tree

.github/ai-prompts/README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,12 @@ merge `release/**` PRs; see `.github/workflows/README.md` → "Release policy".
7272

7373
### Routine dependency bumps
7474

75-
A `go_deps` check can enforce that Go modules are on their latest version,
76-
but it's not currently wired into `pr-checks.yml` (run
77-
`bash .github/scripts/go-deps.sh --check --discover` manually — see
78-
`.github/workflows/README.md` → "Dependabot"). Regardless, the
79-
`architecture` and `security` prompts treat a version bump of
75+
`pr-checks.yml` already reports outdated Go modules as its own "Go
76+
dependencies" section in the sticky comment (see
77+
`.github/workflows/README.md` → "AI review policy") — that's informational
78+
too, so a dependency bump is expected to still show up there, not something
79+
these prompts need to flag separately. The `architecture` and `security`
80+
prompts treat a version bump of
8081
existing modules as **Tier 1** — not an architectural/agent-breaking change
8182
and not a vulnerability — and only flag genuine anomalies (new deps, major
8283
breaking jumps, downgrades, known-vulnerable pins, suspicious `replace`

.github/scripts/post-ai-review-comment.sh

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,33 @@
22
set -euo pipefail
33

44
# Reads every AI review result JSON (one per prompt, produced by
5-
# ai-review.sh) and posts/updates a single sticky PR comment with the
6-
# findings. Purely informational: severity/tier only drive the wording/icon
7-
# of the comment. This never blocks the merge, never fails the job, and
8-
# never @mentions anyone — it's just there so the author knows what to fix.
5+
# ai-review.sh) plus the optional Go dependencies check output, and
6+
# posts/updates a single sticky PR comment. Purely informational:
7+
# severity/tier and the deps check result only drive the wording/icon of
8+
# the comment. This never blocks the merge, never fails the job, and never
9+
# @mentions anyone — it's just there so the author knows what to fix.
910
#
1011
# Required env vars:
1112
# RESULTS_DIR directory containing one <prompt-name>.json per
1213
# AI prompt (as written by ai-review.sh)
1314
# PR_NUMBER PR number to comment on
1415
# GITHUB_REPOSITORY owner/repo
1516
# GITHUB_TOKEN for posting/updating the comment (unless DRY_RUN=1)
17+
#
18+
# Optional env vars:
19+
# GO_DEPS_OUTPUT_FILE path to go-deps.sh's captured stdout+stderr.
20+
# If unset/missing, the Go dependencies section
21+
# is omitted entirely.
22+
# GO_DEPS_EXIT_CODE_FILE path to a file containing go-deps.sh's exit
23+
# code. Required alongside GO_DEPS_OUTPUT_FILE.
1624

1725
: "${RESULTS_DIR:?RESULTS_DIR is required}"
1826
: "${PR_NUMBER:?PR_NUMBER is required}"
1927
: "${GITHUB_REPOSITORY:?GITHUB_REPOSITORY is required}"
2028

29+
GO_DEPS_OUTPUT_FILE="${GO_DEPS_OUTPUT_FILE:-}"
30+
GO_DEPS_EXIT_CODE_FILE="${GO_DEPS_EXIT_CODE_FILE:-}"
31+
2132
# DRY_RUN=1 prints the comment body instead of calling the GitHub API.
2233
DRY_RUN="${DRY_RUN:-0}"
2334

@@ -129,6 +140,20 @@ if (( ${#results[@]} > 0 )); then
129140
done
130141
fi
131142

143+
# Go dependencies — same style as the AI prompt sections above, but not an
144+
# AI call: just the exit code + output of go-deps.sh, ANSI colors stripped.
145+
if [[ -n "$GO_DEPS_OUTPUT_FILE" && -f "$GO_DEPS_OUTPUT_FILE" && -n "$GO_DEPS_EXIT_CODE_FILE" && -f "$GO_DEPS_EXIT_CODE_FILE" ]]; then
146+
go_deps_exit=$(cat "$GO_DEPS_EXIT_CODE_FILE")
147+
go_deps_output=$(sed -E $'s/\x1b\\[[0-9;]*[mK]//g' "$GO_DEPS_OUTPUT_FILE")
148+
if [[ "$go_deps_exit" == "0" ]]; then
149+
findings_md+=$'\n'"#### 🟢 \`go-deps\` — up to date"$'\n\n'
150+
findings_md+="No pending Go dependency updates."$'\n'
151+
else
152+
findings_md+=$'\n'"#### 🔴 \`go-deps\` — pending updates"$'\n\n'
153+
findings_md+='```'$'\n'"$go_deps_output"$'\n''```'$'\n'
154+
fi
155+
fi
156+
132157
if $no_results; then
133158
header="### ❓ AI review — could not run"
134159
intro="No AI results were produced. Check the workflow logs."

.github/workflows/README.md

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ the comment, never the outcome:
7171
| Any high/critical finding | 🛑 "High/critical findings" |
7272
| Tier 3 | 🛑 "Sensitive area, extra care recommended" |
7373

74+
The same comment also carries a **Go dependencies** section (🟢 up to date /
75+
🔴 pending updates), from a plain `go-deps.sh --check --discover` run — not
76+
an AI call, just the same informational treatment: it's reported, never
77+
blocks.
78+
7479
Whatever the signal, the job always succeeds — the status check stays green.
7580
When the author pushes new commits, the sticky comment is **updated
7681
in-place** (same comment, no stacking) and the workflow re-runs
@@ -97,10 +102,11 @@ behavior is ever needed again.)
97102
### Dependabot
98103

99104
Disabled. `.github/dependabot.yml` keeps `updates: []` so Dependabot
100-
reads the file but creates no PRs. Dependency freshness used to be enforced
101-
on every PR via a `go_deps` check; it's no longer wired into `pr-checks.yml`
102-
(see [Reusable workflows](#reusable-workflows)) — run
103-
`bash .github/scripts/go-deps.sh --check --discover` manually instead. To
105+
reads the file but creates no PRs. Dependency freshness is surfaced instead
106+
by the "Check Go dependencies" step in `pr-checks.yml`, which runs
107+
`bash .github/scripts/go-deps.sh --check --discover` and reports the result
108+
as a section in the sticky comment (informational — see
109+
[AI review policy](#ai-review-policy-informational-only-no-auto-merge)). To
104110
re-enable Dependabot, restore the
105111
previous `updates:` list (see git history of that file).
106112

@@ -176,12 +182,17 @@ at all.
176182

177183
### Steps
178184

179-
1. **Fetch the diff**`gh pr diff` (same unified diff the GitHub UI
185+
1. **Check Go dependencies**`actions/setup-go@v5`, then (if `API_SECRET`
186+
is set) configures git for private `utmstack/*` modules, then runs
187+
`bash .github/scripts/go-deps.sh --check --discover`. Captures stdout,
188+
stderr and the exit code to `/tmp/go-deps/`; **never fails the job**
189+
`set +e` around the call, same informational treatment as the AI review.
190+
2. **Fetch the diff**`gh pr diff` (same unified diff the GitHub UI
180191
shows — no need for `fetch-depth: 0`).
181-
2. **Filter the diff** — drops any file under a `rules/`, `filters/` or
192+
3. **Filter the diff** — drops any file under a `rules/`, `filters/` or
182193
`definitions/` folder (detection rules / correlation filters / content,
183194
not code) before the AI ever sees it.
184-
3. **Run AI review, once per prompt** — for each `.md` under
195+
4. **Run AI review, once per prompt** — for each `.md` under
185196
`.github/ai-prompts/` (except `README.md`), calls
186197
`.github/scripts/ai-review.sh`, which:
187198
- Calls the **ThreatWinds AI** `/chat/completions` endpoint with the
@@ -206,9 +217,10 @@ at all.
206217
`.github/ai-prompts/` — the loop in `pr-checks.yml` discovers it at
207218
runtime, no YAML changes needed. **Default model:** `gemini-3-flash-lite`;
208219
each prompt can pin its own in frontmatter (`model: gemini-3-pro`, etc.).
209-
4. **Post the comment**`.github/scripts/post-ai-review-comment.sh` reads
210-
every JSON file, builds one combined markdown comment (severity/tier
211-
only drive wording/icon), and upserts a single sticky comment (marker
220+
5. **Post the comment**`.github/scripts/post-ai-review-comment.sh` reads
221+
every JSON file plus the Go deps output/exit code, builds one combined
222+
markdown comment (severity/tier and the deps exit code only drive
223+
wording/icon), and upserts a single sticky comment (marker
212224
`<!-- approver:ai -->`, kept from the previous design so in-flight PRs
213225
keep updating the same comment). Never fails, never blocks, never
214226
@mentions anyone.
@@ -343,7 +355,7 @@ The installer is uploaded as a release asset.
343355

344356
| Secret | Used in | Description |
345357
|--------|---------|-------------|
346-
| `API_SECRET` | v10, v11 deploy, installer | GitHub PAT with `read:org` scope. Used by deployment workflows for team-membership validation and for fetching private `utmstack/*` Go modules. **Not used by `pr-checks.yml`** — that workflow has no team-membership check. |
358+
| `API_SECRET` | v10, v11 deploy, installer, pr-checks | GitHub PAT with `read:org` scope. Used by deployment workflows for team-membership validation, and by `pr-checks.yml`'s "Check Go dependencies" step to fetch private `utmstack/*` Go modules via `go list`. **Not used for any team-membership check in `pr-checks.yml`** — that workflow has none. |
347359
| `AGENT_SECRET_PREFIX` | v10, v11 | Agent encryption key |
348360
| `SIGN_CERT` | v10, v11 | Code signing certificate path (it's a `var`) |
349361
| `SIGN_KEY` | v10, v11 | Code signing key |
@@ -371,11 +383,12 @@ The installer is uploaded as a release asset.
371383

372384
**PR checks:**
373385

374-
- `_pr-reusable-go-deps.yml` — runs `go-deps.sh --check --discover` at repo
375-
level and uploads `go-deps-result` as an artifact. **Not called by
376-
`pr-checks.yml`** (removed — see [Dependabot](#dependabot)); kept for
377-
running manually on demand via `workflow_call` or a local invocation of
378-
the underlying script.
386+
- `_pr-reusable-go-deps.yml` — a leftover, artifact-based version of the Go
387+
deps check (uploads `go-deps-result` instead of reporting inline). **Not
388+
called by `pr-checks.yml`**`pr-checks.yml` runs
389+
`bash .github/scripts/go-deps.sh --check --discover` directly as a step
390+
instead (see [PR Checks](#pr-checks)). Kept only for manually invoking via
391+
`workflow_call` if you ever need the artifact form again.
379392
- The AI review + comment logic used to be two more reusable workflows
380393
(`_pr-reusable-ai-review.yml`, `_pr-reusable-approver.yml`); both were
381394
removed and folded into steps of the single `review` job in
@@ -467,9 +480,11 @@ git checkout -b hotfix/auth-bug
467480
[AI review policy](#ai-review-policy-informational-only-no-auto-merge).
468481
Those branches are gated by the "Protect Main" GitHub ruleset instead.
469482

470-
**`go_deps` fails with "Could not inspect ... run 'go mod tidy' there":**
483+
**Go dependencies section shows 🔴 "Could not inspect ... run 'go mod tidy' there":**
471484
- `go.sum` is out of sync, typically due to local `replace` directives in
472-
`packages/`. Run `go mod tidy` in the affected module and commit.
485+
`packages/`. Run `go mod tidy` in the affected module and commit. This
486+
never fails the job — it's reported in the comment, same as any other
487+
finding.
473488

474489
**Build failures:**
475490
- Check that all required secrets are configured.

.github/workflows/pr-checks.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,33 @@ jobs:
2020
steps:
2121
- uses: actions/checkout@v4
2222

23+
- uses: actions/setup-go@v5
24+
with:
25+
go-version: '1.23'
26+
27+
- name: Configure git for private Go modules
28+
if: ${{ env.HAS_API_SECRET == 'true' }}
29+
env:
30+
HAS_API_SECRET: ${{ secrets.API_SECRET != '' }}
31+
API_SECRET: ${{ secrets.API_SECRET }}
32+
run: |
33+
git config --global url."https://${API_SECRET}:x-oauth-basic@github.com/".insteadOf "https://github.com/"
34+
{
35+
echo "GOPRIVATE=github.com/utmstack"
36+
echo "GONOPROXY=github.com/utmstack"
37+
echo "GONOSUMDB=github.com/utmstack"
38+
} >> "$GITHUB_ENV"
39+
40+
- name: Check Go dependencies
41+
run: |
42+
mkdir -p /tmp/go-deps
43+
set +e
44+
bash .github/scripts/go-deps.sh --check --discover \
45+
> /tmp/go-deps/output.txt 2>&1
46+
echo $? > /tmp/go-deps/exit_code.txt
47+
set -e
48+
cat /tmp/go-deps/output.txt
49+
2350
- name: Fetch PR diff
2451
env:
2552
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -77,6 +104,8 @@ jobs:
77104
- name: Post AI review comment
78105
env:
79106
RESULTS_DIR: /tmp/ai-results
107+
GO_DEPS_OUTPUT_FILE: /tmp/go-deps/output.txt
108+
GO_DEPS_EXIT_CODE_FILE: /tmp/go-deps/exit_code.txt
80109
PR_NUMBER: ${{ github.event.pull_request.number }}
81110
GITHUB_REPOSITORY: ${{ github.repository }}
82111
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)