diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6dcaece..8a89691 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -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: @@ -18,6 +22,7 @@ on: permissions: contents: write + packages: write jobs: build-sequencer: @@ -161,23 +166,8 @@ 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 @@ -185,34 +175,43 @@ jobs: - 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 - - 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 diff --git a/docs/watchdog/operator-deployment.md b/docs/watchdog/operator-deployment.md index 6116eed..59ed1bb 100644 --- a/docs/watchdog/operator-deployment.md +++ b/docs/watchdog/operator-deployment.md @@ -46,12 +46,21 @@ 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-.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 @@ -59,10 +68,38 @@ inside the image. Toolchain pins live in [`toolchain-pins.env`](../../toolchain- (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://" \ @@ -73,13 +110,13 @@ docker run --rm \ -e WATCHDOG_CM_SNAPSHOT_SAFE_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://" \ -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:** diff --git a/scripts/ci-watchdog-docker-smoke.sh b/scripts/ci-watchdog-docker-smoke.sh index 49ddacf..a1ff03c 100755 --- a/scripts/ci-watchdog-docker-smoke.sh +++ b/scripts/ci-watchdog-docker-smoke.sh @@ -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}" \ . diff --git a/scripts/generate-release-manifest.sh b/scripts/generate-release-manifest.sh index 5bfb75f..5073d74 100755 --- a/scripts/generate-release-manifest.sh +++ b/scripts/generate-release-manifest.sh @@ -58,8 +58,8 @@ artifacts_json="$(cat <&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/ \