Full-depth rename per the approved plan; the 'claw' product vocabulary (claws, /claws routes, clawId, Claw Chat) stays — it is now the brand. - Display brand: Clawmates (manifest, titles, hero, login/rail logo 'clawmates'); default host app.clawmates.work; registry ghcr.io/clawmates - Crates tc-* -> cm-* (16 crates + all imports); binaries clawmates-server/broker/bundler; images clawmates/*; env prefix CLAWMATES_* (+ CM_TEST_DATABASE_URL / CM_LIVE_LLM); config clawmates.toml; helm chart deploy/helm/clawmates with clawmates-* resources; db names clawmates*; sockets /run/clawmates; cookie cm_session; kind cluster clawmates-test; seccomp node profile clawmates-agent-profile.json - All 9 Playwright brand assertions updated in lockstep; historical spec document left untouched as the only remaining 'TeamClaw' - Local env migrated: dev pg clawmates-dev-pg/clawmates_dev, shared test server clawmates-test-pg, kind cluster recreated with image + profile, compose images rebuilt under clawmates/* Verified end to end: 161 Rust + 68 frontend tests, 29 Playwright journeys, 4 live kind tests, helm/install/LOC/placeholder gates, and the clean-room install rehearsal serving the clawmates login page from a signed bundle of the rebuilt images. Co-Authored-By: Claude Fable 5 <[email protected]>
118 lines
5.1 KiB
YAML
118 lines
5.1 KiB
YAML
# Release: build the images both deploy targets share, assemble the
|
|
# SIGNED air-gapped bundle, verify it offline, and attach everything to
|
|
# the tag. The signing key lives in repo secrets (BUNDLE_SIGNING_KEY,
|
|
# hex ed25519 from `clawmates-bundler keygen`); the matching public key is
|
|
# published out of band so customers can verify before docker load.
|
|
name: release
|
|
|
|
on:
|
|
push:
|
|
tags: ["v*"]
|
|
|
|
jobs:
|
|
bundle:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: dtolnay/rust-toolchain@stable
|
|
- uses: Swatinem/rust-cache@v2
|
|
|
|
- name: Version from tag
|
|
run: echo "VERSION=${GITHUB_REF_NAME#v}" >> "$GITHUB_ENV"
|
|
|
|
- name: Build images
|
|
run: |
|
|
docker build -t "clawmates/server:$VERSION" -f images/server.Dockerfile .
|
|
docker build -t "clawmates/frontend:$VERSION" -f images/frontend.Dockerfile .
|
|
docker build -t "clawmates/broker:$VERSION" -f images/broker.Dockerfile .
|
|
docker build -t "clawmates/agent-base:$VERSION" images/agent-base
|
|
docker build -t "clawmates/agent-browser:$VERSION" images/agent-browser
|
|
docker pull postgres:16-alpine
|
|
|
|
- name: SBOMs for every shipped image
|
|
run: |
|
|
mkdir -p dist/sboms
|
|
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh \
|
|
| sh -s -- -b /usr/local/bin
|
|
for image in server frontend broker agent-base agent-browser; do
|
|
syft "clawmates/$image:$VERSION" -o spdx-json \
|
|
> "dist/sboms/$image.spdx.json"
|
|
done
|
|
|
|
- name: Save image tarballs
|
|
run: |
|
|
mkdir -p dist/images
|
|
docker save "clawmates/server:$VERSION" -o dist/images/server.tar
|
|
docker save "clawmates/frontend:$VERSION" -o dist/images/frontend.tar
|
|
docker save "clawmates/broker:$VERSION" -o dist/images/broker.tar
|
|
docker pull tecnativa/docker-socket-proxy:0.3
|
|
docker save tecnativa/docker-socket-proxy:0.3 -o dist/images/socket-proxy.tar
|
|
docker save "clawmates/agent-base:$VERSION" -o dist/images/agent-base.tar
|
|
docker save "clawmates/agent-browser:$VERSION" -o dist/images/agent-browser.tar
|
|
docker save postgres:16-alpine -o dist/images/postgres.tar
|
|
|
|
- name: Build bundler
|
|
run: cargo build --release -p clawmates-bundler
|
|
|
|
- name: Assemble and sign the bundle
|
|
env:
|
|
BUNDLE_SIGNING_KEY: ${{ secrets.BUNDLE_SIGNING_KEY }}
|
|
run: |
|
|
printf '%s' "$BUNDLE_SIGNING_KEY" > /tmp/release.key
|
|
BUNDLER=target/release/clawmates-bundler
|
|
ARTIFACTS=""
|
|
for tar in dist/images/*.tar; do
|
|
ARTIFACTS="$ARTIFACTS $tar=images/$(basename "$tar")"
|
|
done
|
|
for migration in migrations/*.sql; do
|
|
ARTIFACTS="$ARTIFACTS $migration=migrations/$(basename "$migration")"
|
|
done
|
|
# shellcheck disable=SC2086
|
|
"$BUNDLER" assemble dist/bundle "$VERSION" /tmp/release.key \
|
|
deploy/compose/docker-compose.yml=compose/docker-compose.yml \
|
|
deploy/compose/clawmates.toml=compose/clawmates.toml \
|
|
deploy/compose/.env.example=compose/.env.example \
|
|
deploy/e2e/scenarios.toml=compose/scenarios.toml \
|
|
images/seccomp/agent-profile.json=seccomp/agent-profile.json \
|
|
deploy/airgapped/install.sh=install.sh \
|
|
"$BUNDLER"=bin/clawmates-bundler \
|
|
dist/sboms/server.spdx.json=sboms/server.spdx.json \
|
|
dist/sboms/frontend.spdx.json=sboms/frontend.spdx.json \
|
|
dist/sboms/agent-base.spdx.json=sboms/agent-base.spdx.json \
|
|
dist/sboms/agent-browser.spdx.json=sboms/agent-browser.spdx.json \
|
|
$ARTIFACTS
|
|
chmod +x dist/bundle/bin/clawmates-bundler dist/bundle/install.sh
|
|
rm /tmp/release.key
|
|
|
|
- name: Verify the bundle offline (public key only)
|
|
env:
|
|
BUNDLE_SIGNING_KEY: ${{ secrets.BUNDLE_SIGNING_KEY }}
|
|
run: |
|
|
printf '%s' "$BUNDLE_SIGNING_KEY" > /tmp/release.key
|
|
target/release/clawmates-bundler pubkey /tmp/release.key dist/release.pub
|
|
rm /tmp/release.key
|
|
# The customer's exact procedure: only the public half — and
|
|
# inside a NETWORK-DISABLED container, proving verification
|
|
# needs no internet (the air-gapped contract).
|
|
docker run --rm --network none \
|
|
-v "$PWD/dist:/dist:ro" \
|
|
ubuntu:24.04 \
|
|
/dist/bundle/bin/clawmates-bundler verify /dist/bundle /dist/release.pub
|
|
|
|
- name: Tarball
|
|
run: tar -C dist -czf "clawmates-bundle-$VERSION.tgz" bundle
|
|
|
|
- name: Clean-room install rehearsal
|
|
run: |
|
|
docker tag "clawmates/server:$VERSION" clawmates/server:latest
|
|
docker tag "clawmates/frontend:$VERSION" clawmates/frontend:latest
|
|
docker tag "clawmates/broker:$VERSION" clawmates/broker:latest
|
|
./scripts/rehearse-install.sh
|
|
|
|
- name: Attach to release
|
|
uses: softprops/action-gh-release@v2
|
|
with:
|
|
files: |
|
|
clawmates-bundle-*.tgz
|
|
dist/release.pub
|