Skip to content

Replace per-repo CodeQL workflows with GitHub default setup#103

Merged
don-petry merged 3 commits intomainfrom
feat/codeql-default-setup-standard
Apr 9, 2026
Merged

Replace per-repo CodeQL workflows with GitHub default setup#103
don-petry merged 3 commits intomainfrom
feat/codeql-default-setup-standard

Conversation

@don-petry
Copy link
Copy Markdown
Contributor

@don-petry don-petry commented Apr 9, 2026

Summary

  • Rewrites standards/ci-standards.md §2 — CodeQL is now configured via GitHub-managed default setup (Settings → Code security), not a per-repo codeql.yml workflow file. Documents rationale, escape hatch for advanced setup, and migration steps.
  • Deletes .github/workflows/codeql.yml from this repo (just added in feat(security): add codeql.yml for SAST scanning #100) — this repo will use default setup like the rest of the fleet.
  • Updates scripts/compliance-audit.sh — removes codeql.yml from REQUIRED_WORKFLOWS, adds check_codeql_default_setup() that probes the code-scanning/default-setup API and flags both unconfigured repos and stray codeql.yml files as drift.
  • Updates scripts/apply-rulesets.sh — derives the CodeQL required-status-check context from the default-setup API instead of parsing a workflow file for job names.
  • Updates scripts/apply-repo-settings.sh — adds apply_codeql_default_setup() so --all runs enable default setup across the fleet idempotently.

Motivation

Every repo in the fleet carried a minimal codeql.yml that did nothing default setup doesn't already do — no custom query packs, no path filters, no build steps. The cost of maintaining N copies (SHA pinning, Dependabot bumps, language matrix drift) outweighed the marginal supply-chain benefit of pinning a first-party GitHub action.

Default setup also adds automatic language re-detection (new languages picked up without YAML edits), managed analyzer versions, and one fewer workflow file per repo.

Migration plan

  1. Merge this PR to update the standard and scripts
  2. Run apply-repo-settings.sh --all to enable default setup on all repos
  3. Delete codeql.yml from repos that still have one (broodly, markets, google-app-scripts, etc.)
  4. Next compliance audit run will validate the fleet is green

Test plan

  • bash -n passes on all three modified scripts (verified locally)
  • DRY_RUN=true ./scripts/compliance-audit.sh runs to completion with the new check
  • DRY_RUN=true ./scripts/apply-repo-settings.sh --all shows the CodeQL default setup step
  • After merging: apply-repo-settings.sh --all enables default setup fleet-wide
  • After merging: verify CodeQL appears in code-quality ruleset required checks after apply-rulesets.sh run
  • Stray codeql.yml files flagged by next compliance audit

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores

    • CodeQL scans now use GitHub-managed default setup instead of per-repo workflow files; automation updated to enable and skip repos as needed and to tolerate partial failures.
    • Compliance auditing and ruleset application updated to detect and require the default-setup state and treat legacy workflow files as drift.
  • Documentation

    • CI and GitHub settings docs updated to describe default setup, required status check name "CodeQL", and revised compliance guidance.

Copilot AI review requested due to automatic review settings April 9, 2026 07:29
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 9, 2026

📝 Walkthrough

Walkthrough

This PR migrates CodeQL from per-repo workflows to GitHub-managed default setup: removes .github/workflows/codeql.yml, adds automation to enable default setup via the Code Scanning API, updates ruleset detection to query the default-setup API, and changes compliance auditing to validate default-setup state and treat per-repo workflows as drift.

Changes

Cohort / File(s) Summary
Workflow Removal
\.github/workflows/codeql.yml
Deleted the per-repo CodeQL Analysis workflow file and its triggers.
Repository Settings Automation
scripts/apply-repo-settings.sh
Added apply_codeql_default_setup() and CODEQL_ADVANCED_EXCEPTIONS; idempotent API check + PATCH to enable state=configured; skips on DRY_RUN; non-blocking PATCH failures emit warnings.
Ruleset Detection Logic
scripts/apply-rulesets.sh
Replaced workflow-file probing with API probe to repos/$ORG/$repo/code-scanning/default-setup; when .state == configured add single required status check CodeQL; API failures cause error/exit.
Compliance Auditing
scripts/compliance-audit.sh
Removed per-repo codeql.yml from REQUIRED_WORKFLOWS; added check_codeql_default_setup() to error when default setup not configured and to flag stray per-repo codeql.yml as drift; reordered checks.
Standards Documentation
standards/ci-standards.md, standards/github-settings.md
Documented GitHub-managed default setup tier, removed per-repo codeql.yml guidance, replaced required check names with CodeQL, updated compliance/audit expectations and examples.

Sequence Diagram(s)

sequenceDiagram
  actor Operator
  participant ApplyScript as "apply-repo-settings.sh"
  participant Ruleset as "apply-rulesets.sh"
  participant Audit as "compliance-audit.sh"
  participant GHAPI as "GitHub Code Scanning API\n(code-scanning/default-setup)"
  Operator->>ApplyScript: run (--all or single repo)
  ApplyScript->>GHAPI: GET default-setup state
  GHAPI-->>ApplyScript: returns state (configured|not configured|error)
  alt state != configured and not DRY_RUN
    ApplyScript->>GHAPI: PATCH state=configured, query_suite=default
    GHAPI-->>ApplyScript: success|failure (warning on failure)
  end
  Operator->>Ruleset: run ruleset application
  Ruleset->>GHAPI: GET default-setup state
  GHAPI-->>Ruleset: returns state
  Ruleset-->>Operator: add required check "CodeQL" if state==configured
  Operator->>Audit: run compliance audit per repo
  Audit->>GHAPI: GET default-setup state
  GHAPI-->>Audit: returns state
  alt state != configured or API error
    Audit-->>Operator: emit error codeql-default-setup-not-configured
  else if repo contains .github/workflows/codeql.yml
    Audit-->>Operator: emit error stray-codeql-workflow
  end
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: replacing per-repo CodeQL workflow files with GitHub's managed default setup across the codebase and standards.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/codeql-default-setup-standard

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the organization’s CI standard and automation scripts to rely on GitHub’s CodeQL default setup (repo settings) instead of a per-repo codeql.yml workflow, and removes the now-redundant workflow from this repository.

Changes:

  • Document CodeQL as GitHub-managed default setup in standards/ci-standards.md, including rationale and migration guidance.
  • Update compliance and fleet-management scripts to (a) audit CodeQL default setup state via API and (b) enable it via apply-repo-settings.sh.
  • Remove .github/workflows/codeql.yml from this repo.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
standards/ci-standards.md Rewrites CodeQL guidance to default setup, updates required workflows/check naming, and adjusts compliance table language.
scripts/compliance-audit.sh Drops codeql.yml from required workflows and adds API-based check_codeql_default_setup() + drift detection for stray codeql.yml.
scripts/apply-rulesets.sh Derives CodeQL required-check context from default-setup API (CodeQL) instead of parsing workflow job names.
scripts/apply-repo-settings.sh Adds apply_codeql_default_setup() to enable CodeQL default setup idempotently (including in --all).
.github/workflows/codeql.yml Deletes the repository’s advanced CodeQL workflow in favor of default setup.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/compliance-audit.sh Outdated
Comment thread scripts/apply-repo-settings.sh
Comment thread standards/ci-standards.md
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/apply-repo-settings.sh`:
- Around line 191-193: Before issuing the PATCH to enable default CodeQL setup
in scripts/apply-repo-settings.sh, check a shared exception source for approved
advanced-setup repos and skip the PATCH when the current $repo is listed; add a
new check (e.g., load a file or env var like ADVANCED_CODEQL_EXCEPTIONS or a
repo-maintained list) and short-circuit the existing PATCH block that uses gh
api -X PATCH "repos/$ORG/$repo/code-scanning/default-setup" -F state=configured
-F query_suite=default so that repos in the exception list are left on their
documented advanced codeql.yml workflow.

In `@scripts/apply-rulesets.sh`:
- Around line 92-97: The current probe uses `codeql_state=$(gh api ... --jq
'.state' 2>/dev/null || echo "")`, which hides API errors; change the probe
around the `gh api` call so that you capture stderr separately and distinguish
three outcomes: (1) explicit "not-configured" state — keep the existing info
message and skip adding `checks+=("CodeQL")`; (2) explicit "configured" state —
add `checks+=("CodeQL")`; (3) any other failure from the `gh api` call (token
scope missing, transient API error) — treat as a hard failure: log the captured
stderr and exit nonzero. Locate and update the block using the `codeql_state`
variable and the `gh api "repos/$ORG/$repo/code-scanning/default-setup"`
invocation so the script exits on probe errors rather than silently omitting
CodeQL.

In `@standards/ci-standards.md`:
- Line 639: Update the Python example section that currently reads "**Repos
using this pattern:** _(none currently — Python coverage in TalkTerm previously
came from its `codeql.yml`, which has been removed in favor of GitHub default
setup)_" by removing the misleading "CodeQL/coverage" wording and either leave
the repo list empty or replace that parenthetical with a reference to a real
Python CI example (e.g., point to a proper `ci.yml` for Python). Locate the
section by the exact header text "**Repos using this pattern:**" and the
parenthetical mentioning `codeql.yml` and edit the sentence so it no longer
implies CodeQL provided test coverage.
- Around line 722-726: The blockquote in the markdown is broken by a stray blank
line between the two quoted paragraphs (the lines starting with "> **CodeQL is
not in this table**" and the following paragraph), which triggers MD028; either
merge the two quoted paragraphs into a single continuous blockquote (remove the
blank line so both lines start with "> ") or stop quoting the second paragraph
(remove the leading ">" from the second paragraph) so the blockquote does not
contain a blank line; update the lines containing the two blockquote markers
accordingly to make markdownlint pass.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 282d4f42-5c4c-45b3-99d9-e94716d3601d

📥 Commits

Reviewing files that changed from the base of the PR and between 497c2b7 and b263c18.

📒 Files selected for processing (5)
  • .github/workflows/codeql.yml
  • scripts/apply-repo-settings.sh
  • scripts/apply-rulesets.sh
  • scripts/compliance-audit.sh
  • standards/ci-standards.md
💤 Files with no reviewable changes (1)
  • .github/workflows/codeql.yml

Comment thread scripts/apply-repo-settings.sh Outdated
Comment thread scripts/apply-rulesets.sh Outdated
Comment thread standards/ci-standards.md Outdated
Comment thread standards/ci-standards.md Outdated
don-petry and others added 2 commits April 9, 2026 05:00
… setup

The org standard previously required every repo to carry a codeql.yml
workflow file. In practice the fleet used a minimal advanced configuration
that added maintenance overhead (SHA pinning, Dependabot bumps, manual
language matrix) without providing anything GitHub's managed default setup
doesn't already cover.

This commit:
- Rewrites ci-standards.md §2 to make default setup the standard
- Deletes .github/workflows/codeql.yml from this repo (added in #100)
- Updates compliance-audit.sh: replaces codeql.yml file existence check
  with code-scanning/default-setup API probe, and flags stray codeql.yml
  files as drift
- Updates apply-rulesets.sh: derives the `CodeQL` required-status-check
  context from the default-setup API instead of workflow file parsing
- Updates apply-repo-settings.sh: adds apply_codeql_default_setup()
  so `--all` runs enable default setup fleet-wide

Repos with a concrete need for advanced setup (custom query packs, path
filters, compiled-language build modes) may opt out by filing a standards
PR documenting the exception.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace placeholder #<this-pr> with #103 in compliance-audit.sh
- Fix apply-repo-settings.sh: docstring now matches behavior (warn and
  continue on failure, not hard fail); add CODEQL_ADVANCED_EXCEPTIONS
  list so approved advanced-setup repos are skipped
- Fix apply-rulesets.sh: distinguish API probe errors from explicit
  "not-configured" state — probe failures now exit nonzero instead of
  silently omitting CodeQL from required checks
- Fix ci-standards.md: remove misleading "coverage" wording from Python
  section; fix MD028 blank line inside blockquote (Lint failure)
- Update github-settings.md: CodeQL check name is now `CodeQL` (default
  setup context), not `Analyze` / `Analyze (<language>)`

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@don-petry don-petry force-pushed the feat/codeql-default-setup-standard branch from b263c18 to 59850cd Compare April 9, 2026 12:01
@don-petry
Copy link
Copy Markdown
Contributor Author

@coderabbitai resolve

@don-petry
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 9, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/apply-rulesets.sh (1)

291-294: ⚠️ Potential issue | 🔴 Critical

Propagate detect_required_checks() failures before updating the ruleset.

mapfile -t checks < <(detect_required_checks "$repo") ignores the producer's exit status. If the CodeQL probe fails on Lines 100-103, this call can still continue with a partial check list and rewrite code-quality without the SAST gate.

🔧 Suggested fix
-  local checks=()
-  mapfile -t checks < <(detect_required_checks "$repo")
+  local checks_output
+  if ! checks_output=$(detect_required_checks "$repo"); then
+    err "  Failed to detect required checks for $ORG/$repo"
+    return 1
+  fi
+
+  local checks=()
+  if [ -n "$checks_output" ]; then
+    mapfile -t checks <<< "$checks_output"
+  fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/apply-rulesets.sh` around lines 291 - 294, The mapfile
process-substitution hides detect_required_checks()'s exit status causing
failures to be ignored; instead capture detect_required_checks "$repo" output
into a variable or temp file, check its exit code immediately, and if non-zero
return/exit before touching the ruleset. Concretely: run
output=$(detect_required_checks "$repo"); status=$?; if [ $status -ne 0 ]; then
exit $status (or return) ; fi; then populate the checks array with mapfile -t
checks <<<"$output" (or readarray) and proceed — this ensures
detect_required_checks() failures are propagated and prevents rewriting the
code-quality ruleset when the probe failed.
♻️ Duplicate comments (1)
standards/ci-standards.md (1)

722-727: ⚠️ Potential issue | 🟡 Minor

Remove the blank blockquote line.

The standalone > on Line 726 is still a blank line inside the blockquote, so markdownlint will keep flagging MD028 here.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@standards/ci-standards.md` around lines 722 - 727, Remove the stray blank
blockquote marker in the quoted paragraph: delete the standalone ">" line (the
empty blockquote on the middle line of the three-line block starting with
"**CodeQL is not in this table**") so the blockquote contains only the intended
text lines and markdownlint MD028 no longer triggers.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/apply-repo-settings.sh`:
- Around line 184-186: Replace the local CODEQL_ADVANCED_EXCEPTIONS array with a
single shared source file containing the approved exception list and have all
scripts source that file; specifically, extract the CODEQL_ADVANCED_EXCEPTIONS
array into a new shared shell file (exporting or declaring the array and
providing a default empty value), update apply-repo-settings.sh to source the
shared file instead of defining CODEQL_ADVANCED_EXCEPTIONS locally, and update
scripts that check CodeQL setup (the logic in compliance-audit.sh that raises
codeql-default-setup-not-configured / stray-codeql-workflow and the logic in
apply-rulesets.sh that enforces the default setup) to reference the shared
CODEQL_ADVANCED_EXCEPTIONS variable so onboarding, audit, and ruleset
enforcement use the same exception list.
- Around line 213-223: The failure branch handling the gh API call (api_err from
gh api PATCH to "repos/$ORG/$repo/code-scanning/default-setup") uses an
undefined warn and then returns 0 which hides rollout failures; replace the
undefined warn with a real logging call (e.g., the script's existing
error/logger helper or a stderr echo) and do not return success. Instead of
"return 0", mark the overall run as failed by setting a global failure flag
(e.g., FAILED=1) or return a non-zero status so the error is surfaced (and
ensure the script exits with failure at the end if FAILED is set). Ensure
references to api_err, the gh api call, and the ok/log helper remain consistent.

In `@scripts/apply-rulesets.sh`:
- Line 9: Update the header comment in apply-rulesets.sh that currently reads
"code-quality  — required status checks (CI, SonarCloud, CodeQL default setup,
Claude Code)" by removing "Claude Code" so the header matches the script's
actual behavior (which excludes Claude in the ruleset logic); edit the comment
string in the script's top section to list only the enforced checks (e.g., "CI,
SonarCloud, CodeQL default setup") and keep the rest of the comment formatting
intact.

In `@standards/ci-standards.md`:
- Line 831: The onboarding step 3 omitted the query_suite parameter, causing the
documented org-standard CodeQL config to be inconsistent; update the step text
so the gh API/CLI example used by apply-repo-settings.sh includes -F
query_suite=default (i.e., use `gh api -X PATCH
repos/<org>/<repo>/code-scanning/default-setup -F state=configured -F
query_suite=default`) and ensure the prose references that same default as §2
and scripts/apply-repo-settings.sh to keep the documentation consistent (do not
add a codeql.yml workflow file).

---

Outside diff comments:
In `@scripts/apply-rulesets.sh`:
- Around line 291-294: The mapfile process-substitution hides
detect_required_checks()'s exit status causing failures to be ignored; instead
capture detect_required_checks "$repo" output into a variable or temp file,
check its exit code immediately, and if non-zero return/exit before touching the
ruleset. Concretely: run output=$(detect_required_checks "$repo"); status=$?; if
[ $status -ne 0 ]; then exit $status (or return) ; fi; then populate the checks
array with mapfile -t checks <<<"$output" (or readarray) and proceed — this
ensures detect_required_checks() failures are propagated and prevents rewriting
the code-quality ruleset when the probe failed.

---

Duplicate comments:
In `@standards/ci-standards.md`:
- Around line 722-727: Remove the stray blank blockquote marker in the quoted
paragraph: delete the standalone ">" line (the empty blockquote on the middle
line of the three-line block starting with "**CodeQL is not in this table**") so
the blockquote contains only the intended text lines and markdownlint MD028 no
longer triggers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 54e27f06-28e3-44d8-8735-ad77dcf189b0

📥 Commits

Reviewing files that changed from the base of the PR and between b263c18 and 59850cd.

📒 Files selected for processing (6)
  • .github/workflows/codeql.yml
  • scripts/apply-repo-settings.sh
  • scripts/apply-rulesets.sh
  • scripts/compliance-audit.sh
  • standards/ci-standards.md
  • standards/github-settings.md
💤 Files with no reviewable changes (1)
  • .github/workflows/codeql.yml

Comment thread scripts/apply-repo-settings.sh
Comment thread scripts/apply-repo-settings.sh
Comment thread scripts/apply-rulesets.sh
Comment thread standards/ci-standards.md
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Apr 9, 2026

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 9, 2026

✅ Actions performed

Comments resolved and changes approved.

@don-petry don-petry merged commit a3e9658 into main Apr 9, 2026
24 checks passed
@don-petry don-petry deleted the feat/codeql-default-setup-standard branch April 9, 2026 12:09
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.

2 participants