Skip to content
Bitcoin Roots

v30.3-roots.1 · Commit 63: [PATCH 63/68] fix(release): restore signed five-platform CI releases

ci/release/README.md

Before: ci/release/README.md · After: ci/release/README.md

File metadata
index 6fac0115d61b93777f982345a85a7c269bb4842b..5764b45fc2a94fea35bf89e14b6ceb387840b20c 100644

Download original patch · Release notes

Diff rows 1–110 of 110. Line numbers refer to the original before/after files.

+ Added− RemovedUnmarked lines are context.

Scroll the code area horizontally to read long lines. The two line-number columns refer to before and after.

ci/release/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # Release notice assembly
2
2
 
3
- Platform build artifacts are intermediate packages. A green build proves the
4
- built product, but its package must also pass notice assembly before becoming a
5
- release asset. `release.yml` is a read-only `workflow_dispatch` build/rehearsal;
6
- permanent tag pushes do not start builds or create a draft. Maintainers explicitly
7
- assemble reviewed platform notices, validate the final packet and use the draft
8
- helper below. Unassembled packages are rejected before upload. Automatic discovery
9
- or acquisition of dependency notice inputs is not part of release execution.
3
+ `release.yml` runs the five-platform pipeline on a permanent Roots tag push;
4
+ manual dispatch rehearses an absent future tag with read-only permissions.
5
+ Both paths capture notices from each new build runner before packaging. Only
6
+ the tag path enters the `release` environment and requires a signed manifest
7
+ before creating a new draft. Public publication remains a separate approval.
8
+ Unassembled packages fail before upload or final preparation. No old local
9
+ notice bundle or prior binary is substituted for a fresh build.
10
10
 
11
11
  The supported assembly interface uses explicitly reviewed inputs:
12
12
 
@@ -68,49 +68,45 @@ it does not turn an old run into a build of the new commit. Signing, permanent
68
68
  tagging and publication remain separate reviewed actions. These checks verify
69
69
  notice contents and provenance, not general legal compliance.
70
70
 
71
- ## Immutable reviewed-assets draft
72
-
73
- Complete source review, canonical/main integration and asset review first.
74
- Authorize the exact annotated tag target and push only that tag; no tag-triggered
75
- build or draft job runs. The canonical tip must remain unchanged. Release assets
76
- must be outside the clean tagged source checkout and contain exactly the five
77
- platform archives, `bitcoin-roots-<version>.patch` and `SHA512SUMS`. Record the
78
- manifest's SHA512 digest and curated notes' SHA256 digest in the review; passing
79
- newly calculated digests is not a substitute for acceptance of those bytes.
80
-
81
- From the clean checkout at the approved commit, validate the complete handoff:
82
-
83
- ```sh
84
- python3 ci/release/create-draft.py \
85
- --tag v30.3-roots.1 --commit <approved-40-hex-commit> \
86
- --repository LuganoPlanB/bitcoin-roots \
87
- --assets /absolute/path/to/reviewed-release-assets \
88
- --notes /absolute/path/to/reviewed-release-notes.md \
89
- --manifest-sha512 <reviewed-128-hex-digest> \
90
- --notes-sha256 <reviewed-64-hex-digest>
91
- ```
92
-
93
- The default validates without a remote write. After explicit draft authority,
94
- repeat the same command with `--create-draft`. The helper copies the exact packet
95
- and notes into a private temporary snapshot, verifies all six checksums, archive
96
- roots/COPYING/platform notice indexes, local annotated tag/source/linear ancestry,
97
- and the exact portable patch regenerated and replayed from that tag. It then
98
- refreshes remote canonical/tag object/peeled identities and checks every page of
99
- the release inventory. Network/API failure or any existing draft/public release
100
- blocks creation. The only write is `gh release create --draft --verify-tag` with
101
- those seven immutable assets and the reviewed notes; it never updates, clobbers
102
- or publishes an existing release. An interrupted upload requires independent
103
- inspection of its partial draft, not an automatic helper retry or replacement.
104
-
105
- This initial handoff accepts unsigned manifests only. `SHA512SUMS.asc` or any
106
- unexpected file is rejected. Do not infer signing from the inherited public-key
107
- comment in SHA512SUMS. Optional use of `sign-manifest.sh` remains a separate
108
- signing operation, with signed-packet upload requiring its own reviewed path;
109
- never access signing secrets for unsigned draft creation. State the actual Git
110
- tag, manifest and platform-code signature status in the notes.
111
-
112
- Independently download and verify the newly created draft, including notes and
113
- contributor credit, before separately authorized visibility-only publication.
114
- After publication verify all public assets unauthenticated. The helper requires
115
- canonical-tip equality before draft creation; later consumer verification uses
116
- the immutable release tag when the canonical branch has advanced.
71
+ ## Runner collection and signed CI draft
72
+
73
+ `runner-notices.py` feeds the existing descriptor/collection format above:
74
+
75
+ - Linux runs inside the build container after the new build, while installed
76
+ `depends` toolchains/recipes and verified source archives remain available.
77
+ The notice tree persists into the mounted build directory. Both architectures
78
+ independently capture selected packages and Qt's additional source archives.
79
+ - macOS captures matching installed Homebrew formula receipts and verified
80
+ source hashes for required dependencies and any extra Qt modules proven in
81
+ the built bundle. Qt's non-archive umbrella and unrelated CA/tool formulas
82
+ are excluded. Bundle hashes/`otool` records prove system SQLite linkage.
83
+ - Windows captures the actual `build/vcpkg_installed` status and static-triplet
84
+ copyrights. Boost split ports form one logical Boost notice with every exact
85
+ installed version/copyright; the pinned manifest baseline remains evidence.
86
+
87
+ The platform archive is staged and validated in the same job before upload.
88
+ The tag-only final job downloads only its own run's five archives and patch,
89
+ runs `prepare-release.sh`, and requires signing through `sign-manifest.sh` with
90
+ `REQUIRE_RELEASE_SIGNATURE=1`. The real secret is passed only to that step;
91
+ never copy it to local tooling or build jobs. A missing/mismatched key fails.
92
+
93
+ `create-ci-draft.py` requires exactly eight regular nonempty assets. It reuses
94
+ the packet/source/notice/patch replay guards, independently imports only the
95
+ checked-in public key and verifies `SHA512SUMS.asc` with the expected fingerprint.
96
+ It snapshots the checked bytes and curated notes, refreshes remote tag/canonical
97
+ identities and paginated release inventory, then calls only
98
+ `gh release create --draft --verify-tag`. Any existing draft/public release or
99
+ network ambiguity fails closed; no clobber/update/deletion/replacement exists.
100
+ The notes add the actual fresh build run/source and distinguish manifest, Git
101
+ and platform signatures. `contrib/release/release-notes.md` is the reviewed
102
+ curated template, including #24/#25 contributor credit.
103
+
104
+ The older `create-draft.py` remains a validation/unsigned-packet utility and
105
+ shares its fail-closed guards with the signed CI path. It is not the normal
106
+ release publication route. Never use it to bypass required CI signing.
107
+
108
+ Download all eight draft assets independently and check the manifest signature,
109
+ six asset checksums, package notices, immutable source/tag, patch replay and
110
+ notes before visibility-only publication under separate authority. Repeat the
111
+ consumer checks unauthenticated after publication. Interrupted creation needs
112
+ operator inspection of the partial draft; reruns cannot replace it.