Skip to content

chore(deps): Update module golang.org/x/vuln to v1.8.0 #25

chore(deps): Update module golang.org/x/vuln to v1.8.0

chore(deps): Update module golang.org/x/vuln to v1.8.0 #25

Workflow file for this run

# Orchestrator (service variant) — local reusable stages, PR-gated builds, one required check `ci`. Rationale: github-actions-align/templates/README.md#ciserviceyaml
name: CI
# push only, no pull_request — branch-push checks surface on the PR anyway, and
# adding pull_request would double-run every same-repo PR.
#
# THIS REQUIRES APP SECRETS. GITHUB_TOKEN cannot trigger workflows, so without
# them release-please's own release PR gets no run, `ci` never reports, and the
# PR is unmergeable forever. See README#github-app-handling.
on:
push:
branches: ['**']
workflow_dispatch:
concurrency:
group: ci-${{ github.ref }}
# Does not cancel a RUNNING main job. A third main push can still cancel the
# one sitting pending — GitHub allows only one pending run per group.
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
permissions:
contents: read
jobs:
# Decides whether this push warrants building an image. Code testing always
# runs; building does not — most feature-branch commits are WIP, and a
# multi-arch build plus smoke on each is the bulk of the runner time and
# registry churn. A DRAFT PR counts.
#
# `needs: [test]` is NOT a data dependency — it is a freshness one, and it is
# load-bearing. This job's only input is "does an open PR exist for this
# branch?", which is a fact about the world that CHANGES while the run is in
# flight. Evaluated at push time it answers in ~4 s; `build`, the job it
# gates, cannot start until `test` finishes minutes later. `gh pr create`
# right after `git push` therefore lands inside that window, `context`
# answers "no open PR", build and smoke skip, and the `ci` rollup goes green
# having never built the image. That produced SEVEN silent false greens in
# one repo before this fix.
#
# Waiting for `test` does not make the query race-free, it makes the window
# minutes instead of seconds, which covers the push-then-open-PR flow
# completely. The residual case — a PR opened well after the push — is caught
# loudly by the `ci` gate's re-query below rather than passing silently.
# Deciding at the point of use instead of caching the answer is also just
# correct: `build` already needs `test`, so this costs ~4 s of wall clock.
context:
name: context
needs: [test]
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: read
pull-requests: read
outputs:
build: ${{ steps.q.outputs.build }}
steps:
- id: q
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
EVENT: ${{ github.event_name }}
run: |
set -euo pipefail
if [ "${GITHUB_REF}" = "refs/heads/main" ] || [ "${EVENT}" = "workflow_dispatch" ]; then
echo "main or manual dispatch -> build"
echo "build=true" >> "$GITHUB_OUTPUT"
exit 0
fi
n=$(gh pr list --repo "${GITHUB_REPOSITORY}" --head "${GITHUB_REF_NAME}" \
--state open --json number --jq 'length')
if [ "${n}" -gt 0 ]; then
echo "${n} open PR(s) for ${GITHUB_REF_NAME} -> build"
echo "build=true" >> "$GITHUB_OUTPUT"
else
echo "no open PR for ${GITHUB_REF_NAME} -> test only (open a draft PR to get an image)"
echo "build=false" >> "$GITHUB_OUTPUT"
fi
test:
uses: ./.github/workflows/ci-test.yml
# The GHCR jobs (build/smoke and their release twins) deliberately do NOT
# receive APP_ID/APP_PRIVATE_KEY, so they authenticate with GITHUB_TOKEN.
# ci-build documents these as "required only to push outside this repo's own
# GHCR namespace", and this repo only ever pushes ghcr.io/jacaudi/
# critical-thinking -- its own. The same App installation was found (in
# stormglass) to have no package-write grant, so passing them there FAILS
# with "installation not allowed to Write organization package".
#
# `release` still gets the App, which is where it earns its keep: GITHUB_TOKEN
# cannot trigger downstream workflows, and the App owns release-PR attribution.
build:
needs: [context, test]
if: ${{ needs.context.outputs.build == 'true' }}
permissions:
contents: read
packages: write
uses: ./.github/workflows/ci-build.yml
smoke:
needs: [build]
permissions:
contents: read
packages: read
uses: ./.github/workflows/ci-smoke.yml
with:
image: ${{ needs.build.outputs.image }}
release:
needs: [smoke]
if: ${{ github.ref == 'refs/heads/main' }}
permissions:
contents: write
pull-requests: write
secrets:
APP_ID: ${{ secrets.APP_ID }}
APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }}
uses: ./.github/workflows/ci-release.yml
# No App secrets here either -- same own-namespace reasoning as `build`.
release-image:
needs: [release]
if: ${{ needs.release.outputs.release_created == 'true' }}
permissions:
contents: read
packages: write
uses: ./.github/workflows/ci-build.yml
with:
version: ${{ needs.release.outputs.tag_name }}
ref: ${{ needs.release.outputs.tag_name }} # pin to the TAG, not this run's commit
release-smoke:
needs: [release-image]
permissions:
contents: read
packages: read
uses: ./.github/workflows/ci-smoke.yml
with:
image: ${{ needs.release-image.outputs.image }}
# LOCAL ADDITION to the template: this repo ships prebuilt binaries — the
# Claude Code plugin's install hook downloads them from the GitHub Release —
# so goreleaser attaches the archives and checksums to the release
# release-please just created. Independent of the image jobs: a binary
# release must not wait on (or be blocked by) the container build.
release-binaries:
needs: [release]
if: ${{ needs.release.outputs.release_created == 'true' }}
permissions:
contents: write
uses: ./.github/workflows/ci-binaries.yml
with:
tag: ${{ needs.release.outputs.tag_name }}
# The template ships commented-out `release-artifact` and `release-chart`
# jobs plus a multi-image example. They are dropped rather than carried
# commented: this repo ships neither a Helm chart nor a generated release
# manifest, and `task repo:actions:local-refs` strips the leading `#` before
# matching `uses:`, so a commented reference to a stage file that is not
# copied in fails `task lint`. Adding either later stays additive: copy the
# stage in from ~/.claude/skills/github-actions-align/templates/workflows/.
# THE single required status check — point every ruleset at `ci` and nothing else.
ci:
# `context` MUST be here. Without it, a failing context skips build and
# smoke, this gate accepts `skipped`, and the required check goes GREEN on a
# PR whose image was never built or tested.
needs: [context, test, build, smoke]
if: ${{ !cancelled() }} # required: else this is SKIPPED on failure, which can satisfy protection
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: read
pull-requests: read # for the skipped-build re-query below
steps:
- name: Assert required stages
env:
CONTEXT: ${{ needs.context.result }}
TEST: ${{ needs.test.result }}
BUILD: ${{ needs.build.result }}
SMOKE: ${{ needs.smoke.result }}
run: |
set -euo pipefail
fail=0
for stage in context:"${CONTEXT}" test:"${TEST}"; do
name="${stage%%:*}"; result="${stage##*:}"
printf '%-8s %s (must be success)\n' "${name}" "${result}"
[ "${result}" = "success" ] || fail=1
done
# build/smoke skip legitimately when context says "no open PR" — and
# context is asserted successful above, so a skip here is a real
# decision rather than an upstream failure leaking through.
for stage in build:"${BUILD}" smoke:"${SMOKE}"; do
name="${stage%%:*}"; result="${stage##*:}"
printf '%-8s %s (success, or skipped when no PR is open)\n' "${name}" "${result}"
case "${result}" in success|skipped) ;; *) fail=1 ;; esac
done
[ "${fail}" = "0" ] || { echo "::error::one or more required stages did not pass"; exit 1; }
# The backstop for the assertion directly above. That loop accepts a
# skipped build/smoke on `context`'s word, and `context` answered minutes
# ago — so a PR opened after it ran turns "correctly skipped" into "green
# on an image that was never built". Re-asking HERE, at the end of the
# run, is the latest and therefore most accurate point available.
#
# This cannot fire on the normal flow now that `context` waits for
# `test`; it exists so the residual case is LOUD rather than silent.
- name: Reject a skipped image build while a PR is open
if: ${{ needs.build.result == 'skipped' || needs.smoke.result == 'skipped' }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
if [ "${GITHUB_REF}" = "refs/heads/main" ]; then
echo "on main — build/smoke are unconditional there, nothing to re-check"
exit 0
fi
n=$(gh pr list --repo "${GITHUB_REPOSITORY}" --head "${GITHUB_REF_NAME}" \
--state open --json number --jq 'length')
if [ "${n}" -gt 0 ]; then
echo "::error::build/smoke were skipped, but ${n} open PR(s) now exist for ${GITHUB_REF_NAME}. The image was never built or booted, so this run is not evidence the PR is mergeable. Re-run this workflow (gh run rerun <run-id>) now that the PR exists."
exit 1
fi
echo "no open PR for ${GITHUB_REF_NAME} — skipping build/smoke is correct"