Documentation
¶
Overview ¶
Package ciaudit checks repository CI/CD files for explicit coverage gates and build-once artifact promotion. It is deliberately read-only so the same audit can run locally, in CI, or across a workstation fleet.
Index ¶
- func WorkflowMechanismsWithReuse(root, workflow string) (map[string]bool, bool, error)
- type BatchOptions
- type Concurrency
- type Finding
- func CompareAgainstTarget(root, target string) ([]Finding, error)
- func CompareCampaignTestNamesPendingTotal(root, target string) ([]Finding, error)
- func CompareCoverageFloors(root, target string) ([]Finding, error)
- func CompareExecSitesPendingTotal(root, target string) ([]Finding, error)
- func CompareUnitTierPendingTotal(root, target string) ([]Finding, error)
- type Report
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func WorkflowMechanismsWithReuse ¶ added in v0.91.0
WorkflowMechanismsWithReuse additionally reports whether the workflow calls a REUSABLE workflow whose body WB cannot see.
A `uses:` callee lives in another repository, so WB cannot tell whether it runs a mechanism. That is "unverified", never "absent": reporting a mechanism as unguarded because the callee is opaque asserts something WB does not know, which is the same false-assurance failure in the other direction.
Types ¶
type BatchOptions ¶
BatchOptions selects repositories; command output and exit policy stay above this service.
type Concurrency ¶ added in v0.87.0
type Concurrency struct {
// Workflow is the repository-relative workflow path.
Workflow string `json:"workflow"`
// Name is the workflow's declared name, when it has one.
Name string `json:"name,omitempty"`
// PullRequest is true when the workflow runs on pull_request events, and
// therefore runs on a stream branch's draft pull request.
PullRequest bool `json:"pull_request"`
// Push is true when the workflow runs on push events.
Push bool `json:"push"`
// Group is the concurrency group expression, empty when the workflow
// declares no concurrency at all.
Group string `json:"group,omitempty"`
// CancelInProgress is the declared value; false covers both "declared
// false" and "not declared", which Declared distinguishes.
CancelInProgress bool `json:"cancel_in_progress"`
// Declared is true when the workflow declares a concurrency block.
Declared bool `json:"declared"`
// RefKeyed is true when the group expression varies per ref or per pull
// request, which is what makes cancellation scoped to one stream branch
// rather than to the whole repository.
RefKeyed bool `json:"ref_keyed"`
}
Concurrency is one workflow's cancel-in-progress policy.
A stream branch is force-pushed on every rebase, so without a concurrency group keyed to the branch a superseded push races its predecessor instead of cancelling it: the same commit range is built twice and the fleet pays for both. `push-hook-defers-to-ci-on-stream-branches` moves local cost to CI and therefore obliges WB to bound CI, which starts with proving the cancellation is configured at all.
func StreamConcurrency ¶ added in v0.87.0
func StreamConcurrency(root string) ([]Concurrency, error)
StreamConcurrency reads every workflow under .github/workflows and reports the pull-request workflows a stream branch's draft pull request would trigger, with their concurrency policy.
It is deliberately a typed YAML read rather than a regular expression: the value being checked (`cancel-in-progress: true` under a ref-keyed group) is exactly the kind of nested structure a text match reports as present when it is declared for a different job.
func (Concurrency) Cancels ¶ added in v0.87.0
func (concurrency Concurrency) Cancels() bool
Cancels reports whether this workflow cancels a superseded run for the branch it is building.
type Finding ¶
type Finding struct {
Code string `json:"code"`
Message string `json:"message"`
File string `json:"file,omitempty"`
}
func CompareAgainstTarget ¶ added in v0.170.0
CompareAgainstTarget runs every `wb ci audit --target` cross-branch comparison this package owns -- CompareCoverageFloors, CompareUnitTierPendingTotal, CompareExecSitesPendingTotal and CompareCampaignTestNamesPendingTotal -- against root and target, and returns their findings combined and sorted the same way cmd/wb/ci.go already sorts a target comparison's findings (by Code, then File). Callers that want all four comparisons call this one function instead of calling each separately, so adding a further such comparison in the future costs this package a new call here, not a new call site in cmd/wb (review note #764 B5: keep cmd/wb's statement count over this path unchanged; task-8 and task-21 both reuse the same seam for their own ratchets rather than adding a parallel call site).
func CompareCampaignTestNamesPendingTotal ¶ added in v0.172.0
CompareCampaignTestNamesPendingTotal implements spec/plans/coverage-to-100/README.md task-21's cross-PR ratchet on internal/quality/testdata/campaign_test_names.pending (AGENTS.md:108-112): the list's grand total may not rise against the base branch's committed copy, unless the same PR shrinks other entries by at least as much (the PR that creates the list is exempt, since there is no prior copy to compare against).
It follows CompareUnitTierPendingTotal's and CompareExecSitesPendingTotal's own shape exactly -- same technique ("fetch origin/<target> and git show its copy"), same git-agnostic core/exported-wrapper split so a unit test can substitute a fake instead of a real repository, reusing task-24's and task-8's code shape rather than inventing a third style for a naming rule's own ratchet. The real git calls are gitOutput, the same helper the other two comparators use; compareCampaignTestNamesPendingTotal below is the testable core.
func CompareCoverageFloors ¶ added in v0.122.0
CompareCoverageFloors implements lesson:l10-coverage-floors-are-raised-with-real-tests-never-lowered-to-fit: a numeric coverage threshold is a ratchet, and a floor lowered quietly in a branch is exactly the shape the lesson names ("lowering the bar was easier than restructuring the test").
It compares every numeric `min_test_coverage_percent` in root's workflow files against the same file's value on the fetched target branch, and reports any threshold that dropped as a Finding. Unlike Audit, this function is not read-only in the no-process sense: it runs `git fetch` and `git show` against root, because "the fetched target" is a comparison this package cannot make from local files alone — root's own doc comment (see audit.go) describes Audit itself as read-only; this sibling function is the one exception, confined to this file, and only ever runs on explicit request (a non-empty target), never as part of Audit.
It is a deliberate no-op — returning (nil, nil) — when root's current branch already equals target: auditing main against itself has nothing to compare.
func CompareExecSitesPendingTotal ¶ added in v0.172.0
CompareExecSitesPendingTotal implements spec/plans/coverage-to-100/README.md task-8's cross-PR ratchet on internal/quality/testdata/exec_sites.pending: the list's grand total may not rise against the base branch's committed copy, unless the same PR shrinks other entries by at least as much (the PR that creates the list is exempt, since there is no prior copy to compare against).
It follows CompareUnitTierPendingTotal's own shape exactly -- same technique ("fetch origin/<target> and git show its copy"), same git-agnostic core/exported-wrapper split so a unit test can substitute a fake instead of a real repository, reusing task-24's code shape per the task-8 brief rather than inventing a second style. The real git calls are gitOutput, the same helper CompareCoverageFloors and CompareUnitTierPendingTotal use; compareExecSitesPendingTotal below is the testable core.
func CompareUnitTierPendingTotal ¶ added in v0.170.0
CompareUnitTierPendingTotal implements spec/plans/coverage-to-100/README.md task-24's cross-PR ratchet on internal/quality/testdata/unit_tier.pending: the list's grand total may not rise against the base branch's committed copy of the same file, unless the same PR shrinks other entries by at least as much (the PR that creates the list is exempt, since there is no prior copy to compare against).
It follows CompareCoverageFloors's own shape exactly (same package, same file, same "fetch origin/<target> and git show its copy" technique, task-24's own instruction to "reuse the wb ci audit --target pattern"): a deliberate no-op when root's current branch already equals target, and one of the two functions in this package that are not read-only, because "the fetched target" is a comparison this package cannot make from local files alone. The real git calls are gitOutput, the same helper CompareCoverageFloors uses; compareUnitTierPendingTotal below is the testable core.
type Report ¶
type Report struct {
Path string `json:"path"`
HasGo bool `json:"has_go"`
HasFrontend bool `json:"has_frontend"`
HasDeploy bool `json:"has_deploy"`
GoCoverageThreshold bool `json:"go_coverage_threshold"`
FrontendCoverageThreshold bool `json:"frontend_coverage_threshold"`
ArtifactPromotion bool `json:"artifact_promotion"`
Findings []Finding `json:"findings"`
}
func AuditBatch ¶
func AuditBatch(options BatchOptions) ([]Report, error)