Skip to content

Commit dc2ad82

Browse files
JasonVranekjclapisgithub-advanced-security[bot]
authored
Unified binary (#12)
* Started merging service binaries * Started refactoring handle_docker_init() * More refactoring of handle_docker_init * Fixed some tests * Reverted to multiple Docker images, merged CLI binary into CB * Updated justfile * Updated release workflow * Updated docs for unified binary * Clippy fix * Added integration tests to ensure the CLI commands work * one-click kurtosis support * More doc changes to use new binary * Remove panic!() and unwrap() from docker_init.rs and improve test coverage for these flows * Add cmds for test coverage + regroup kurtosis commands for easier viewing in `just -l` * Add criterion microbenchmark test for get_header with Justfile cmds * Add binary signing to GitHub releases (Commit-Boost#433) Co-authored-by: Jason Vranek <jasonvranek@gmail.com> * Fix for code scanning alert no. 21: Code injection Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * prevent cmd injection and pin sigstore version * fmt code --------- Co-authored-by: Joe Clapis <jclapis@outlook.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
1 parent a28743b commit dc2ad82

35 files changed

Lines changed: 2665 additions & 849 deletions

.github/workflows/release-gate.yml

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
name: Release Gate
2+
3+
on:
4+
pull_request:
5+
types: [closed]
6+
branches: [main]
7+
8+
jobs:
9+
release-gate:
10+
name: Tag and update release branches
11+
runs-on: ubuntu-latest
12+
# Only run when a release/ branch is merged (not just closed)
13+
if: |
14+
github.event.pull_request.merged == true &&
15+
startsWith(github.event.pull_request.head.ref, 'release/v')
16+
17+
permissions:
18+
contents: write
19+
20+
steps:
21+
- uses: actions/create-github-app-token@v1
22+
id: app-token
23+
with:
24+
app-id: ${{ secrets.APP_ID }}
25+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
26+
27+
- uses: actions/checkout@v4
28+
with:
29+
# Full history required for version comparison against existing tags
30+
# and for the fast-forward push to stable/beta.
31+
fetch-depth: 0
32+
token: ${{ steps.app-token.outputs.token }}
33+
34+
- name: Extract and validate version
35+
id: version
36+
env:
37+
BRANCH_REF: ${{ github.event.pull_request.head.ref }}
38+
run: |
39+
BRANCH="$BRANCH_REF"
40+
NEW_VERSION="${BRANCH#release/}"
41+
echo "new=${NEW_VERSION}" >> $GITHUB_OUTPUT
42+
43+
# Determine if this is an RC
44+
if echo "$NEW_VERSION" | grep -qE '\-rc[0-9]+$'; then
45+
echo "is_rc=true" >> $GITHUB_OUTPUT
46+
else
47+
echo "is_rc=false" >> $GITHUB_OUTPUT
48+
fi
49+
50+
- name: Validate version is strictly increasing
51+
env:
52+
NEW_VERSION: ${{ steps.version.outputs.new }}
53+
run: |
54+
# Get the latest tag; if none exist yet, skip the comparison
55+
LATEST_TAG=$(git tag --list 'v*' --sort=-version:refname | head -n1)
56+
if [ -z "$LATEST_TAG" ]; then
57+
echo "No existing tags found — skipping version comparison"
58+
exit 0
59+
fi
60+
61+
LATEST_VERSION="${LATEST_TAG#v}"
62+
63+
python3 - <<EOF
64+
import sys
65+
from packaging.version import Version
66+
67+
def normalize(v):
68+
# Convert vX.Y.Z-rcQ → X.Y.ZrcQ (PEP 440)
69+
return v.replace("-rc", "rc")
70+
71+
new = Version(normalize("$NEW_VERSION"))
72+
latest = Version(normalize("$LATEST_VERSION"))
73+
74+
print(f"Latest tag : {latest}")
75+
print(f"New version: {new}")
76+
77+
if new <= latest:
78+
print(f"\n❌ {new} is not strictly greater than current {latest}")
79+
sys.exit(1)
80+
81+
print(f"\n✅ Version order is valid")
82+
EOF
83+
84+
- name: Configure git
85+
run: |
86+
git config user.name "commit-boost-release-bot[bot]"
87+
git config user.email "commit-boost-release-bot[bot]@users.noreply.github.com"
88+
89+
- name: Create and push tag
90+
env:
91+
VERSION: ${{ steps.version.outputs.new }}
92+
run: |
93+
git tag "$VERSION" HEAD
94+
git push origin "$VERSION"
95+
# Branch fast-forwarding happens in release.yml after all artifacts
96+
# are successfully built. stable/beta are never touched if the build fails.

.github/workflows/release.yml

Lines changed: 138 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,25 @@ on:
88
permissions:
99
contents: write
1010
packages: write
11+
id-token: write
1112

1213
jobs:
13-
# Builds the x64 and arm64 binaries for Linux, for all 3 crates, via the Docker builder
14+
# Builds the x64 and arm64 binary for Linux via the Docker builder
1415
build-binaries-linux:
1516
strategy:
1617
matrix:
1718
target:
1819
- amd64
1920
- arm64
2021
name:
21-
- commit-boost-cli
22-
- commit-boost-pbs
23-
- commit-boost-signer
22+
- commit-boost
2423
include:
2524
- target: amd64
2625
package-suffix: x86-64
2726
- target: arm64
2827
package-suffix: arm64
29-
- name: commit-boost-cli
30-
target-crate: cli
31-
- name: commit-boost-pbs
32-
target-crate: pbs
33-
- name: commit-boost-signer
34-
target-crate: signer
28+
- name: commit-boost
29+
target-crate: commit-boost
3530
runs-on: ubuntu-latest
3631
steps:
3732
- name: Checkout code
@@ -44,6 +39,9 @@ jobs:
4439
run: |
4540
echo "Releasing commit: $(git rev-parse HEAD)"
4641
42+
- name: Set lowercase owner
43+
run: echo "OWNER=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
44+
4745
- name: Set up QEMU
4846
uses: docker/setup-qemu-action@v3
4947

@@ -63,8 +61,8 @@ jobs:
6361
context: .
6462
push: false
6563
platforms: linux/amd64,linux/arm64
66-
cache-from: type=registry,ref=ghcr.io/commit-boost/buildcache:${{ matrix.target-crate}}
67-
cache-to: type=registry,ref=ghcr.io/commit-boost/buildcache:${{ matrix.target-crate }},mode=max
64+
cache-from: type=registry,ref=ghcr.io/${{ env.OWNER }}/buildcache:${{ matrix.target-crate}}
65+
cache-to: type=registry,ref=ghcr.io/${{ env.OWNER }}/buildcache:${{ matrix.target-crate }},mode=max
6866
file: provisioning/build.Dockerfile
6967
outputs: type=local,dest=build
7068
build-args: |
@@ -83,7 +81,7 @@ jobs:
8381
path: |
8482
${{ matrix.name }}-${{ github.ref_name }}-linux_${{ matrix.package-suffix }}.tar.gz
8583
86-
# Builds the arm64 binaries for Darwin, for all 3 crates, natively
84+
# Builds the arm64 binary for Darwin natively
8785
build-binaries-darwin:
8886
strategy:
8987
matrix:
@@ -92,9 +90,7 @@ jobs:
9290
# - x86_64-apple-darwin
9391
- aarch64-apple-darwin
9492
name:
95-
- commit-boost-cli
96-
- commit-boost-pbs
97-
- commit-boost-signer
93+
- commit-boost
9894
include:
9995
# - target: x86_64-apple-darwin
10096
# os: macos-latest-large
@@ -158,6 +154,31 @@ jobs:
158154
path: |
159155
${{ matrix.name }}-${{ github.ref_name }}-darwin_${{ matrix.package-suffix }}.tar.gz
160156
157+
# Signs the binaries
158+
sign-binaries:
159+
needs:
160+
- build-binaries-linux
161+
- build-binaries-darwin
162+
runs-on: ubuntu-latest
163+
steps:
164+
- name: Download artifacts
165+
uses: actions/download-artifact@v4
166+
with:
167+
path: ./artifacts
168+
pattern: "commit-boost*"
169+
170+
- name: Sign binaries
171+
uses: sigstore/gh-action-sigstore-python@a5caf349bc536fbef3668a10ed7f5cd309a4b53d #v3.2.0
172+
with:
173+
inputs: ./artifacts/**/*.tar.gz
174+
175+
- name: Upload signatures
176+
uses: actions/upload-artifact@v4
177+
with:
178+
name: signatures-${{ github.ref_name }}
179+
path: |
180+
./artifacts/**/*.sigstore.json
181+
161182
# Builds the PBS Docker image
162183
build-and-push-pbs-docker:
163184
needs: [build-binaries-linux]
@@ -173,16 +194,19 @@ jobs:
173194
uses: actions/download-artifact@v4
174195
with:
175196
path: ./artifacts
176-
pattern: "commit-boost-*"
197+
pattern: "commit-boost*"
177198

178199
- name: Extract binaries
179200
run: |
180201
mkdir -p ./artifacts/bin/linux_amd64
181202
mkdir -p ./artifacts/bin/linux_arm64
182-
tar -xzf ./artifacts/commit-boost-pbs-${{ github.ref_name }}-linux_x86-64/commit-boost-pbs-${{ github.ref_name }}-linux_x86-64.tar.gz -C ./artifacts/bin
183-
mv ./artifacts/bin/commit-boost-pbs ./artifacts/bin/linux_amd64/commit-boost-pbs
184-
tar -xzf ./artifacts/commit-boost-pbs-${{ github.ref_name }}-linux_arm64/commit-boost-pbs-${{ github.ref_name }}-linux_arm64.tar.gz -C ./artifacts/bin
185-
mv ./artifacts/bin/commit-boost-pbs ./artifacts/bin/linux_arm64/commit-boost-pbs
203+
tar -xzf ./artifacts/commit-boost-${{ github.ref_name }}-linux_x86-64/commit-boost-${{ github.ref_name }}-linux_x86-64.tar.gz -C ./artifacts/bin
204+
mv ./artifacts/bin/commit-boost ./artifacts/bin/linux_amd64/commit-boost
205+
tar -xzf ./artifacts/commit-boost-${{ github.ref_name }}-linux_arm64/commit-boost-${{ github.ref_name }}-linux_arm64.tar.gz -C ./artifacts/bin
206+
mv ./artifacts/bin/commit-boost ./artifacts/bin/linux_arm64/commit-boost
207+
208+
- name: Set lowercase owner
209+
run: echo "OWNER=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
186210

187211
- name: Set up QEMU
188212
uses: docker/setup-qemu-action@v3
@@ -206,8 +230,8 @@ jobs:
206230
build-args: |
207231
BINARIES_PATH=./artifacts/bin
208232
tags: |
209-
ghcr.io/commit-boost/pbs:${{ github.ref_name }}
210-
${{ !contains(github.ref_name, 'rc') && 'ghcr.io/commit-boost/pbs:latest' || '' }}
233+
ghcr.io/${{ env.OWNER }}/pbs:${{ github.ref_name }}
234+
${{ !contains(github.ref_name, 'rc') && format('ghcr.io/{0}/pbs:latest', env.OWNER) || '' }}
211235
file: provisioning/pbs.Dockerfile
212236

213237
# Builds the Signer Docker image
@@ -225,16 +249,19 @@ jobs:
225249
uses: actions/download-artifact@v4
226250
with:
227251
path: ./artifacts
228-
pattern: "commit-boost-*"
252+
pattern: "commit-boost*"
229253

230254
- name: Extract binaries
231255
run: |
232256
mkdir -p ./artifacts/bin/linux_amd64
233257
mkdir -p ./artifacts/bin/linux_arm64
234-
tar -xzf ./artifacts/commit-boost-signer-${{ github.ref_name }}-linux_x86-64/commit-boost-signer-${{ github.ref_name }}-linux_x86-64.tar.gz -C ./artifacts/bin
235-
mv ./artifacts/bin/commit-boost-signer ./artifacts/bin/linux_amd64/commit-boost-signer
236-
tar -xzf ./artifacts/commit-boost-signer-${{ github.ref_name }}-linux_arm64/commit-boost-signer-${{ github.ref_name }}-linux_arm64.tar.gz -C ./artifacts/bin
237-
mv ./artifacts/bin/commit-boost-signer ./artifacts/bin/linux_arm64/commit-boost-signer
258+
tar -xzf ./artifacts/commit-boost-${{ github.ref_name }}-linux_x86-64/commit-boost-${{ github.ref_name }}-linux_x86-64.tar.gz -C ./artifacts/bin
259+
mv ./artifacts/bin/commit-boost ./artifacts/bin/linux_amd64/commit-boost
260+
tar -xzf ./artifacts/commit-boost-${{ github.ref_name }}-linux_arm64/commit-boost-${{ github.ref_name }}-linux_arm64.tar.gz -C ./artifacts/bin
261+
mv ./artifacts/bin/commit-boost ./artifacts/bin/linux_arm64/commit-boost
262+
263+
- name: Set lowercase owner
264+
run: echo "OWNER=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
238265

239266
- name: Set up QEMU
240267
uses: docker/setup-qemu-action@v3
@@ -258,32 +285,110 @@ jobs:
258285
build-args: |
259286
BINARIES_PATH=./artifacts/bin
260287
tags: |
261-
ghcr.io/commit-boost/signer:${{ github.ref_name }}
262-
${{ !contains(github.ref_name, 'rc') && 'ghcr.io/commit-boost/signer:latest' || '' }}
288+
ghcr.io/${{ env.OWNER }}/signer:${{ github.ref_name }}
289+
${{ !contains(github.ref_name, 'rc') && format('ghcr.io/{0}/signer:latest', env.OWNER) || '' }}
263290
file: provisioning/signer.Dockerfile
264291

265292
# Creates a draft release on GitHub with the binaries
266293
finalize-release:
267294
needs:
268295
- build-binaries-linux
269296
- build-binaries-darwin
297+
- sign-binaries
270298
- build-and-push-pbs-docker
271299
- build-and-push-signer-docker
272300
runs-on: ubuntu-latest
273301
steps:
274-
- name: Download artifacts
302+
- name: Download binaries
303+
uses: actions/download-artifact@v4
304+
with:
305+
path: ./artifacts
306+
pattern: "commit-boost*"
307+
308+
- name: Download signatures
275309
uses: actions/download-artifact@v4
276310
with:
277311
path: ./artifacts
278-
pattern: "commit-boost-*"
312+
pattern: "signatures-${{ github.ref_name }}*"
279313

280314
- name: Finalize Release
281315
uses: softprops/action-gh-release@v2
282316
with:
283317
files: ./artifacts/**/*
284318
draft: true
285-
prerelease: false
319+
prerelease: ${{ contains(github.ref_name, '-rc') }}
286320
tag_name: ${{ github.ref_name }}
287321
name: ${{ github.ref_name }}
288322
env:
289323
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
324+
325+
# Fast-forwards stable (full release) or beta (RC) to the new tag.
326+
# Runs after all artifacts are built and the draft release is created,
327+
# so stable/beta are never touched if any part of the pipeline fails.
328+
fast-forward-branch:
329+
needs:
330+
- finalize-release
331+
runs-on: ubuntu-latest
332+
steps:
333+
- uses: actions/create-github-app-token@v1
334+
id: app-token
335+
with:
336+
app-id: ${{ secrets.APP_ID }}
337+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
338+
339+
- uses: actions/checkout@v4
340+
with:
341+
fetch-depth: 0
342+
token: ${{ steps.app-token.outputs.token }}
343+
344+
- name: Configure git
345+
run: |
346+
git config user.name "commit-boost-release-bot[bot]"
347+
git config user.email "commit-boost-release-bot[bot]@users.noreply.github.com"
348+
349+
- name: Fast-forward beta branch (RC releases)
350+
if: contains(github.ref_name, '-rc')
351+
run: |
352+
git checkout beta
353+
git merge --ff-only "${{ github.ref_name }}"
354+
git push origin beta
355+
356+
- name: Fast-forward stable branch (full releases)
357+
if: "!contains(github.ref_name, '-rc')"
358+
run: |
359+
git checkout stable
360+
git merge --ff-only "${{ github.ref_name }}"
361+
git push origin stable
362+
363+
# Deletes the tag if any job in the release pipeline fails.
364+
# This keeps the tag and release artifacts in sync — a tag should only
365+
# exist if the full pipeline completed successfully.
366+
# stable/beta are never touched on failure since fast-forward-branch
367+
# only runs after finalize-release succeeds.
368+
#
369+
# Note: if finalize-release specifically fails, a draft release may already
370+
# exist on GitHub pointing at the now-deleted tag and will need manual cleanup.
371+
cleanup-on-failure:
372+
needs:
373+
- build-binaries-linux
374+
- build-binaries-darwin
375+
- sign-binaries
376+
- build-and-push-pbs-docker
377+
- build-and-push-signer-docker
378+
- finalize-release
379+
- fast-forward-branch
380+
runs-on: ubuntu-latest
381+
if: failure()
382+
steps:
383+
- uses: actions/create-github-app-token@v1
384+
id: app-token
385+
with:
386+
app-id: ${{ secrets.APP_ID }}
387+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
388+
389+
- uses: actions/checkout@v4
390+
with:
391+
token: ${{ steps.app-token.outputs.token }}
392+
393+
- name: Delete tag
394+
run: git push origin --delete ${{ github.ref_name }}

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,6 @@ devenv.*
2424
devenv.lock
2525
.devenv.flake.nix
2626
.envrc
27+
28+
# Generated from testnet
29+
kurtosis-dump

0 commit comments

Comments
 (0)