A CodeQL upgrade can turn one Rust finding into a notification on a different line, which is enough to confuse a dashboard, a pull-request review, and an audit trail even when the underlying risk has not changed. CodeQL 2.26.4 is especially worth treating as a verification release because it adds Go 1.27 support, sharpens Rust alert locations, and improves GitHub Actions security detections.
The important work is not clicking “rerun.” It is separating expected scan-result movement from a real coverage regression or a genuinely new security finding. The release also mentions accuracy improvements across several other languages, so an organization with mixed repositories should inventory more than its Go and Rust services before declaring the rollout complete.
1. Build an affected-repository inventory first
Start with a list of repositories that contain Go, Rust, or GitHub Actions workflows. Do not rely only on repository topics such as golang or rust; monorepos often contain a Rust command-line tool under tools/, a Go service under cmd/, and reusable workflows under .github/workflows/.
A practical inventory answers three questions: which repositories scan these languages, how CodeQL is run, and who owns the resulting alerts. A repository using GitHub’s default setup needs a different change path from one that owns a checked-in codeql.yml and custom workflow.
| Repository signal | Why it matters for 2.26.4 | Record in the inventory |
|---|---|---|
go.mod or go.work |
Go 1.27 support can affect whether the intended Go source is analyzed. | Go version, module paths, CodeQL workflow name |
Cargo.toml |
Rust findings may point to more precise source locations after the update. | Crate paths, alert owner, open Rust alerts |
.github/workflows/*.yml |
GitHub Actions security detection accuracy can change scan results. | Workflow count, reusable workflows, security owner |
| Custom build steps | Build failures can be mistaken for a query-quality issue. | Build command and required environment variables |
For a small organization, a spreadsheet with one row per repository is enough. For a larger GitHub organization, make this a generated report: search checked-out repositories for go.mod, Cargo.toml, and .github/workflows, then assign an owner before triggering any scans.
2. Capture a baseline at a known commit
Comparing “yesterday’s alerts” with “today’s alerts” is weak evidence if the default branch received merges in between. Record the exact commit SHA you are comparing, the workflow run URL, the CodeQL version reported by the run, and the current open-alert count by language.
Use a baseline ledger, not screenshots. Screenshots omit rule IDs, locations, and dismissals—the details needed when a Rust alert moves from a call site to a more useful source expression.
git rev-parse HEAD
git status --short
codeql version
If CodeQL runs only on GitHub-hosted runners, the last command may not be available on a developer laptop. In that case, add a temporary diagnostic step after CodeQL initialization or read the workflow log for the installed CodeQL version. The verification goal is simple: prove that the baseline and upgrade runs used different scanner versions while analyzing the same source revision.
- Commit SHA of the scanned revision
- Workflow run URL and completion time
- CodeQL version shown in logs
- Language databases created successfully
- Open alerts grouped by rule ID and language
- A short list of known high-priority alerts with file and line
Keep this baseline for at least the duration of the rollout. It gives reviewers a defensible answer when an alert’s location changes but its rule and code path remain recognizably related.
3. Update the delivery path, not just a local CLI
The scanner that matters is the one producing code-scanning results for the repository. Updating a developer’s local CodeQL CLI does not update an organization’s GitHub Actions scans, and rerunning an old workflow does not prove that its runner selected CodeQL 2.26.4.
First identify the delivery model. Repositories may use GitHub’s default setup, a workflow based on the CodeQL Action, or a separately managed CLI invocation. Update the configuration or tool-selection mechanism used by that model, then confirm the installed version in the resulting logs.
- name: Show CodeQL version used by this run
run: codeql version
Place that diagnostic step where the codeql executable is available in the workflow. Remove it after the rollout if your logs already expose the version clearly; keeping it permanently is usually harmless, but it adds one more log line rather than meaningful scan coverage.
Do not combine this upgrade with unrelated workflow modernization. For example, changing actions/upload-artifact@v3 or actions/download-artifact@v3 to version 4 can require unique artifact names within a workflow run. That is worthwhile maintenance, but it creates a second failure mode: a broken artifact handoff can look like a CodeQL build regression. Make CodeQL 2.26.4 its own pull request whenever possible.
4. Rerun scans in an order that produces useful evidence
Run one representative repository from each pattern before updating every repository. A useful pilot set has one Go 1.27 service, one Rust repository with existing alerts, and one repository that scans GitHub Actions workflows. If one monorepo covers all three, use it only if its build is stable enough to diagnose failures quickly.
- Create the upgrade branch or configuration change.
- Trigger the CodeQL workflow against a branch containing a recorded commit SHA.
- Verify that initialization, database creation, analysis, and result upload all succeeded.
- Compare results with the baseline ledger before merging.
- Roll the approved change to repositories sharing the same workflow pattern.
Check workflow logs before looking at alert totals. A scan that silently analyzes less code can produce fewer alerts and appear “cleaner.” Conversely, a successful scan with more alerts may reflect broader detection accuracy rather than a new vulnerable commit.
The decision rule is: treat any failed database creation, missing language database, or unexpectedly skipped build as a rollout blocker. Treat a changed alert count as a review task, not as success or failure by itself. This keeps scanner health separate from security triage.
5. Review Rust location changes as a mapping exercise
The release specifically calls out sharper Rust alert locations. That can improve remediation because the alert points closer to the expression or data flow a developer must change. It also means a location-based comparison alone will overstate the number of “new” findings.
For each changed Rust result, compare four items: rule ID, alert message, affected crate, and the relevant code path. If those are substantially the same but the location moved from a broad function-level line to a specific expression, classify it as a relocated finding. Preserve the old and new locations in the rollout record for high-severity alerts.
| Observed change | Likely interpretation | Reviewer action |
|---|---|---|
| Same rule ID and same crate, different line | Potentially improved alert precision | Read the new location and link it to the prior finding |
| New rule ID in existing Rust code | Potentially newly detected issue | Perform normal security triage |
| Prior Rust alert no longer appears | Could be an analysis change or lost coverage | Confirm the Rust database and crate were analyzed |
| Many alerts move after a refactor and upgrade | Two independent causes changed | Repeat against a fixed pre-refactor commit if possible |
The tradeoff nobody likes is reviewer time: precise locations reduce future remediation time, but the first upgraded run can require manually reconciling alert history. Assign that work to the service owner, not only the central security team, because the owner understands whether two Rust expressions belong to the same data flow.
6. Verify Go 1.27 coverage instead of assuming it
CodeQL 2.26.4 adds Go 1.27 support. That is a coverage change, so the central verification question is not “did the workflow turn green?” It is “did CodeQL successfully create and analyze the Go database for the Go 1.27 code we intended to scan?”
Inspect the workflow output for the Go analysis stage and any build or dependency-resolution errors. In repositories with multiple modules, confirm that the modules containing production code were included; a root-level go.mod is not proof that every nested module was analyzed.
Use a deliberately small Go smoke target
Select one repository that declares Go 1.27 and has a predictable CodeQL run. Record its module layout, then rerun after the upgrade. You are looking for successful database creation and an uploaded result set, not a particular alert count. A repository with zero Go alerts can still be a good coverage smoke test if its logs show the source was discovered and analyzed.
find . -name go.mod -o -name go.work
go version
git rev-parse HEAD
Run these commands in the same checkout used for diagnosis, not necessarily as a replacement for the Actions workflow. If the Go version in CI differs from local development, record both. The upgrade decision should be based on the CI environment that produces GitHub code-scanning results.
7. Treat GitHub Actions findings as workflow code
GitHub Actions workflows are executable security configuration: they decide which pull requests run privileged jobs, which tokens are available, and which third-party actions execute. Since 2.26.4 includes broader accuracy improvements for GitHub Actions security detections, review workflow-related result changes with the same care as application-code findings.
Start with repositories that have complicated workflow surfaces: reusable workflows called with workflow_call, release workflows, pull-request automation, and jobs that write repository contents. These are more valuable pilots than a repository containing only a single test workflow.
When a GitHub Actions result is new, examine the exact workflow revision and trigger context before dismissing it as scanner noise. A workflow using pull_request differs materially from one using a more privileged event, and a reusable workflow can concentrate risk across many repositories. The release’s broader accuracy language is a reason to inspect the result, not a reason to automatically close it.
Also check whether a workflow is scanned at all. A path filter, disabled workflow, malformed YAML file, or scan configuration that excludes the relevant directory can produce a misleadingly quiet result set. The scan log and the repository’s workflow tree are more reliable coverage evidence than an alert count.
8. Classify every difference before changing alert status
Use a three-bucket review so that a scanner upgrade does not create accidental dismissals or duplicate tickets. The bucket matters more than whether the count went up or down.
- Confirmed new finding: a new rule, new workflow issue, or previously unreported risky code path. Create or update the normal remediation ticket.
- Relocated finding: the same underlying issue now points to a sharper Rust location. Keep history connected and avoid assigning duplicate work.
- Coverage concern: an expected language, module, or workflow was not analyzed, or a scan stage failed. Fix scanning before interpreting missing alerts as resolved.
Do not bulk-dismiss alerts solely because the upgrade changed their presentation. Similarly, do not reopen every historical alert merely because its line number changed. The right unit of comparison is the security issue represented by the result, supported by its rule, message, repository context, and code path.
For organizations that export code-scanning data, add a temporary field named scanner_upgrade_2_26_4_review with values such as new, relocated, and coverage-check. Even a CSV maintained for one rollout is better than relying on reviewers to remember why 20 Rust alerts shifted in a week.
9. Complete a one-week rollout with explicit owners
Finish the upgrade as an operational change, not a one-time repository edit. The fastest path is a pilot early in the week, a review window for results, then a grouped rollout by workflow template. Repositories with custom builds should be handled separately from simple default-setup repositories.
- Day 1: inventory Go, Rust, and GitHub Actions repositories; identify owners and scan delivery models.
- Day 2: capture baseline runs at recorded commit SHAs and select three pilot repositories.
- Day 3: update the pilot scan path to CodeQL 2.26.4 and verify the version in logs.
- Day 4: classify Rust location changes, new GitHub Actions findings, and Go coverage results.
- Day 5: roll out to repositories using the same configuration; open follow-up work for custom-build failures or missing coverage.
Close the rollout only when every affected repository has one of three states: verified on 2.26.4, scheduled with an owner and date, or explicitly exempted with a documented reason. That final list is what turns a release update into evidence that Go 1.27 code, Rust code, and GitHub Actions workflows are still being scanned as intended.