Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions standards/ci-standards.md
Original file line number Diff line number Diff line change
Expand Up @@ -732,12 +732,17 @@ first time it is **added** to a SonarCloud-gated repo. (The legacy per-file
also works and is accepted during transition, but the inline marker is canonical.)

Caller-stub templates that use `secrets: inherit` and therefore carry the S7635
marker: `initiative-planner.yml`, `idea-triage.yml`, `idea-enhancer.yml`.
**Pending:** `dev-lead.yml`, `auto-rebase.yml`, `dependabot-automerge.yml`, and
`pr-review-mention.yml` also use `secrets: inherit` but do not yet carry the
marker; because they are already deployed fleet-wide (so re-syncing them fans out
broadly) the marker is being added to them under a separate rollout — until then a
**new** adoption of one of those four needs the legacy per-file S7635 exemption.
marker: `initiative-planner.yml`, `idea-triage.yml`, `idea-enhancer.yml`,
`persona-mention.yml`, `dev-lead.yml`, `auto-rebase.yml`,
`dependabot-automerge.yml`. Every template with a `secrets: inherit` line now
carries the marker; the
[`s7635-secrets-inherit.bats`](https://github.com/petry-projects/.github/blob/main/test/scripts/standards-templates/s7635-secrets-inherit.bats)
template guard fails CI if any such line drops it (mirrors the S7637 v-form pin
guard).

Stubs that pass secrets **explicitly** (least privilege — no `secrets: inherit`
line, e.g. `add-to-project.yml`, `pr-review-mention.yml`) never trip S7635 and
carry **no** marker. Do not add one, as the marker is only necessary for `secrets: inherit` lines, which these stubs lack.

### 4. Secret Scanning (`ci.yml` — gitleaks job)

Expand Down
2 changes: 1 addition & 1 deletion standards/workflows/auto-rebase.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,4 @@ jobs:
contents: write # update-branch via GITHUB_TOKEN (may touch .github/workflows/)
pull-requests: write # post comments on PRs
uses: petry-projects/.github/.github/workflows/auto-rebase-reusable.yml@auto-rebase/v2-stable # NOSONAR(githubactions:S7637) first-party channel ref
secrets: inherit
secrets: inherit # NOSONAR(githubactions:S7635) first-party trusted reusable
2 changes: 1 addition & 1 deletion standards/workflows/dependabot-automerge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ jobs:
contents: read
pull-requests: read
uses: petry-projects/.github/.github/workflows/dependabot-automerge-reusable.yml@dependabot-automerge/v2-stable # NOSONAR(githubactions:S7637) first-party channel ref
secrets: inherit
secrets: inherit # NOSONAR(githubactions:S7635) first-party trusted reusable
2 changes: 1 addition & 1 deletion standards/workflows/dev-lead.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ jobs:
uses: petry-projects/.github-private/.github/workflows/dev-lead-reusable.yml@dev-lead/v1-stable # NOSONAR(githubactions:S7637) first-party channel ref
with:
agent_ref: dev-lead/v1-stable
secrets: inherit
secrets: inherit # NOSONAR(githubactions:S7635) first-party trusted reusable
permissions:
contents: write
pull-requests: write
Expand Down
86 changes: 86 additions & 0 deletions test/scripts/standards-templates/s7635-secrets-inherit.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/usr/bin/env bats
# Template-guard for the S7635 NOSONAR marker on caller-stub templates under
# standards/workflows/ (#875, mirrors the #860 v-form/S7637 pin guard).
#
# A caller stub that hands the reusable every org secret via `secrets: inherit`
# trips SonarCloud rule `githubactions:S7635` ("only pass required secrets").
# The reusable is first-party and fully trusted, so the stub carries an inline
# secrets: inherit # NOSONAR(githubactions:S7635) <prose>
# marker that suppresses S7635 on exactly that line and travels with the stub to
# every consumer repo. Dropping the marker regresses any consumer that copied
# the stub (re-triggers S7635 in their SonarCloud run). This guard fails in CI
# the moment a template with `secrets: inherit` loses the marker.
#
# Stubs that pass secrets EXPLICITLY (least privilege, no `secrets: inherit`
# line — e.g. add-to-project.yml, pr-review-mention.yml) do not trip S7635 and
# are correctly ignored: the guard only inspects real `secrets: inherit` lines.

REPO_ROOT="$(cd -- "${BATS_TEST_DIRNAME}/../../.." && pwd)"
WF_DIR="${REPO_ROOT}/standards/workflows"

# The exact NOSONAR token every marked line must carry (grep -F, literal).
MARKER='NOSONAR(githubactions:S7635)'

# Emit `secrets: inherit` lines that are REAL YAML (indented key), never a `#`
# comment mention. Anchors `secrets:` to the start-of-line-after-indent so a
# prose line like `# ... secrets: inherit ...` is not matched.
secrets_inherit_lines() {
grep -nE '^[[:space:]]*secrets:[[:space:]]+inherit([[:space:]]|$)' "$1" || true
}

@test "every template with 'secrets: inherit' carries the S7635 marker" {
local violations=()
local f name lines line lineno content
for f in "${WF_DIR}"/*.yml; do
name="$(basename "$f")"
lines="$(secrets_inherit_lines "$f")"
[ -n "$lines" ] || continue
while IFS= read -r line; do
lineno="${line%%:*}"
content="${line#*:}"
if ! grep -qF "$MARKER" <<<"$content"; then
violations+=("${name}:${lineno}: 'secrets: inherit' line lacks ${MARKER}")
fi
done <<<"$lines"
done
if [ "${#violations[@]}" -ne 0 ]; then
printf 'missing S7635 marker -> %s\n' "${violations[@]}"
return 1
fi
}
Comment thread
don-petry marked this conversation as resolved.

@test "every S7635 marker uses the canonical inline shape" {
# Two spaces before the '#', then the exact token. Trailing prose is free-form
# (e.g. 'first-party trusted reusable' vs 'org secrets are scoped ...'), but
# the marker itself must be byte-consistent so SonarCloud honours it.
local violations=()
local f name lines line lineno content
for f in "${WF_DIR}"/*.yml; do
name="$(basename "$f")"
lines="$(secrets_inherit_lines "$f")"
[ -n "$lines" ] || continue
while IFS= read -r line; do
lineno="${line%%:*}"
content="${line#*:}"
grep -qF "$MARKER" <<<"$content" || continue
if ! grep -qE 'secrets: inherit # NOSONAR\(githubactions:S7635\) ' <<<"$content"; then
violations+=("${name}:${lineno}: marker is not the canonical 'secrets: inherit # NOSONAR(githubactions:S7635) <prose>' shape")
fi
done <<<"$lines"
done
if [ "${#violations[@]}" -ne 0 ]; then
printf 'bad marker shape -> %s\n' "${violations[@]}"
return 1
fi
}
Comment thread
don-petry marked this conversation as resolved.

@test "the guard actually inspects at least one 'secrets: inherit' stub" {
# Positive control: without this, a broken matcher that finds nothing would let
# the first test pass vacuously (its `[ -n "$lines" ] || continue` skips every
# file). At least one template uses `secrets: inherit` by design.
local f found=0
for f in "${WF_DIR}"/*.yml; do
[ -n "$(secrets_inherit_lines "$f")" ] && found=1 && break
done
[ "$found" -eq 1 ] || { echo "no template with a real 'secrets: inherit' line found"; return 1; }
}
Loading