Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 39 additions & 40 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Release workflow: git tag v* builds sequencer tarballs, CM images, and pushes
# watchdog OCI images to ghcr.io + docker.io (requires DOCKERHUB_USERNAME /
# DOCKERHUB_TOKEN repo secrets, same as cartesi/cli).

name: Release

on:
Expand All @@ -18,6 +22,7 @@ on:

permissions:
contents: write
packages: write

jobs:
build-sequencer:
Expand Down Expand Up @@ -161,58 +166,52 @@ jobs:
path: dist/canonical-machine-image-*.tar.gz

build-watchdog-image:
name: Build watchdog image (${{ matrix.arch }})
# arm64 must build on an arm64 host — docker build --platform linux/arm64 on
# ubuntu-latest (amd64) without QEMU hits "exec format error" in RUN steps.
runs-on: ${{ matrix.runs_on }}
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
platform: linux/amd64
runs_on: ubuntu-latest
deb_sha_env: CARTESI_MACHINE_SHA256_AMD64
- arch: arm64
platform: linux/arm64
runs_on: ubuntu-24.04-arm
deb_sha_env: CARTESI_MACHINE_SHA256_ARM64

name: Build and push watchdog image
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5

- name: Load toolchain pins
uses: ./.github/actions/load-toolchain-pins

- name: Set up QEMU
uses: docker/setup-qemu-action@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mss a setup-qemu action so the multiarch can work.

Suggested change
- name: Set up QEMU
uses: docker/setup-qemu-action@v4

- name: Build and export watchdog image
env:
TAG: ${{ inputs.tag || github.ref_name }}
DEB_SHA_ENV: ${{ matrix.deb_sha_env }}
run: |
set -euo pipefail
DEB_SHA="${!DEB_SHA_ENV}"
image="sequencer-watchdog:${TAG}"
docker build \
--platform "${{ matrix.platform }}" \
--build-arg "RELEASE_TAG=${TAG}" \
--build-arg "GIT_COMMIT=${GITHUB_SHA}" \
--build-arg "CARTESI_MACHINE_VERSION=${CARTESI_MACHINE_VERSION}" \
--build-arg "CARTESI_MACHINE_DEB_SHA256=${DEB_SHA}" \
-f watchdog/Dockerfile \
-t "${image}" \
.
mkdir -p dist
docker save "${image}" | gzip -9 > "dist/sequencer-watchdog-${TAG}-linux-${{ matrix.arch }}.tar.gz"
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Upload artifact
uses: actions/upload-artifact@v6
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build and push watchdog image
uses: docker/build-push-action@v6
with:
name: watchdog-image-linux-${{ matrix.arch }}
path: dist/sequencer-watchdog-*.tar.gz
context: .
file: watchdog/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: |
ghcr.io/cartesi/sequencer-watchdog:${{ inputs.tag || github.ref_name }}
docker.io/cartesi/sequencer-watchdog:${{ inputs.tag || github.ref_name }}
build-args: |
RELEASE_TAG=${{ inputs.tag || github.ref_name }}
GIT_COMMIT=${{ github.sha }}
CARTESI_MACHINE_VERSION=${{ env.CARTESI_MACHINE_VERSION }}
CARTESI_MACHINE_DEB_SHA256_AMD64=${{ env.CARTESI_MACHINE_SHA256_AMD64 }}
CARTESI_MACHINE_DEB_SHA256_ARM64=${{ env.CARTESI_MACHINE_SHA256_ARM64 }}
cache-from: type=gha
cache-to: type=gha,mode=max

publish:
name: Publish GitHub Release
Expand Down
53 changes: 45 additions & 8 deletions docs/watchdog/operator-deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,60 @@ curl -sS -o /dev/null -w "%{http_code}\n" "$WATCHDOG_SEQUENCER_URL/finalized_sta
# expect 200 when a finalized snapshot exists (404 = not promoted yet or wrong host)
```

### 2. Watchdog runtime (release bundle or local build)
### 2. Watchdog runtime (release image or local build)

**Production (recommended):** use the **release bundle** for tag `vX` — same
**Production (recommended):** pull the **release container image** for tag `vX` — same
git tag as the sequencer binary and `canonical-machine-image-*-vX.tar.gz`.
Load `sequencer-watchdog-vX-linux-<arch>.tar.gz` (`docker load`) and verify
alignment via `release-manifest-vX.json` and `/opt/watchdog/RELEASE.json`

**Container images (preferred for Dockerfile / Fly.io assembly):**

| Registry | Image |
|----------|-------|
| GHCR | `ghcr.io/cartesi/sequencer-watchdog:vX` |
| Docker Hub | `docker.io/cartesi/sequencer-watchdog:vX` |

Multi-arch manifest (`amd64` + `arm64`).

Verify alignment via `release-manifest-vX.json` and `/opt/watchdog/RELEASE.json`
inside the image. Toolchain pins live in [`toolchain-pins.env`](../../toolchain-pins.env).

`cartesi-machine` in the watchdog image **must** match
`CARTESI_MACHINE_VERSION` in [`toolchain-pins.env`](../../toolchain-pins.env)
(the emulator that built the CM image tarball). Mismatch causes load failures
or false `state_mismatch`.

Release image quick run:
**Compose a custom image (e.g. Fly.io rootfs)** — base on `debian:trixie-slim`,
install the same runtime packages as the release image, then copy from the
published watchdog image:

```dockerfile
FROM debian:trixie-slim

RUN apt-get update && apt-get install -y --no-install-recommends \
lua5.4 libcurl4 libslirp0 libgomp1 ca-certificates util-linux \
&& rm -rf /var/lib/apt/lists/*

COPY --from=ghcr.io/cartesi/sequencer-watchdog:vX /opt/watchdog /opt/watchdog
COPY --from=ghcr.io/cartesi/sequencer-watchdog:vX /usr/local/bin/sequencer-watchdog /usr/local/bin/sequencer-watchdog
COPY --from=ghcr.io/cartesi/sequencer-watchdog:vX /usr/local/bin/cartesi-machine /usr/local/bin/cartesi-machine
COPY --from=ghcr.io/cartesi/sequencer-watchdog:vX /usr/local/lib/ /usr/local/lib/
COPY --from=ghcr.io/cartesi/sequencer-watchdog:vX /usr/local/lib/lua/ /usr/local/lib/lua/
COPY --from=ghcr.io/cartesi/sequencer-watchdog:vX /usr/local/share/lua/ /usr/local/share/lua/
COPY --from=ghcr.io/cartesi/sequencer-watchdog:vX /usr/local/share/cartesi-machine/ /usr/local/share/cartesi-machine/

ENV WATCHDOG_LUA_DEPS=/opt/watchdog/lib \
LUA_PATH="/opt/watchdog/lua/?.lua;/opt/watchdog/lua/?/init.lua;/usr/local/share/lua/5.4/?.lua;/usr/local/share/lua/5.4/?/init.lua;;" \
LUA_CPATH="/opt/watchdog/lib/?.so;/usr/local/lib/lua/5.4/?.so;;" \
LD_LIBRARY_PATH="/usr/local/lib" \
PATH="/usr/local/share/cartesi-machine:${PATH}"

ENTRYPOINT ["/usr/local/bin/sequencer-watchdog"]
```

**Run from the published image:**

```bash
docker load < sequencer-watchdog-vX-linux-amd64.tar.gz
docker pull ghcr.io/cartesi/sequencer-watchdog:vX

docker run --rm \
-e WATCHDOG_SEQUENCER_URL="https://<internal-sequencer>" \
Expand All @@ -73,13 +110,13 @@ docker run --rm \
-e WATCHDOG_CM_SNAPSHOT_SAFE_BLOCK="<bootstrap inclusion_block>" \
-v /var/lib/watchdog/state:/watchdog-state \
-v /var/lib/watchdog/cm-bootstrap:/cm-bootstrap:ro \
sequencer-watchdog:vX init
ghcr.io/cartesi/sequencer-watchdog:vX init

docker run --rm \
-e WATCHDOG_L1_RPC_URL="https://<archive-rpc>" \
-e WATCHDOG_STATE_DIR=/watchdog-state \
-v /var/lib/watchdog/state:/watchdog-state \
sequencer-watchdog:vX tick
ghcr.io/cartesi/sequencer-watchdog:vX tick
```

**Local / dev build:**
Expand Down
23 changes: 2 additions & 21 deletions scripts/ci-watchdog-docker-smoke.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,13 @@ cd "${root}"
source toolchain-pins.env

image="sequencer-watchdog:ci-smoke"
if command -v dpkg >/dev/null 2>&1; then
arch="$(dpkg --print-architecture)"
else
case "$(uname -m)" in
x86_64) arch=amd64 ;;
aarch64 | arm64) arch=arm64 ;;
*)
echo "unsupported arch for watchdog docker smoke: $(uname -m)" >&2
exit 1
;;
esac
fi
case "${arch}" in
amd64) deb_sha="${CARTESI_MACHINE_SHA256_AMD64}" ;;
arm64) deb_sha="${CARTESI_MACHINE_SHA256_ARM64}" ;;
*)
echo "unsupported arch for watchdog docker smoke: ${arch}" >&2
exit 1
;;
esac

docker build \
--build-arg "RELEASE_TAG=ci-smoke" \
--build-arg "GIT_COMMIT=local" \
--build-arg "CARTESI_MACHINE_VERSION=${CARTESI_MACHINE_VERSION}" \
--build-arg "CARTESI_MACHINE_DEB_SHA256=${deb_sha}" \
--build-arg "CARTESI_MACHINE_DEB_SHA256_AMD64=${CARTESI_MACHINE_SHA256_AMD64}" \
--build-arg "CARTESI_MACHINE_DEB_SHA256_ARM64=${CARTESI_MACHINE_SHA256_ARM64}" \
-f watchdog/Dockerfile \
-t "${image}" \
.
Expand Down
4 changes: 2 additions & 2 deletions scripts/generate-release-manifest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ artifacts_json="$(cat <<EOF
{"name":"sequencer-${tag}-linux-arm64.tar.gz","kind":"sequencer","arch":"arm64"},
{"name":"canonical-machine-image-devnet-${tag}.tar.gz","kind":"cm_image","chain":"devnet"},
{"name":"canonical-machine-image-sepolia-${tag}.tar.gz","kind":"cm_image","chain":"sepolia"},
{"name":"sequencer-watchdog-${tag}-linux-amd64.tar.gz","kind":"watchdog_image","arch":"amd64","format":"docker-save"},
{"name":"sequencer-watchdog-${tag}-linux-arm64.tar.gz","kind":"watchdog_image","arch":"arm64","format":"docker-save"}
{"name":"ghcr.io/cartesi/sequencer-watchdog:${tag}","kind":"watchdog_image","format":"oci","arch":"multi","registry":"ghcr"},
{"name":"docker.io/cartesi/sequencer-watchdog:${tag}","kind":"watchdog_image","format":"oci","arch":"multi","registry":"dockerhub"}
]
EOF
)"
Expand Down
9 changes: 5 additions & 4 deletions watchdog/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ FROM debian:${DEBIAN_VERSION} AS build
SHELL ["/bin/bash", "-o", "pipefail", "-c"]

ARG CARTESI_MACHINE_VERSION
ARG CARTESI_MACHINE_DEB_SHA256
ARG CARTESI_MACHINE_DEB_SHA256_AMD64
ARG CARTESI_MACHINE_DEB_SHA256_ARM64
ARG TARGETARCH

# wget + ca-certificates fetch the cartesi-machine .deb; gcc/pkg-config + Lua
Expand All @@ -33,13 +34,13 @@ COPY watchdog/third_party watchdog/third_party
RUN bash scripts/watchdog-lua-deps.sh

RUN case "${TARGETARCH}" in \
amd64) CM_ARCH=amd64 ;; \
arm64) CM_ARCH=arm64 ;; \
amd64) DEB_SHA="${CARTESI_MACHINE_DEB_SHA256_AMD64}"; CM_ARCH=amd64 ;; \
arm64) DEB_SHA="${CARTESI_MACHINE_DEB_SHA256_ARM64}"; CM_ARCH=arm64 ;; \
*) echo "unsupported TARGETARCH=${TARGETARCH}" >&2; exit 1 ;; \
esac \
&& wget -O /tmp/machine-emulator.deb \
"https://github.com/cartesi/machine-emulator/releases/download/${CARTESI_MACHINE_VERSION}/machine-emulator_${CM_ARCH}.deb" \
&& echo "${CARTESI_MACHINE_DEB_SHA256} /tmp/machine-emulator.deb" | sha256sum --check \
&& echo "${DEB_SHA} /tmp/machine-emulator.deb" | sha256sum --check \
&& dpkg-deb -x /tmp/machine-emulator.deb /tmp/cm \
&& mkdir -p /out/bin /out/lib /out/lib/lua/5.4 /out/share/cartesi-machine /out/share/lua/5.4 \
&& cp -a /tmp/cm/usr/bin/cartesi-machine /out/bin/ \
Expand Down
Loading