feat(ci): add fleet-wide charm security scan report workflow - #485
Merged
Conversation
Adds _local-charm-scan.yaml, a manually-triggered workflow that walks every charm release in manifest.yaml, clones it at its release branch, runs 'just scan', and publishes a report grouped by cycle to the run's job summary. A charm's branch not existing fails the run; vulnerabilities found by the scan itself are reported without failing it.
Groups the scan matrix by repo+branch instead of by charm, so repos hosting several charms at the same track (litmus-operators, loki-operators, mimir-operators, pyroscope-operators, tempo-operators) are cloned once and just scan is run once per charm subdirectory against that single clone. Cuts the matrix from 39 legs to 32 on the current manifest, and the gap grows as those monorepos gain charms. A shared clone failure is now recorded against every charm it backs, each still reported individually.
Groups the scan matrix by repo alone instead of repo+branch. A single 'git clone --depth=1 --no-single-branch' fetches shallow history for every branch of a repo in one network round trip; each release branch is then just a local 'git checkout' against that same clone, run sequentially, so repos gain multi-branch support at zero extra clone cost. Leg count is unchanged today (32, since no charm currently has more than one active branch), but a repo with several supported tracks will no longer need one runner per track. A branch-level checkout failure is now attributed only to the charms on that branch, and a whole-repo clone failure is attributed to all of them.
Adds two justfile recipes, following the repo's existing pattern of manifest-querying just recipes (list-charms, list-expired, ...) and python-shebang recipes (charms.just's tracks/changelog): - list-scan-matrix: the same repo-grouped manifest query that used to be inline jq in the build-matrix job. - scan-repo <repo>: the clone/checkout/scan/record loop that used to be a ~60-line bash block in the scan job. Runs standalone for local debugging, e.g. 'just scan-repo canonical/litmus-operators'. _local-charm-scan.yaml's scan job shrinks to checkout + install deps + 'just scan-repo ""' + upload. As a side effect, scan-repo exiting non-zero on a real checkout failure now drives job failure directly, so the any-failed output and the dedicated 'Fail on checkout error' step are no longer needed. Verified list-scan-matrix and scan-repo directly (not just via actionlint): scan-repo against a real single-branch repo surfaced a real uv audit finding end-to-end, and against a temporarily multi-branched manifest entry it correctly scanned two real branches from one clone and reported a fabricated bad branch as checkout-failed without disturbing the other two results.
Splits the charm-scan recipes (scan-matrix, scan-repo, and the new build-report) out of the root justfile into security.just, mod-imported as 'mod security' - so they're invoked as just security::scan-repo etc. build-report replaces the report job's inline Python heredoc in _local-charm-scan.yaml: it reads a directory of result JSON files (recursively, so both a flat local directory and the one-artifact- per-repo layout download-artifact produces work) and prints the same markdown report to stdout, redirected into $GITHUB_STEP_SUMMARY. _local-charm-scan.yaml's three jobs now do essentially nothing but checkout + install deps + one 'just security::<recipe>' call each. Also gitignores charm-checkout/ and results/, the working directories these recipes create when run locally outside CI.
Parallelizing the charm scan across one runner per repo (up to 33 matrix legs) bought little: each scan is just a shallow clone plus a few lightweight `uv audit` runs, so most of the wall time was runner startup and per-leg artifact upload/download rather than actual scanning. Replace the build-matrix/scan-matrix/report job split with a single job that loops `scan-repo` over every repo sequentially via a new scan-fleet recipe, then builds the report directly from the local results directory. Drops the GitHub Actions matrix and all per-repo artifacts.
scan-fleet -> scan-charms, scan-repo -> scan-charm-repo, both grouped under "charms" instead of "security"; build-report grouped under "report". Also calls out that scan-charms runs uv audit.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
_local-charm-scan.yaml, a prototype workflow (following the repo's existing_local-*.yamlstaging convention) that walks every charm release inmanifest.yaml, clones it at its release branch, runsjust scan, and publishes a single grouped report to the run's job summary.Changes
build-matrixjob flattensmanifest.yaml's charm releases into a matrix (charm, repo, path, branch, cycle, LTS).scanjob (one leg per charm release,fail-fast: false) clones the charm at its release branch and runsjust scan, capturing output for the report.reportjob aggregates all results into$GITHUB_STEP_SUMMARY, grouped by release cycle, with a collapsible details block per charm showing its LTS status and raw scan output.just scanare reported but do not fail the run.Notes
Manual trigger only (
workflow_dispatch), no schedule yet. Opened as a draft since this is a first pass at a_local-prototype, not yet promoted to a real workflow name.