Generate a read-only promotion evidence report¶
The opt-in developer command scripts/promotion-readiness.py summarizes local Git evidence for a proposed production change. It neither promotes nor certifies readiness. It replaces the useful reporting portion of the historical local promotion skill; it does not restore that skill's obsolete stacked-promotion workflow.
It reads two pinned revisions of a local cluster-gitops checkout and two explicitly selected SyRF source revisions. Fetch refs separately if needed. Nothing fetches automatically, contacts a cluster, queries databases, invokes a GitHub API, changes flags, merges PRs or closes promotion PRs. No application feature flag is needed: this is a manually invoked reporting tool outside application execution paths.
Usage¶
Requires Git, Python 3.10+ and PyYAML 6.0.3. An isolated dependency runner avoids changing system Python:
uv run --no-project --with-requirements scripts/promotion-readiness-requirements.txt \
python scripts/promotion-readiness.py \
--gitops /path/to/cluster-gitops \
--gitops-before <reviewed-production-baseline-ref> \
--gitops-after <rolling-promotion-PR-ref> \
--source /path/to/syrf/worktree \
--source-before <corresponding-production-source-commit> \
--source-after <corresponding-proposed-source-commit> \
> /tmp/promotion-evidence.md
Use --format json for structured output. All refs resolve to immutable commit IDs before collection. The source baseline must be an ancestor of the target; reversed or divergent source ranges are rejected. The tool writes only to stdout/stderr; the shell redirection creates the report. Keep reports outside tracked worktrees.
Exit 1 means an inventory blocker: an explicit image pin; a production service configuration addition/removal; an unavailable chart version; a declared service-enabled change; or a declared source revision that is invalid, unavailable locally, or not reachable from the selected target source. Exit 2 means incomplete evidence or invalid input. There is deliberately no ready/approved exit code. A nonzero exit does not necessarily mean report generation failed; inspect the report and stderr separately.
What is covered¶
- Production service chart versions in
syrf/environments/production/<service>/config.yaml. - Declared service image tags, enabled state and source SHA; resolve each declared source SHA locally and check it is an ancestor of the selected target source (without certifying the running artifact). Unchanged services built at earlier commits are valid; an absent declaration remains unverified.
- Explicit top-level
image.tagpins in target per-servicevalues.yaml, flagged for review without guessing whether intentional. - Literal Boolean
featureFlagsdeclarations at environment and per-service levels, reported separately without resolving inheritance. - Canonical schema defaults read from
default, including quoted Boolean strings. Section-qualified identifiers preserve different defaults for the same environment variable in backend and frontend sections. - Filename-based migration candidates between the selected source snapshots.
- Complete locally available source commit range and PR references from commit subjects, without date-based cutoffs or a 100-PR API truncation.
Arbitrary YAML values and raw diffs are not printed. This is not a general secret scanner; source filenames and flag identifiers still belong in an appropriately access-controlled report.
Boundaries and decisions¶
Declared values are not effective runtime state. Helm inheritance/rendering, raw environment overrides, Mongo overrides, source-to-artifact provenance for every service, deployed digests/health, migration execution/environment binding, compatibility evidence and acceptance are explicitly unverified. Do not infer data loss, safety or production approval from this inventory.
A list of migration-like files is not a migration plan. Follow ADR-023, including its latest forward-only amendment. An old binary is not a guaranteed rollback target; data-losing compensation needs explicit planning and approval.
Use the existing production promotion process and runtime release plan. The current pipeline maintains one rolling draft PR; the report never marks it ready or merges it. Producing this report grants no production authorization.
Verification¶
Twenty-one tests use temporary Git repositories and synthetic YAML only, covering version/flag/migration changes, source history, pin and service-enable blockers, secret-value omission, unavailable input, ref validation, incomplete exit semantics and unchanged checkout state, repeated schema declarations, shared environment flags, declared image/enablement/source provenance, reversed/divergent ranges and explicit empty sections, services built at different ancestor commits, divergent recorded revisions, malformed optional metadata and actionable range diagnostics.