@kungfu-tech/buildchain 2.0.16-alpha.0 → 2.0.17-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +71 -0
- package/CONTRIBUTING.md +120 -0
- package/LICENSE +202 -0
- package/LICENSE-POLICY.md +52 -0
- package/README.md +10 -2
- package/SECURITY.md +43 -0
- package/actions/promote-buildchain-ref/README.md +202 -0
- package/actions/run-lifecycle/README.md +41 -0
- package/actions/validate-config/README.md +34 -0
- package/docs/MAP.md +64 -0
- package/docs/lifecycle-protocol.md +21 -1
- package/docs/migration-inventory.md +88 -0
- package/docs/ownership.md +52 -0
- package/docs/publish-transaction.md +40 -1
- package/docs/release-flow.md +259 -0
- package/docs/release-governance.md +313 -0
- package/fixtures/libnode-shaped/README.md +23 -0
- package/fixtures/publish-transaction-shaped/README.md +26 -0
- package/fixtures/web-surface-shaped/README.md +9 -0
- package/package.json +13 -2
- package/packages/core/buildchain-config.js +47 -0
- package/packages/core/index.js +1 -0
- package/packages/core/publish-transaction.js +5 -0
- package/scripts/check-inventory.mjs +9 -1
- package/scripts/npm-publish-transaction.mjs +1 -1
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# Release Flow Diagrams
|
|
2
|
+
|
|
3
|
+
This document describes the Buildchain v2 branch, tag, and version-state flow.
|
|
4
|
+
See [Release governance](release-governance.md) for the design rationale.
|
|
5
|
+
|
|
6
|
+
## Architecture
|
|
7
|
+
|
|
8
|
+
```mermaid
|
|
9
|
+
flowchart TD
|
|
10
|
+
Maintainer["Maintainer opens channel PR"]
|
|
11
|
+
Verify["Release - Verify"]
|
|
12
|
+
Review["Protected branch review"]
|
|
13
|
+
Merge["Merge PR into alpha or release"]
|
|
14
|
+
Promotion["Buildchain Ref Promotion"]
|
|
15
|
+
Action["promote-buildchain-ref action"]
|
|
16
|
+
VersionState["Version-state commit"]
|
|
17
|
+
ExactTag["Exact tag"]
|
|
18
|
+
FloatingRefs["Floating tags and channel branches"]
|
|
19
|
+
Consumers["Consumers pin stable or exact refs"]
|
|
20
|
+
|
|
21
|
+
Maintainer --> Verify
|
|
22
|
+
Verify --> Review
|
|
23
|
+
Review --> Merge
|
|
24
|
+
Merge --> Promotion
|
|
25
|
+
Promotion --> Action
|
|
26
|
+
Action --> VersionState
|
|
27
|
+
Action --> ExactTag
|
|
28
|
+
Action --> FloatingRefs
|
|
29
|
+
ExactTag --> Consumers
|
|
30
|
+
FloatingRefs --> Consumers
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Buildchain treats the PR merge as release intent and the promotion action as the
|
|
34
|
+
only component allowed to turn that intent into release refs.
|
|
35
|
+
|
|
36
|
+
## Ref State
|
|
37
|
+
|
|
38
|
+
| Ref kind | Example | Mutability | Purpose |
|
|
39
|
+
| --- | --- | --- | --- |
|
|
40
|
+
| Development branch | `dev/v2/v2.0` | moves | next source state for a minor line |
|
|
41
|
+
| Alpha branch | `alpha/v2/v2.0` | moves | latest test state for a minor line |
|
|
42
|
+
| Release branch | `release/v2/v2.0` | moves | latest production state for a minor line |
|
|
43
|
+
| Major gate branch | `publish-gate/major` | moves | reviewed administrator gate for publishing the next major |
|
|
44
|
+
| Exact alpha tag | `v2.0.3-alpha.0` | immutable | audit ref for one tested prerelease |
|
|
45
|
+
| Exact release tag | `v2.0.2` | immutable | audit ref for one production release |
|
|
46
|
+
| Floating alpha tag | `v2.0-alpha` | moves | latest test channel for a minor line |
|
|
47
|
+
| Floating minor tag | `v2.0` | moves | latest production patch on a minor line |
|
|
48
|
+
| Floating major tag | `v2` | moves | selected stable major entrypoint |
|
|
49
|
+
|
|
50
|
+
## Ref Protection Contract
|
|
51
|
+
|
|
52
|
+
Repository rulesets must distinguish immutable evidence refs from mutable
|
|
53
|
+
channel refs.
|
|
54
|
+
|
|
55
|
+
Protect exact release and alpha tags as immutable evidence:
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
refs/tags/v*.*.*
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Do not apply immutable-tag rulesets to every `refs/tags/v*` ref. Buildchain
|
|
62
|
+
must be able to update floating channel tags such as `v2`, `v2.0`, and
|
|
63
|
+
`v2.0-alpha` after the exact tag and publish evidence are valid. A ruleset that
|
|
64
|
+
matches all `v*` tags also matches floating tags, so release finalization can
|
|
65
|
+
fail with GitHub protected-ref errors even though the exact release tag and
|
|
66
|
+
published artifacts are already durable.
|
|
67
|
+
|
|
68
|
+
The intended governance split is:
|
|
69
|
+
|
|
70
|
+
- exact tags such as `v2.0.14` and `v2.0.15-alpha.0` are immutable audit refs;
|
|
71
|
+
- floating tags such as `v2`, `v2.0`, and `v2.0-alpha` are mutable channel refs
|
|
72
|
+
owned by the Buildchain promotion token;
|
|
73
|
+
- protected branches still require reviewed channel PRs before Buildchain can
|
|
74
|
+
move any exact or floating release refs.
|
|
75
|
+
|
|
76
|
+
## Alpha Promotion
|
|
77
|
+
|
|
78
|
+
```mermaid
|
|
79
|
+
sequenceDiagram
|
|
80
|
+
participant Dev as dev/vX/vX.Y
|
|
81
|
+
participant PR as PR dev -> alpha
|
|
82
|
+
participant Verify as Release - Verify
|
|
83
|
+
participant Alpha as alpha/vX/vX.Y
|
|
84
|
+
participant Promote as Buildchain Ref Promotion
|
|
85
|
+
participant Tags as Tags
|
|
86
|
+
|
|
87
|
+
Dev->>PR: open channel PR
|
|
88
|
+
PR->>Verify: run verification checks
|
|
89
|
+
Verify-->>PR: check succeeds
|
|
90
|
+
PR->>Alpha: reviewed merge
|
|
91
|
+
Alpha->>Promote: Verify workflow_run completed
|
|
92
|
+
Promote->>Promote: validate same-repo merged PR
|
|
93
|
+
Promote->>Promote: compute next vX.Y.Z-alpha.N
|
|
94
|
+
Promote->>Promote: write and verify version state
|
|
95
|
+
Promote->>Tags: create or reuse vX.Y.Z-alpha.N
|
|
96
|
+
Promote->>Tags: move vX.Y-alpha
|
|
97
|
+
Promote->>Alpha: move alpha/vX/vX.Y
|
|
98
|
+
Promote->>Dev: move dev/vX/vX.Y
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Result:
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
vX.Y.Z-alpha.N
|
|
105
|
+
vX.Y-alpha
|
|
106
|
+
alpha/vX/vX.Y
|
|
107
|
+
dev/vX/vX.Y
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
all point at the generated alpha version-state commit.
|
|
111
|
+
|
|
112
|
+
## Release Promotion
|
|
113
|
+
|
|
114
|
+
```mermaid
|
|
115
|
+
sequenceDiagram
|
|
116
|
+
participant Alpha as alpha/vX/vX.Y
|
|
117
|
+
participant PR as PR alpha -> release
|
|
118
|
+
participant Verify as Release - Verify
|
|
119
|
+
participant Release as release/vX/vX.Y
|
|
120
|
+
participant Promote as Buildchain Ref Promotion
|
|
121
|
+
participant Tags as Tags
|
|
122
|
+
participant Dev as dev/vX/vX.Y
|
|
123
|
+
|
|
124
|
+
Alpha->>PR: open channel PR
|
|
125
|
+
PR->>Verify: run verification checks
|
|
126
|
+
Verify-->>PR: check succeeds
|
|
127
|
+
PR->>Release: reviewed merge
|
|
128
|
+
Release->>Promote: Verify workflow_run completed
|
|
129
|
+
Promote->>Promote: validate same-repo merged PR
|
|
130
|
+
Promote->>Promote: find same-patch alpha tag
|
|
131
|
+
Promote->>Promote: compare release tree with tested alpha tree
|
|
132
|
+
Promote->>Promote: write and verify final version state
|
|
133
|
+
Promote->>Tags: create or reuse vX.Y.Z
|
|
134
|
+
Promote->>Tags: move vX.Y
|
|
135
|
+
Promote->>Tags: move vX when eligible
|
|
136
|
+
Promote->>Release: move release/vX/vX.Y
|
|
137
|
+
Promote->>Promote: prepare vX.Y.(Z+1)-alpha.0
|
|
138
|
+
Promote->>Tags: create or reuse vX.Y.(Z+1)-alpha.0
|
|
139
|
+
Promote->>Tags: move vX.Y-alpha
|
|
140
|
+
Promote->>Alpha: move alpha/vX/vX.Y
|
|
141
|
+
Promote->>Dev: move dev/vX/vX.Y
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Result:
|
|
145
|
+
|
|
146
|
+
```text
|
|
147
|
+
vX.Y.Z
|
|
148
|
+
vX.Y
|
|
149
|
+
vX
|
|
150
|
+
release/vX/vX.Y
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
point at the production version-state commit, while:
|
|
154
|
+
|
|
155
|
+
```text
|
|
156
|
+
vX.Y.(Z+1)-alpha.0
|
|
157
|
+
vX.Y-alpha
|
|
158
|
+
alpha/vX/vX.Y
|
|
159
|
+
dev/vX/vX.Y
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
point at the next alpha version-state commit.
|
|
163
|
+
|
|
164
|
+
## State Machine
|
|
165
|
+
|
|
166
|
+
```mermaid
|
|
167
|
+
stateDiagram-v2
|
|
168
|
+
[*] --> Development: work lands on dev/vX/vX.Y
|
|
169
|
+
Development --> AlphaCandidate: PR dev -> alpha
|
|
170
|
+
AlphaCandidate --> AlphaPublished: Verify + review + merge + promotion
|
|
171
|
+
AlphaPublished --> ReleaseCandidate: PR alpha -> release
|
|
172
|
+
ReleaseCandidate --> ProductionPublished: Verify + review + merge + promotion
|
|
173
|
+
ProductionPublished --> NextAlphaPrepared: prepare vX.Y.(Z+1)-alpha.0
|
|
174
|
+
NextAlphaPrepared --> Development: dev and alpha refs move to next alpha
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
The same minor line can loop through this state machine many times.
|
|
178
|
+
|
|
179
|
+
## Version Examples
|
|
180
|
+
|
|
181
|
+
Assume `v2.0.2-alpha.1` has been tested and a maintainer merges
|
|
182
|
+
`alpha/v2/v2.0 -> release/v2/v2.0`.
|
|
183
|
+
|
|
184
|
+
Buildchain should produce:
|
|
185
|
+
|
|
186
|
+
```text
|
|
187
|
+
v2.0.2 exact production tag
|
|
188
|
+
v2.0 floating minor tag
|
|
189
|
+
v2 floating major tag when v2.0 is the selected major line
|
|
190
|
+
release/v2/v2.0 production channel branch
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
It should also prepare:
|
|
194
|
+
|
|
195
|
+
```text
|
|
196
|
+
v2.0.3-alpha.0 exact next alpha tag
|
|
197
|
+
v2.0-alpha floating alpha tag
|
|
198
|
+
alpha/v2/v2.0 alpha channel branch
|
|
199
|
+
dev/v2/v2.0 development channel branch
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
This is expected behavior. A production release closes one patch and opens the
|
|
203
|
+
next test patch on the same minor line.
|
|
204
|
+
|
|
205
|
+
## Major Gate Promotion
|
|
206
|
+
|
|
207
|
+
```mermaid
|
|
208
|
+
sequenceDiagram
|
|
209
|
+
participant Release as release/vX/vX.Y
|
|
210
|
+
participant PR as PR release -> publish-gate/major
|
|
211
|
+
participant Verify as Release - Verify
|
|
212
|
+
participant Gate as publish-gate/major
|
|
213
|
+
participant Promote as Buildchain Ref Promotion
|
|
214
|
+
participant Tags as Tags
|
|
215
|
+
participant Next as dev/alpha/release v(X+1).0
|
|
216
|
+
|
|
217
|
+
Release->>PR: open administrator PR
|
|
218
|
+
PR->>Verify: run verification checks
|
|
219
|
+
Verify-->>PR: check succeeds
|
|
220
|
+
PR->>Gate: reviewed merge
|
|
221
|
+
Gate->>Promote: Verify workflow_run completed
|
|
222
|
+
Promote->>Promote: validate same-repo release -> publish-gate/major PR
|
|
223
|
+
Promote->>Promote: write v(X+1).0.0 version state
|
|
224
|
+
Promote->>Tags: create v(X+1).0.0
|
|
225
|
+
Promote->>Tags: move v(X+1).0 and v(X+1)
|
|
226
|
+
Promote->>Gate: move publish-gate/major to v(X+1).0.0
|
|
227
|
+
Promote->>Next: move release/v(X+1)/v(X+1).0 to v(X+1).0.0
|
|
228
|
+
Promote->>Promote: prepare v(X+1).0.1-alpha.0
|
|
229
|
+
Promote->>Next: move alpha/dev v(X+1).0 to next alpha
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
`publish-gate/major` is intentionally not an active source branch. It is the PR
|
|
233
|
+
target for the administrator's "publish the next major" decision. The older
|
|
234
|
+
`major-gate` name is a compatibility alias only.
|
|
235
|
+
|
|
236
|
+
## Failure Boundaries
|
|
237
|
+
|
|
238
|
+
Promotion should stop before moving refs when:
|
|
239
|
+
|
|
240
|
+
- the run is a non-dry-run manual dispatch;
|
|
241
|
+
- the expected same-repository PR cannot be found;
|
|
242
|
+
- the PR was not merged;
|
|
243
|
+
- the branch pair is not a valid channel path;
|
|
244
|
+
- the required status check did not pass;
|
|
245
|
+
- a release tree does not match the same-patch alpha tag tree;
|
|
246
|
+
- version-state verification fails;
|
|
247
|
+
- a required exact tag already exists at a commit unrelated to the active
|
|
248
|
+
transaction or finalized channel head.
|
|
249
|
+
|
|
250
|
+
These failures are intentional. They protect consumers from refs that look
|
|
251
|
+
released but do not have a complete evidence chain.
|
|
252
|
+
|
|
253
|
+
During transaction finalization recovery, the current channel head may be a
|
|
254
|
+
generated version-state merge commit. Buildchain validates that the durable
|
|
255
|
+
transaction version, exact tag, evidence, and release material match, and that
|
|
256
|
+
the current target ref contains or corresponds to the recorded
|
|
257
|
+
`release_material_sha`. It must then tolerate exact tags, dev refs, or alpha
|
|
258
|
+
refs that have already moved and continue filling any missing floating tags
|
|
259
|
+
before writing the transaction state as `complete`.
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
# Release Governance
|
|
2
|
+
|
|
3
|
+
Buildchain v2 preserves the release semantics of the older ABV workflow while
|
|
4
|
+
moving the implementation into one modern repository.
|
|
5
|
+
|
|
6
|
+
The central idea is simple: a reviewed merge into a release channel is the
|
|
7
|
+
release intent. Automation must then create the version-state commit, exact tag,
|
|
8
|
+
floating tag, and next alpha state that make that intent true in Git.
|
|
9
|
+
|
|
10
|
+
## Design Problem
|
|
11
|
+
|
|
12
|
+
Kungfu release automation has to keep four facts aligned:
|
|
13
|
+
|
|
14
|
+
1. The source tree that was reviewed.
|
|
15
|
+
2. The package version recorded in manifests such as `package.json` or
|
|
16
|
+
`lerna.json`.
|
|
17
|
+
3. The exact immutable release or prerelease tag.
|
|
18
|
+
4. The floating channel refs that consumers actually use.
|
|
19
|
+
|
|
20
|
+
If any one of these facts is updated by hand, the system can split:
|
|
21
|
+
|
|
22
|
+
- a consumer can fetch `v2.0` and receive a tree whose package version still
|
|
23
|
+
says the previous release;
|
|
24
|
+
- a maintainer can move `v2` without producing an exact `v2.0.N` audit tag;
|
|
25
|
+
- an alpha can be promoted to production even though the release tree is not the
|
|
26
|
+
same tree that was tested;
|
|
27
|
+
- a protected branch merge can succeed while the follow-up version commit is
|
|
28
|
+
missing.
|
|
29
|
+
|
|
30
|
+
The older ABV workflow addressed this by letting GitHub PRs drive release
|
|
31
|
+
state. Buildchain keeps that choice because it makes release intent reviewable,
|
|
32
|
+
observable, and recoverable from Git history.
|
|
33
|
+
|
|
34
|
+
## What ABV Contributed
|
|
35
|
+
|
|
36
|
+
The old ABV model was not just "bump a version number." It encoded a governance
|
|
37
|
+
loop:
|
|
38
|
+
|
|
39
|
+
- release branches are named as channels: `dev`, `alpha`, `release`, and the
|
|
40
|
+
administrative `publish-gate/major`;
|
|
41
|
+
- a PR from one channel to the next is the release request;
|
|
42
|
+
- verify jobs check that the branch pair is valid before merge;
|
|
43
|
+
- a maintainer review is required before the branch moves;
|
|
44
|
+
- after merge, automation writes the version change and moves tags;
|
|
45
|
+
- exact tags and floating refs are aligned with the resulting commit;
|
|
46
|
+
- the next development channel is prepared automatically.
|
|
47
|
+
|
|
48
|
+
ABV also kept the version-state mutation in the repository. For JavaScript
|
|
49
|
+
repositories that usually meant changing `lerna.json` and/or `package.json`.
|
|
50
|
+
That commit is important because the tag alone is not enough evidence: the
|
|
51
|
+
source tree should also declare the version that the tag advertises.
|
|
52
|
+
|
|
53
|
+
Buildchain v2 treats that as a hard semantic requirement for its own release
|
|
54
|
+
line.
|
|
55
|
+
|
|
56
|
+
## Buildchain Implementation
|
|
57
|
+
|
|
58
|
+
Buildchain implements the same governance loop with:
|
|
59
|
+
|
|
60
|
+
- `.github/workflows/release-verify.yml` for PR verification;
|
|
61
|
+
- `.github/workflows/buildchain-ref-promotion.yml` for post-verify ref
|
|
62
|
+
promotion;
|
|
63
|
+
- `actions/promote-buildchain-ref` for branch, tag, version-state, and
|
|
64
|
+
governance checks;
|
|
65
|
+
- package-manager adapters that can update version state for pnpm, npm, and
|
|
66
|
+
yarn style repositories;
|
|
67
|
+
- `buildchain.toml` lifecycle configuration for repositories whose version
|
|
68
|
+
state or verification commands are not Node package-manager defaults.
|
|
69
|
+
|
|
70
|
+
The implementation is intentionally stricter than a local release script:
|
|
71
|
+
|
|
72
|
+
- manual workflow dispatch can only do dry-run promotion;
|
|
73
|
+
- non-dry-run promotion must be driven by a completed `Verify` workflow;
|
|
74
|
+
- target branch protection details must be readable, and branch protection must
|
|
75
|
+
apply to administrators as well as regular contributors;
|
|
76
|
+
- alpha promotion must come from a merged same-repository PR from
|
|
77
|
+
`dev/vX/vX.Y` to `alpha/vX/vX.Y`;
|
|
78
|
+
- release promotion must come from a merged same-repository PR from
|
|
79
|
+
`alpha/vX/vX.Y` to `release/vX/vX.Y`;
|
|
80
|
+
- major promotion must come from a merged same-repository PR from
|
|
81
|
+
`release/vX/vX.Y` to `publish-gate/major`;
|
|
82
|
+
- release promotion requires an existing same-patch alpha tag and checks the
|
|
83
|
+
release source tree against that tested alpha tree;
|
|
84
|
+
- generated version-state commits are verified before refs move.
|
|
85
|
+
|
|
86
|
+
## Version Lines
|
|
87
|
+
|
|
88
|
+
Kungfu uses Python-like version lines where a minor line can represent a
|
|
89
|
+
long-lived product train. A line such as `v2.0` can produce many production
|
|
90
|
+
patch releases:
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
v2.0.0
|
|
94
|
+
v2.0.1
|
|
95
|
+
v2.0.2
|
|
96
|
+
...
|
|
97
|
+
v2.0.1234
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
This is why Buildchain maintains both exact and floating refs:
|
|
101
|
+
|
|
102
|
+
- `v2.0.2` is immutable release evidence;
|
|
103
|
+
- `v2.0` is the latest production release on the `2.0` line;
|
|
104
|
+
- `v2` is the selected stable major-line entrypoint;
|
|
105
|
+
- `v2.0.3-alpha.0` is immutable alpha evidence;
|
|
106
|
+
- `v2.0-alpha` is the latest test channel for the `2.0` line.
|
|
107
|
+
|
|
108
|
+
A release does not mean "minor is complete." It means "this patch on this minor
|
|
109
|
+
line is now production."
|
|
110
|
+
|
|
111
|
+
GitHub repository rules must preserve that distinction. Exact tags such as
|
|
112
|
+
`v2.0.2` and `v2.0.3-alpha.0` should be immutable. Floating channel tags such as
|
|
113
|
+
`v2`, `v2.0`, and `v2.0-alpha` must remain movable by the Buildchain promotion
|
|
114
|
+
token after governance checks and publish evidence pass. A tag ruleset that
|
|
115
|
+
protects every `refs/tags/v*` ref is too broad because it also locks the
|
|
116
|
+
floating channel tags that Buildchain is required to update. Prefer exact-tag
|
|
117
|
+
patterns such as `refs/tags/v*.*.*` for immutable release evidence, while
|
|
118
|
+
leaving floating channel tags under Buildchain automation control.
|
|
119
|
+
|
|
120
|
+
## Alpha Semantics
|
|
121
|
+
|
|
122
|
+
An alpha merge is:
|
|
123
|
+
|
|
124
|
+
```text
|
|
125
|
+
dev/vX/vX.Y -> alpha/vX/vX.Y
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Buildchain then:
|
|
129
|
+
|
|
130
|
+
1. Computes the next prerelease for the minor line.
|
|
131
|
+
2. Writes version state such as `vX.Y.Z-alpha.N`.
|
|
132
|
+
3. Verifies the generated version-state tree.
|
|
133
|
+
4. Creates or reuses the exact alpha tag.
|
|
134
|
+
5. Moves `alpha/vX/vX.Y` to the generated alpha commit.
|
|
135
|
+
6. Moves `dev/vX/vX.Y` to the same generated alpha commit when this is a
|
|
136
|
+
fast-forward update.
|
|
137
|
+
7. Moves `vX.Y-alpha` to the same generated alpha commit.
|
|
138
|
+
|
|
139
|
+
This keeps the test channel self-describing. If a consumer checks out
|
|
140
|
+
`v2.0-alpha`, the manifests and exact alpha tag agree.
|
|
141
|
+
|
|
142
|
+
If `dev/vX/vX.Y` has already advanced while the generated alpha version-state PR
|
|
143
|
+
was under review, Buildchain records `skipped-non-fast-forward` for the dev sync
|
|
144
|
+
and still completes the exact and floating alpha tags for the reviewed alpha
|
|
145
|
+
commit. Later dev changes must go through their own dev-to-alpha promotion
|
|
146
|
+
instead of rewinding dev.
|
|
147
|
+
|
|
148
|
+
If alpha finalization is resumed after the version-state PR is merged,
|
|
149
|
+
Buildchain accepts the current alpha head as a merge commit that contains the
|
|
150
|
+
recorded release material. An already-created exact alpha tag may point at the
|
|
151
|
+
transaction release/material SHA or at the finalized alpha head; missing
|
|
152
|
+
floating alpha tags are retried before the transaction becomes `complete`.
|
|
153
|
+
|
|
154
|
+
## Release Semantics
|
|
155
|
+
|
|
156
|
+
A release merge is:
|
|
157
|
+
|
|
158
|
+
```text
|
|
159
|
+
alpha/vX/vX.Y -> release/vX/vX.Y
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Buildchain then:
|
|
163
|
+
|
|
164
|
+
1. Finds the same-patch alpha tag that was tested.
|
|
165
|
+
2. Checks that the release source tree matches that alpha tag tree, excluding
|
|
166
|
+
only generated version-state differences.
|
|
167
|
+
3. Writes final release version state such as `vX.Y.Z`.
|
|
168
|
+
4. Verifies the generated release tree.
|
|
169
|
+
5. Creates or reuses the exact release tag `vX.Y.Z`.
|
|
170
|
+
6. Moves `release/vX/vX.Y` to the exact release commit.
|
|
171
|
+
7. Moves `vX.Y` to the exact release commit.
|
|
172
|
+
8. Moves `vX` when this minor line should be the stable major entrypoint.
|
|
173
|
+
9. Prepares the next alpha version-state commit, such as
|
|
174
|
+
`vX.Y.(Z+1)-alpha.0`.
|
|
175
|
+
10. Moves `alpha/vX/vX.Y`, `dev/vX/vX.Y`, and `vX.Y-alpha` to that next alpha
|
|
176
|
+
commit.
|
|
177
|
+
|
|
178
|
+
The production channel and the test channel therefore intentionally diverge
|
|
179
|
+
after release: production stays on the release commit, while alpha/dev continue
|
|
180
|
+
at the next prerelease commit.
|
|
181
|
+
|
|
182
|
+
If release finalization is resumed after the version-state PR is merged,
|
|
183
|
+
Buildchain applies the same recovery rule: the current release head may be a
|
|
184
|
+
merge commit that contains the recorded release material, existing exact tags
|
|
185
|
+
and alpha/dev refs are accepted when they match the transaction, and missing
|
|
186
|
+
floating `vX.Y` or `vX` tags are retried idempotently before completion.
|
|
187
|
+
|
|
188
|
+
## Major Gate Semantics
|
|
189
|
+
|
|
190
|
+
A major gate merge is:
|
|
191
|
+
|
|
192
|
+
```text
|
|
193
|
+
release/vX/vX.Y -> publish-gate/major
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
`publish-gate/major` is the explicit replacement for the older ABV `main`
|
|
197
|
+
channel. The name is intentionally operational: it is a gate for a rare
|
|
198
|
+
administrator decision, not the active trunk. Keeping this decision in the same
|
|
199
|
+
PR UI as alpha and release promotion keeps the human workflow simple while
|
|
200
|
+
avoiding the misleading meaning of `main`. The older `major-gate` branch name is
|
|
201
|
+
a compatibility alias only.
|
|
202
|
+
|
|
203
|
+
Buildchain then:
|
|
204
|
+
|
|
205
|
+
1. Verifies the source is a merged same-repository PR from a protected release
|
|
206
|
+
line into `publish-gate/major`.
|
|
207
|
+
2. Writes the next major production version state, such as `v(X+1).0.0`.
|
|
208
|
+
3. Creates or reuses the exact release tag `v(X+1).0.0`.
|
|
209
|
+
4. Moves `publish-gate/major` and `release/v(X+1)/v(X+1).0` to that release commit.
|
|
210
|
+
5. Moves `v(X+1).0` and `v(X+1)` to that release commit.
|
|
211
|
+
6. Prepares the next alpha version-state commit, such as
|
|
212
|
+
`v(X+1).0.1-alpha.0`.
|
|
213
|
+
7. Moves `alpha/v(X+1)/v(X+1).0`, `dev/v(X+1)/v(X+1).0`, and
|
|
214
|
+
`v(X+1).0-alpha` to that next alpha commit.
|
|
215
|
+
|
|
216
|
+
Checking out `publish-gate/major` should therefore look like a frozen release
|
|
217
|
+
state, not like a branch where day-to-day source work continues. Day-to-day
|
|
218
|
+
source work continues on `dev/vX/vX.Y`.
|
|
219
|
+
|
|
220
|
+
## Package-Manager Adapters
|
|
221
|
+
|
|
222
|
+
Old ABV assumed JavaScript repositories with root version state and often
|
|
223
|
+
Lerna. Buildchain keeps the version-state contract but does not assume every
|
|
224
|
+
repository is yarn/Lerna.
|
|
225
|
+
|
|
226
|
+
The promotion action discovers and updates:
|
|
227
|
+
|
|
228
|
+
- root `package.json`;
|
|
229
|
+
- `lerna.json`;
|
|
230
|
+
- package manifests from `package.json` workspaces;
|
|
231
|
+
- package manifests from `lerna.json` packages;
|
|
232
|
+
- package manifests from `pnpm-workspace.yaml`.
|
|
233
|
+
|
|
234
|
+
It then runs the repository's detected package manager semantics where needed:
|
|
235
|
+
|
|
236
|
+
- pnpm repositories use pnpm-oriented workspace discovery;
|
|
237
|
+
- npm repositories use npm/package-lock semantics where present;
|
|
238
|
+
- yarn repositories use yarn-style metadata where present.
|
|
239
|
+
|
|
240
|
+
For Buildchain itself, version state is required. For a consumer repository that
|
|
241
|
+
has no package manifest, the same action can degrade to ref-only behavior only
|
|
242
|
+
when that is explicitly allowed by the caller.
|
|
243
|
+
|
|
244
|
+
## Lifecycle Configuration
|
|
245
|
+
|
|
246
|
+
`buildchain.toml` is the v2 user configuration format. It lets a repository
|
|
247
|
+
declare version-state files and lifecycle commands without pretending every
|
|
248
|
+
project is a Node workspace. Supported version files include JSON, TOML, and
|
|
249
|
+
regex-based files such as `CMakeLists.txt` or `conanfile.py`.
|
|
250
|
+
|
|
251
|
+
The promotion action currently consumes `version.files` and `lifecycle.verify`.
|
|
252
|
+
The verify stage runs after generated version-state changes are applied locally
|
|
253
|
+
and before any release refs move. If `verification-command` is passed directly
|
|
254
|
+
to the action, that explicit command overrides `lifecycle.verify`.
|
|
255
|
+
|
|
256
|
+
Protected release-line branches keep their normal review gate. When generated
|
|
257
|
+
version state would move a protected alpha or release branch, Buildchain creates
|
|
258
|
+
a version-state PR instead of bypassing branch protection. After that PR is
|
|
259
|
+
reviewed, checked, and merged, the next promotion run verifies that only
|
|
260
|
+
declared version-state files changed from the legally merged source parent, then
|
|
261
|
+
moves the exact and floating tags.
|
|
262
|
+
|
|
263
|
+
## What This Guarantees
|
|
264
|
+
|
|
265
|
+
When the loop succeeds, maintainers and consumers can rely on these facts:
|
|
266
|
+
|
|
267
|
+
- every production release has an exact tag such as `v2.0.2`;
|
|
268
|
+
- every production minor line has a floating tag such as `v2.0`;
|
|
269
|
+
- every selected stable major has a floating tag such as `v2`;
|
|
270
|
+
- every next-major release is driven by a reviewed `release -> publish-gate/major` PR,
|
|
271
|
+
not a hidden manual button;
|
|
272
|
+
- every test channel has an exact alpha tag such as `v2.0.3-alpha.0`;
|
|
273
|
+
- every alpha minor line has a floating tag such as `v2.0-alpha`;
|
|
274
|
+
- version manifests match the tag visible from the same commit;
|
|
275
|
+
- production releases are derived from the alpha tree that was tested;
|
|
276
|
+
- manual non-dry-run promotion cannot bypass PR review and verification;
|
|
277
|
+
- admin users cannot make a channel promotion valid by temporarily bypassing
|
|
278
|
+
branch protection.
|
|
279
|
+
|
|
280
|
+
This is the practical meaning of "governance closed loop" in Buildchain: the
|
|
281
|
+
decision, code, version state, and Git refs close over the same evidence chain.
|
|
282
|
+
|
|
283
|
+
## What This Does Not Do
|
|
284
|
+
|
|
285
|
+
Buildchain release promotion does not embed registry clients or product-specific
|
|
286
|
+
publish logic. When publish transactions are enabled, `promote-buildchain-ref`
|
|
287
|
+
can run the consumer's `lifecycle.publish` command and own the transaction,
|
|
288
|
+
evidence validation, durable recovery state, and ref finalization order. The
|
|
289
|
+
consumer repository still owns registry truth: npm, PyPI, OCI, S3, Conan, CMake
|
|
290
|
+
packaging, download pages, dist-tags, and similar side effects must be
|
|
291
|
+
implemented by project lifecycle commands that emit Buildchain publish evidence.
|
|
292
|
+
|
|
293
|
+
Buildchain also does not maintain bare exact tags such as `1.0.0`. The supported
|
|
294
|
+
exact release and alpha refs are v-prefixed:
|
|
295
|
+
|
|
296
|
+
```text
|
|
297
|
+
v2.0.0
|
|
298
|
+
v2.0.1-alpha.0
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## Operational Reading Order
|
|
302
|
+
|
|
303
|
+
When debugging or extending release behavior, read in this order:
|
|
304
|
+
|
|
305
|
+
1. `docs/release-flow.md`
|
|
306
|
+
2. `.github/workflows/release-verify.yml`
|
|
307
|
+
3. `.github/workflows/buildchain-ref-promotion.yml`
|
|
308
|
+
4. `actions/promote-buildchain-ref/README.md`
|
|
309
|
+
5. `actions/promote-buildchain-ref/src/`
|
|
310
|
+
6. `docs/migration-inventory.md`
|
|
311
|
+
|
|
312
|
+
That path gives the policy first, the workflow trigger second, and the action
|
|
313
|
+
implementation last.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Libnode-shaped Fixture
|
|
2
|
+
|
|
3
|
+
This fixture models the Buildchain contract needed by `kungfu-systems/libnode`
|
|
4
|
+
without running the real native build.
|
|
5
|
+
|
|
6
|
+
It is intentionally small, but it keeps the important shape:
|
|
7
|
+
|
|
8
|
+
- `package.json` is the package version-state file;
|
|
9
|
+
- `libnode.release.json` is the explicit upstream anchor manifest;
|
|
10
|
+
- `buildchain.toml` declares `install`, `build`, and `verify` lifecycle stages;
|
|
11
|
+
- `version.strategy = "anchored"` and `version.next = "manual"` tell
|
|
12
|
+
Buildchain to validate the current anchor instead of deriving the next Node
|
|
13
|
+
anchor automatically;
|
|
14
|
+
- lifecycle commands are Node-based and cross-platform;
|
|
15
|
+
- build output lands under `dist/`, which the reusable build workflow uploads
|
|
16
|
+
with a deterministic artifact name and manifest;
|
|
17
|
+
- the fixture can be resolved through a publish-gate source lock, which binds
|
|
18
|
+
the requested consumer version to `package.json` and `libnode.release.json`
|
|
19
|
+
before any publish side effect is allowed;
|
|
20
|
+
- `[publish]` declares the normal token-free path:
|
|
21
|
+
`mode = "publish-final-version"` with `auth = "trusted-publishing"`, `latest`
|
|
22
|
+
as the release dist-tag, and platform packages published before the main
|
|
23
|
+
package.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# publish-transaction-shaped
|
|
2
|
+
|
|
3
|
+
Fixture for the Buildchain publish transaction contract.
|
|
4
|
+
|
|
5
|
+
It represents a release unit with three required artifact families:
|
|
6
|
+
|
|
7
|
+
- npm package metadata;
|
|
8
|
+
- OCI image digest;
|
|
9
|
+
- binary archive digest.
|
|
10
|
+
|
|
11
|
+
The fixture does not publish to external services. `lifecycle.publish` writes
|
|
12
|
+
generic Buildchain evidence to `BUILDCHAIN_PUBLISH_EVIDENCE`, which is enough for
|
|
13
|
+
tests and for consumers to understand the expected shape.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
BUILDCHAIN_VERSION=1.0.0 \
|
|
17
|
+
BUILDCHAIN_CHANNEL=release \
|
|
18
|
+
BUILDCHAIN_SOURCE_SHA=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
|
|
19
|
+
BUILDCHAIN_RELEASE_SHA=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb \
|
|
20
|
+
BUILDCHAIN_RELEASE_MATERIAL_SHA=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb \
|
|
21
|
+
BUILDCHAIN_PUBLISH_TOOLING_SHA=cccccccccccccccccccccccccccccccccccccccc \
|
|
22
|
+
BUILDCHAIN_TARGET_REF=release/v1/v1.0 \
|
|
23
|
+
BUILDCHAIN_EVIDENCE_DIR=.buildchain/release-evidence/v1.0.0 \
|
|
24
|
+
BUILDCHAIN_PUBLISH_EVIDENCE=.buildchain/release-evidence/v1.0.0/evidence.json \
|
|
25
|
+
node scripts/publish.mjs
|
|
26
|
+
```
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Web Surface Shaped Fixture
|
|
2
|
+
|
|
3
|
+
This fixture models a static site repository that wants Buildchain deployment
|
|
4
|
+
semantics without opting into package release lines.
|
|
5
|
+
|
|
6
|
+
It proves that `project.type = "web-surface"` can declare preview, staging, and
|
|
7
|
+
production channels, generate deterministic deployment manifests, and create
|
|
8
|
+
dry-run deploy and cleanup plans without touching AWS.
|
|
9
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kungfu-tech/buildchain",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.17-alpha.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Kungfu Buildchain reusable workflows, release governance, and CLI tooling.",
|
|
6
6
|
"repository": "https://github.com/kungfu-systems/buildchain",
|
|
@@ -16,15 +16,26 @@
|
|
|
16
16
|
"./package.json": "./package.json"
|
|
17
17
|
},
|
|
18
18
|
"files": [
|
|
19
|
+
"AGENTS.md",
|
|
19
20
|
"bin/",
|
|
21
|
+
"CONTRIBUTING.md",
|
|
22
|
+
"LICENSE-POLICY.md",
|
|
20
23
|
"scripts/*.mjs",
|
|
21
24
|
"packages/core/",
|
|
22
25
|
"README.md",
|
|
26
|
+
"SECURITY.md",
|
|
27
|
+
"docs/MAP.md",
|
|
23
28
|
"docs/cli.md",
|
|
24
29
|
"docs/lifecycle-protocol.md",
|
|
30
|
+
"docs/migration-inventory.md",
|
|
31
|
+
"docs/ownership.md",
|
|
25
32
|
"docs/publish-transaction.md",
|
|
33
|
+
"docs/release-flow.md",
|
|
34
|
+
"docs/release-governance.md",
|
|
26
35
|
"docs/reusable-build-surface.md",
|
|
27
|
-
"docs/web-surface-deployments.md"
|
|
36
|
+
"docs/web-surface-deployments.md",
|
|
37
|
+
"actions/*/README.md",
|
|
38
|
+
"fixtures/*/README.md"
|
|
28
39
|
],
|
|
29
40
|
"engines": {
|
|
30
41
|
"node": ">=22.14.0"
|