Committer identity (author + committer name/email) for the rare path
where a git invocation lands on a host with no user.email /
user.name configured — notably actions/checkout@v6, which does
NOT set committer identity for the workflow runner. Resolved once per
caller and threaded through to revert_commit_in so the CLI never
mutates the repo’s git config (env-only, scoped to the single spawn).
One GitHub repo push-probe: the coordinates, the credential, the retry
budget (attempt ladder plus the invocation’s wall-clock deadline) the
probe must stay inside, and the strictness the outcome is graded under.
The two outcomes whose severity + wording genuinely differ between the
preflight callers of github_repo_push_check: an unwritable repo blocks
the required github-release target but only warns for a tap/index repo,
and the missing/denied wording names what the caller was probing.
Prefix of the changelog-provenance marker lines the tag and
bump --commit commands record in the version-bump commit body when their
--changelog refresh regenerates on-disk CHANGELOG.md files.
The ordered env-var ladder consulted (after any explicit CLI/context
value) when resolving a GitHub token: ANODIZER_GITHUB_TOKEN is preferred,
then GITHUB_TOKEN, then GH_TOKEN (the gh CLI’s conventional var, so
runners configured only for gh still authenticate). This is the single
source of truth for the ladder —
resolve_github_token_with_env (the only real reader) consumes it, and
the config-aware preflight builds its EnvAnyOf lists from it so the
validated set cannot drift from the set the resolver actually reads.
Subject prefix anodizer stamps on its own release-machinery commits
(version-sync bumps, rollback reverts). The matchers that must recognise
those commits — rollback’s idempotency check, the changelog stage’s
version-sync exclusion — compose their patterns from this same constant
so a reworded writer can never silently break a matcher.
Default short-commit length used across error messages, log
output, and any place that needs to truncate a full SHA for
human display. Matches git’s --short default (7) — and the
ShortCommit template var populated by crate::git::detect_git_info
(which delegates to git rev-parse --short).
Return remote branch short names that contain sha (e.g. master,
release/v1). The bump commit’s SHA is the deterministic anchor of
the tag, so deriving the push branch from it is race-immune to the
default branch moving between bump and rollback. Empty Vec when
the SHA is not on any remote branch (orphan / not-yet-pushed).
Marker line recording that the tool regenerated the changelog file owned
by crate_name at version: changelog regenerated for <crate>@<version>.
Always crate-scoped, so one crate’s regeneration can never vouch for a
same-numbered version of a different crate, and a root-only aggregate that
touched no packaged crate’s own CHANGELOG.md mints no marker at all.
Whether the LAST commit that touched changelog_rel_path (repo-relative,
/-separated) in workspace_root records that the tool regenerated the
changelog for crate_name at version.
git log -1 --format=%s <sha> — return the subject line of a single
commit. Used to render the “non-bump commit subject” list when the
rollback safety check fires.
git log --format=%H%x1f%s <sha>..HEAD — return every (full_sha, subject)
pair in the range in one subprocess. Used by the rollback safety check so
classifying N intervening commits is a single git spawn rather than
1 + N (one rev-list plus one log -1 per commit).
Filter an arbitrary tag list through the user’s ignore_tags (glob) /
ignore_tag_prefixes (starts-with) config plus the unconditional
is_nightly_tag exclusion — the same semantics
find_latest_tag_matching_in
applies to its candidate set, packaged for callers that obtain tags
elsewhere (e.g. tags-at-HEAD crate selection).
Ignore patterns are template-rendered when vars is provided.
--name-only sibling of get_commits_between_paths_in: each commit is
paired with the repo-relative paths it touched, for a precise
changelog.paths glob intersect over the git-pathspec scope.
All commits reachable from an arbitrary rev (not just HEAD), filtered to
paths. Used by the changelog stage to bound a no-lower-bound range at an
explicit upper ref (changelog ..<tag>): the range is then every ancestor
of <tag>, excluding commits made after it.
Env-injectable sibling of gh_api_get_with_binary, mirroring the
resolve_github_token/resolve_github_token_with_env split: env
stands in for std::env::vars() when redacting the bailed error message,
so a test asserting on the raw gh stderr text does not depend on the
real ambient process environment (which may contain secret-suffixed
values that happen to collide with the asserted substring).
Run the GET /repos/{owner}/{repo} request under the shallow probe policy,
reading response headers (not just the status) so a secondary-rate-limit 403
is separable from an auth 403. 5xx and retriable transport errors retry
within policy and stop once deadline — the invocation’s wall-clock
budget — is spent; everything else resolves on the first response.
The env-var fragment of a “no GitHub token” remediation hint, rendered
from GITHUB_TOKEN_ENV_LADDER in actual resolution-precedence order:
ANODIZER_GITHUB_TOKEN or GITHUB_TOKEN or GH_TOKEN. Error messages
interpolate this
(or github_token_hint) instead of restating the vars, so a
hand-spelled hint can never list the ladder in the wrong order or go
stale when a var is added or renamed.
Full remediation hint for surfaces that also accept a --token flag:
set ANODIZER_GITHUB_TOKEN or GITHUB_TOKEN or GH_TOKEN, or pass --token, rendered
from GITHUB_TOKEN_ENV_LADDER.
git -C <repo> log -1 --format=%ct HEAD — return HEAD’s committer
timestamp (seconds since UNIX epoch) for the given repository. Used by
the determinism harness as the non-snapshot SDE seed.
Wrap an indeterminate probe outcome (the probe could not reach a verdict)
in its effective severity: Warning by default so a transient upstream
blip cannot abort an otherwise-valid release, Blocker under strict
preflight (fail-closed).
Return true when name looks like a branch (NOT an anodize-shaped
release tag). Tag shapes: ^v\d+\.\d+\.\d+ (lockstep
v1.2.3[-pre][+build]) or ^<crate>-v\d+\.\d+\.\d+
(per-crate mycrate-v1.2.3[...]).
Whether tag carries anodizer’s own nightly marker: the literal tag
nightly (the default nightly.tag_name), or a nightly token delimited
by - / . / + inside the version portion — the shape every supported
nightly.version_template produces (default
…-{{ ShortCommit }}-nightly, nushell-style …-nightly.{{ NightlyBuild }}+…).
Whether an error body marks the response as rate-limited at all
(primary quota exhaustion or a secondary limit): any 429, or a 403 whose
message / documentation_url carries a rate-limit signal.
git -C <workspace_root> tag --list --sort=-v:refname '<prefix>*' —
return the list of refs whose name starts with prefix, ordered by
reverse semver. Returns Ok(Vec::new()) when git fails (no repo,
no tags) so callers can treat absence as a non-error.
git -C <workspace_root> -c log.showSignature=false log --pretty=format:%B%x1e <range> -- <rel_path> — list commit message
bodies (subject+body) for commits in range touching rel_path,
using the \x1e (RS) byte as a between-commits separator so multi-line
bodies survive parsing.
git diff --name-only <tag>..HEAD -- <paths>... — return true when
any of the named paths changed between tag and HEAD. Returns
Ok(false) when git fails (e.g. not a git repo) so callers can treat
the absence-of-info case as “no changes”.
The tag-family prefix used for a crate: the prefix extracted from its
tag_template, falling back to the <name>-v convention when the
template is empty or carries no recognised version placeholder.
Process-env wrapper of resolve_github_token_with_env for call sites
without a Context (e.g. the bump/tag changelog-sync write path,
whose commands expose no --token flag).
Resolve the GitHub token for API calls through the codebase-standard
chain: explicit value (CLI flag / context option) → the
GITHUB_TOKEN_ENV_LADDER (ANODIZER_GITHUB_TOKEN → GITHUB_TOKEN →
GH_TOKEN).
Empty strings count as absent at every link — GitHub Actions materializes
missing secrets as "", which must not short-circuit the fallback to the
next link.
Resolve the committer identity to use for a rollback-style commit.
When the host already has user.name AND user.email configured
(or GIT_AUTHOR_* / GIT_COMMITTER_* are set in the parent env),
returns an empty identity so the child inherits the existing
values. Otherwise returns a synthetic identity so the commit
doesn’t fail with “Author identity unknown” on bare-CI hosts.
Whether a GitHub response’s headers mark it as rate-limited: a Retry-After
header (primary or secondary limit) or X-RateLimit-Remaining: 0. Header
lookups are case-insensitive (reqwest::header::HeaderMap).
git rev-parse --verify <rev>^{commit} — resolve rev to a commit SHA,
erroring when it does not name an existing commit. Stricter than
rev_parse_in: --verify rejects ambiguous / non-existent refs (rather
than echoing the input back), and the ^{commit} peel rejects a ref that
resolves to a non-commit object (e.g. a tree or blob SHA).
Truncate a full commit SHA string to SHORT_COMMIT_LEN
characters. Returns the input unchanged when it’s already shorter
or equal in length. Use this any time the SHA arrives as a string
(e.g. deserialized from a manifest or read from a template var)
rather than running git rev-parse --short again — saves a
subprocess and keeps the length convention in one place.
Split a release tag into its family prefix and the parsed version it
stamps: crd-v0.5.0 → ("crd-v", 0.5.0), v1.2.3 → ("v", 1.2.3),
sub/v1.2.3-rc.1 → ("sub/v", 1.2.3-rc.1). Two tags with equal
prefixes belong to the same tag family (the same tag_template
track). None when no semver version can be located in the tag.
The glob describing the tag family tag_template mints — literally the
filter find_previous_tag_in_family
applies, so a diagnostic quoting it cannot drift from the search that was
actually performed. None when
nothing scopes the search.