1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use ;
use Path;
use Command;
/// 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.
pub const RELEASE_COMMIT_PREFIX: &str = "chore(release): ";
/// `chore(release): bump ` — the subject prefix shared by every version-sync
/// bump commit (see [`release_bump_subject`]).
/// Build a version-sync bump commit subject:
/// `chore(release): bump <summary><suffix>`. `suffix` carries the optional
/// ` [skip ci]` marker (empty when none applies).
/// 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 publish stage's already-published content guard matches these markers
/// (via [`changelog_regenerated_recorded_in`]) to decide whether a crate-root
/// `CHANGELOG.md` difference against an already-published version is the
/// tool's own re-cut artifact (forgivable) or operator-authored drift (a hard
/// divergence). Writer and matcher compose from this one constant so a
/// reworded marker can never silently break the guard.
pub const CHANGELOG_PROVENANCE_PREFIX: &str = "changelog regenerated for ";
/// 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`.
///
/// Anchoring on the file's last toucher — not any marker anywhere in history —
/// scopes the provenance to the file's CURRENT content: an operator hand-edit
/// committed after the tool's regeneration makes the operator's commit the
/// last toucher, whose message carries no marker, so the guard reverts to
/// byte-strict instead of forgiving drift the tool did not author.
///
/// The marker match is an exact trimmed-line comparison, ruling out substring
/// false positives (a `0.12.0` marker never matches a `0.12.01` probe).
/// Returns `Ok(false)` when the file has never been committed or the last
/// toucher carries no matching marker; `Err` only when git itself fails
/// (callers making forgiveness decisions treat that as "no provenance").