From efc62893a7aaed3eb05495f777a7d7b31528547d Mon Sep 17 00:00:00 2001 From: Don Petry Date: Thu, 2 Jul 2026 09:43:32 -0500 Subject: [PATCH 1/2] feat(ci-template): add secret-scan + coverage jobs to standards/workflows/ci.yml (#575) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The day-0 CI template gains the two org required-check producers so repos created from repo-template are forward-compatible with the code-quality ruleset: - secret-scan → `Secret scan (gitleaks)`: copied verbatim from push-protection.md#required-ci-job — gitleaks CLI (the action's v2+ needs a paid org license), fully pinned + checksum-verified, `--config .gitleaks.toml`, `--redact`, `--exit-code 1`, `contents: read` only (no SARIF upload, so no `security-events: write`). Requires a .gitleaks.toml at repo root, seeded alongside this template (companion .github-private PR wires seed-repo-template.sh). - coverage → `coverage`: stack-aware, default shell/bats via kcov. Green-until-tests — succeeds with no report when a stack emits no coverage, so seeding it fleet-wide never bricks a repo without a test suite; enforces once tests exist. Per-stack expansion blocks (Node/Go/Python/Rust) documented inline; job name kept `coverage`. checkout pinned to actions/checkout@de0fac2e…#v6.0.2 (verified via API; matches the existing template + push-protection.md). yamllint (repo rules) + actionlint clean. Adding these contexts to the code-quality ruleset is sequenced SEPARATELY (follow-up PR) and scoped to template/new repos — existing fleet repos have no coverage job, so a fleet-wide required `coverage` would brick them (the #575 finding). Part of #575 (folded-in from closed #569). Epic #964. Co-Authored-By: Claude Opus 4.8 (1M context) --- standards/workflows/ci.yml | 71 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/standards/workflows/ci.yml b/standards/workflows/ci.yml index 1e359244..73a3c621 100644 --- a/standards/workflows/ci.yml +++ b/standards/workflows/ci.yml @@ -10,6 +10,10 @@ # 3. The job name `build-and-test` is the required CI status check. Keep it — or, # if you split into per-language jobs (e.g. TypeScript, Go, Python), update the # repo's branch-protection required checks to match the new job names. +# 4. Two more jobs ship by default and are org required checks — `Secret scan +# (gitleaks)` (per push-protection.md; needs a .gitleaks.toml at root, seeded +# with this template) and `coverage` (green until your stack emits coverage). +# Keep their job names stable so the required checks stay satisfied. # # CONVENTIONS (enforced by the standard): # • permissions: {} at top, least-privilege per job (CI needs contents: read) @@ -51,3 +55,70 @@ jobs: # placeholder below keeps the required `build-and-test` check green. - name: Placeholder — replace with real build/test steps run: echo "CI stub — add your stack's lint/format/typecheck/test/coverage steps; see BOOTSTRAP.md." + + # Canonical secret-scan job — copied verbatim from push-protection.md#required-ci-job. + # Produces the `Secret scan (gitleaks)` required check. Uses the gitleaks CLI (not + # gitleaks/gitleaks-action, whose v2+ needs a paid org license); fully pinned + + # checksum-verified; no SARIF upload, so no `security-events: write` permission. + secret-scan: + name: Secret scan (gitleaks) + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout (full history) + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + + - name: Install gitleaks + env: + GITLEAKS_VERSION: "8.30.1" + # Named GITLEAKS_CHECKSUM (not GITLEAKS_SHA256) — SonarCloud flags env var names + # matching *SHA256* containing hex strings as Security Hotspots (false positive). + GITLEAKS_CHECKSUM: "551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb" + run: | + tarball="gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" + url="https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/${tarball}" + wget -q "${url}" -O /tmp/gitleaks.tar.gz + echo "${GITLEAKS_CHECKSUM} /tmp/gitleaks.tar.gz" | sha256sum -c + tar -xzf /tmp/gitleaks.tar.gz -C /usr/local/bin gitleaks + + - name: Run gitleaks + # Requires a .gitleaks.toml at repo root (seeded by seed-repo-template.sh). + run: gitleaks detect --source . --config .gitleaks.toml --redact --verbose --exit-code 1 + + # Stack-aware coverage — produces the `coverage` required check. Default stack is + # shell/bats via kcov. GREEN-UNTIL-TESTS: when a stack emits no coverage yet, the + # job succeeds without producing a report, so seeding it fleet-wide never bricks a + # repo that has no test suite. It begins enforcing once tests exist. Add a per-stack + # block below (keep the job id and `name:` as `coverage` so the required check is stable). + coverage: + name: coverage + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Coverage (shell/bats via kcov) + run: | + shopt -s globstar nullglob + bats_files=(tests/**/*.bats) + if [ ${#bats_files[@]} -eq 0 ]; then + echo "No bats tests found — coverage is green until tests exist." + exit 0 + fi + sudo apt-get update -qq + sudo apt-get install -y -qq bats kcov + mkdir -p coverage + kcov --include-path=. --exclude-path=tests,coverage coverage bats "${bats_files[@]}" + echo "Coverage report written to ./coverage" + + # ── Per-stack expansion — replace/augment the shell block above for your stack. + # Keep the job id and `name:` as `coverage` so the required check is unchanged. + # Node: npx jest --coverage + # Go: go test ./... -coverprofile=coverage.out && go tool cover -func=coverage.out + # Python: pytest --cov + # Rust: cargo llvm-cov --workspace From 1190d33b3d52c0152d8cf2cf7aae8b765659ed62 Mon Sep 17 00:00:00 2001 From: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com> Date: Thu, 2 Jul 2026 14:47:24 +0000 Subject: [PATCH 2/2] fix(bot): address bot feedback [skip ci-relay] --- standards/workflows/ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/standards/workflows/ci.yml b/standards/workflows/ci.yml index 73a3c621..c2df94bf 100644 --- a/standards/workflows/ci.yml +++ b/standards/workflows/ci.yml @@ -12,7 +12,7 @@ # repo's branch-protection required checks to match the new job names. # 4. Two more jobs ship by default and are org required checks — `Secret scan # (gitleaks)` (per push-protection.md; needs a .gitleaks.toml at root, seeded -# with this template) and `coverage` (green until your stack emits coverage). +# by repo-template tooling) and `coverage` (green until your stack emits coverage). # Keep their job names stable so the required checks stay satisfied. # # CONVENTIONS (enforced by the standard): @@ -82,7 +82,8 @@ jobs: url="https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/${tarball}" wget -q "${url}" -O /tmp/gitleaks.tar.gz echo "${GITLEAKS_CHECKSUM} /tmp/gitleaks.tar.gz" | sha256sum -c - tar -xzf /tmp/gitleaks.tar.gz -C /usr/local/bin gitleaks + tar -xzf /tmp/gitleaks.tar.gz -C /tmp gitleaks + sudo mv /tmp/gitleaks /usr/local/bin - name: Run gitleaks # Requires a .gitleaks.toml at repo root (seeded by seed-repo-template.sh).