diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 0000000..20ddeb7 --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,115 @@ +name: Publish Docker Image + +on: + push: + branches: + - master + tags: + - "*" + workflow_dispatch: + +concurrency: + group: docker-publish-${{ github.ref }} + cancel-in-progress: true + +jobs: + resolve: + runs-on: ubuntu-latest + outputs: + should_publish: ${{ steps.publish.outputs.should_publish }} + image_tag: ${{ steps.publish.outputs.image_tag }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Resolve publish tag + id: publish + shell: bash + run: | + set -euo pipefail + + should_publish=false + image_tag="" + + if [[ "${GITHUB_REF_TYPE}" == "branch" && "${GITHUB_REF_NAME}" == "master" ]]; then + should_publish=true + image_tag="latest" + elif [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then + should_publish=true + image_tag="${GITHUB_REF_NAME}" + fi + + echo "should_publish=${should_publish}" >> "${GITHUB_OUTPUT}" + echo "image_tag=${image_tag}" >> "${GITHUB_OUTPUT}" + + build: + needs: resolve + if: needs.resolve.outputs.should_publish == 'true' + strategy: + fail-fast: false + matrix: + include: + - arch: amd64 + platform: linux/amd64 + runner: ubuntu-latest + - arch: arm64 + platform: linux/arm64 + runner: ubuntu-24.04-arm + runs-on: ${{ matrix.runner }} + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: blockstream + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push ${{ matrix.arch }} + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + platforms: ${{ matrix.platform }} + push: true + tags: blockstream/waterfalls:${{ needs.resolve.outputs.image_tag }}-${{ matrix.arch }} + cache-from: type=gha,scope=waterfalls-${{ matrix.arch }} + cache-to: type=gha,mode=max,scope=waterfalls-${{ matrix.arch }} + + manifest: + needs: + - resolve + - build + if: needs.resolve.outputs.should_publish == 'true' + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: blockstream + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Create multi-arch manifest + shell: bash + run: | + set -euo pipefail + docker buildx imagetools create \ + -t blockstream/waterfalls:${{ needs.resolve.outputs.image_tag }} \ + blockstream/waterfalls:${{ needs.resolve.outputs.image_tag }}-amd64 \ + blockstream/waterfalls:${{ needs.resolve.outputs.image_tag }}-arm64 + + - name: Inspect manifest + run: docker buildx imagetools inspect blockstream/waterfalls:${{ needs.resolve.outputs.image_tag }} diff --git a/AGENTS.md b/AGENTS.md index d47c3f4..4b82e7c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -66,6 +66,7 @@ No `rustfmt.toml` or `clippy.toml` — default settings are used. ### Imports Grouped in this order (separated by blank lines when practical): + 1. `std::` — standard library 2. External crates — `anyhow`, `elements`, `hyper`, `serde`, `tokio`, etc. 3. `crate::` / `super::` — internal modules @@ -128,13 +129,38 @@ tests/integration.rs # Integration tests benches/benches.rs # Criterion benchmarks ``` -## CI (`.github/workflows/rust.yml`) +## CI + +### Rust checks (`.github/workflows/rust.yml`) Runs on push/PR to `master`: + - **tests**: downloads bitcoind 28.0 & elementsd 23.2.4, runs `cargo test` and `cargo test -- --ignored` - **checks**: `cargo check` with various feature combinations - **nix**: `nix build .` with cachix +### Docker publish (`.github/workflows/docker-publish.yml`) + +Runs on push to `master`, tag creation, and manual dispatch: + +- Push to `master` publishes `blockstream/waterfalls:latest` +- Tag push publishes `blockstream/waterfalls:` + +The workflow builds native images on: + +- `ubuntu-latest` for `linux/amd64` +- `ubuntu-24.04-arm` for `linux/arm64` + +Then it creates a multi-arch manifest tag from per-arch tags: + +- `blockstream/waterfalls:-amd64` +- `blockstream/waterfalls:-arm64` +- `blockstream/waterfalls:` (manifest list with both architectures) + +Required GitHub repository secret: + +- `DOCKERHUB_TOKEN` + ## Cursor Rules From `.cursor/rules/my-custom-rule.mdc` (always applied):