Files
clawmates/.github/workflows/release.yml
T
Omar SobhandClaude Fable 5 add4f79fed Rebrand: TeamClaw -> Clawmates (clawmates.work)
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]>
2026-06-10 12:31:25 -05:00

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