hooks: fix non-unix gate_socket_transport stub signature (Windows build) #13
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Docker | |
| # Build and publish the busbar container image (Docker Hub + GHCR) as a multi-arch | |
| # manifest (linux/amd64 + linux/arm64), FROM scratch over static musl binaries. | |
| # | |
| # Triggers: | |
| # - v* tags: publish with the semver tag cascade (X.Y.Z, X.Y, X, latest) | |
| # - workflow_dispatch: publish a `test` tag only — end-to-end pipeline check | |
| # without cutting a release. | |
| # | |
| # Supply chain: both registries carry a GitHub build-provenance attestation | |
| # (stored by GitHub — no extra tags on the repo). Verify with: | |
| # gh attestation verify oci://index.docker.io/getbusbar/busbar:<tag> --repo MattJackson/busbarAI | |
| # Cosign signatures are additionally pushed for the GHCR image only — cosign | |
| # stores signatures as sha256-*.sig tags, which we keep off the Docker Hub tag | |
| # list deliberately (clean public page; GHCR carries them for cosign users): | |
| # cosign verify ghcr.io/mattjackson/busbar:<tag> \ | |
| # --certificate-identity-regexp 'https://github.com/MattJackson/busbarAI/\.github/workflows/docker\.yml@.*' \ | |
| # --certificate-oidc-issuer https://token.actions.githubusercontent.com | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: >- | |
| Publish as this version (e.g. 1.1.0) with the full semver tag cascade + | |
| latest. Only use when the dispatched ref is source-identical to that | |
| release. Leave empty to publish only a `test` tag. | |
| required: false | |
| default: "" | |
| retag_from: | |
| description: >- | |
| Point `latest` at an ALREADY-PUBLISHED version (e.g. 1.1.1) with a | |
| manifest-only retag — no rebuild, and the immutable X.Y.Z tag is never | |
| re-pushed. Skips the build. Leave empty for a normal build. | |
| required: false | |
| default: "" | |
| env: | |
| DOCKERHUB_IMAGE: getbusbar/busbar | |
| GHCR_IMAGE: ghcr.io/mattjackson/busbar | |
| permissions: | |
| contents: read | |
| packages: write # push to GHCR | |
| id-token: write # keyless cosign signing | |
| attestations: write # build-provenance attestation | |
| jobs: | |
| # Manifest-only retag: point `latest` at an already-published version, no rebuild. | |
| # Used when version tags are immutable — the immutable X.Y.Z is never re-pushed. | |
| retag-latest: | |
| name: point latest at ${{ inputs.retag_from }} | |
| if: ${{ inputs.retag_from != '' }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: docker/setup-buildx-action@v3 | |
| - name: Log in to Docker Hub | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: Log in to GHCR | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Retag latest -> ${{ inputs.retag_from }} (multi-arch preserved) | |
| env: | |
| V: ${{ inputs.retag_from }} | |
| run: | | |
| set -euo pipefail | |
| # Docker Hub: point latest at the (immutable) version. Idempotent. | |
| docker buildx imagetools create -t "${DOCKERHUB_IMAGE}:latest" "${DOCKERHUB_IMAGE}:${V}" | |
| # GHCR may be MISSING this version if a prior combined build-push aborted mid-way | |
| # (e.g. Docker Hub tag-immutability rejected `latest` before GHCR finished). Mirror the | |
| # version from Docker Hub into GHCR (cross-registry manifest copy, no rebuild), then move | |
| # GHCR latest onto it. `imagetools create` is a no-op-safe overwrite if it already exists. | |
| docker buildx imagetools create -t "${GHCR_IMAGE}:${V}" "${DOCKERHUB_IMAGE}:${V}" | |
| docker buildx imagetools create -t "${GHCR_IMAGE}:latest" "${GHCR_IMAGE}:${V}" | |
| echo "== Docker Hub latest =="; docker buildx imagetools inspect "${DOCKERHUB_IMAGE}:latest" | grep -iE 'name|platform' | |
| echo "== GHCR ${V} =="; docker buildx imagetools inspect "${GHCR_IMAGE}:${V}" | grep -iE 'name|platform' | |
| # Static musl binaries, one per architecture, built on native runners (no QEMU). | |
| build-binaries: | |
| name: musl ${{ matrix.arch }} | |
| if: ${{ inputs.retag_from == '' }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: true | |
| matrix: | |
| include: | |
| - arch: amd64 | |
| os: ubuntu-latest | |
| target: x86_64-unknown-linux-musl | |
| - arch: arm64 | |
| os: ubuntu-24.04-arm | |
| target: aarch64-unknown-linux-musl | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Install musl toolchain | |
| run: sudo apt-get update && sudo apt-get install -y musl-tools | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| key: ${{ matrix.target }} | |
| - name: Build static binary | |
| env: | |
| # musl-gcc drives both the C compiles (bundled SQLite) and the final link. | |
| CC: musl-gcc | |
| CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER: musl-gcc | |
| CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER: musl-gcc | |
| run: | | |
| cargo build --release --target ${{ matrix.target }} | |
| file "target/${{ matrix.target }}/release/busbar" | |
| # Fail loudly if the binary is not fully static — FROM scratch has no loader. | |
| if ldd "target/${{ matrix.target }}/release/busbar" 2>&1 | grep -qv 'not a dynamic\|statically linked'; then | |
| echo "binary is dynamically linked; refusing to ship in FROM scratch" && exit 1 | |
| fi | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: busbar-${{ matrix.arch }} | |
| path: target/${{ matrix.target }}/release/busbar | |
| if-no-files-found: error | |
| publish: | |
| name: build & push image | |
| needs: build-binaries | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Stage binaries into build context | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: busbar-* | |
| path: staged | |
| - name: Arrange per-arch layout | |
| run: | | |
| mkdir -p binaries/amd64 binaries/arm64 | |
| mv staged/busbar-amd64/busbar binaries/amd64/busbar | |
| mv staged/busbar-arm64/busbar binaries/arm64/busbar | |
| chmod +x binaries/amd64/busbar binaries/arm64/busbar | |
| - uses: docker/setup-buildx-action@v3 | |
| - name: Log in to Docker Hub | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: Log in to GHCR | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| # The version being published: the pushed v* tag, or the workflow_dispatch | |
| # `version` input. Empty (bare dispatch) → publish only a `test` tag. | |
| - name: Resolve version | |
| id: ver | |
| run: | | |
| VER="${{ inputs.version }}" | |
| if [ -z "$VER" ] && [ "$GITHUB_REF_TYPE" = "tag" ]; then VER="$GITHUB_REF_NAME"; fi | |
| echo "ver=${VER#v}" >> "$GITHUB_OUTPUT" | |
| - name: Compute tags and labels | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: | | |
| ${{ env.DOCKERHUB_IMAGE }} | |
| ${{ env.GHCR_IMAGE }} | |
| # version resolved → X.Y.Z + latest (exact pins only, no floating | |
| # major/minor aliases — one consistent tag shape); bare dispatch → `test` only. | |
| tags: | | |
| type=semver,pattern={{version}},value=v${{ steps.ver.outputs.ver }},enable=${{ steps.ver.outputs.ver != '' }} | |
| type=raw,value=test,enable=${{ steps.ver.outputs.ver == '' }} | |
| labels: | | |
| org.opencontainers.image.title=busbar | |
| org.opencontainers.image.description=The reliability layer for LLM traffic — one endpoint, six wire protocols, fault-attributed circuit breaking, in-flight failover. | |
| org.opencontainers.image.url=https://getbusbar.com | |
| org.opencontainers.image.documentation=https://getbusbar.com/docs/getting-started/ | |
| org.opencontainers.image.licenses=Apache-2.0 | |
| - name: Build and push | |
| id: push | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| platforms: linux/amd64,linux/arm64 | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| - name: Install cosign | |
| uses: sigstore/cosign-installer@v3 | |
| # GHCR only: cosign stores signatures as sha256-*.sig tags, which we keep | |
| # off the Docker Hub tag list (clean public page). Hub verification runs | |
| # through the GitHub build-provenance attestation instead. | |
| - name: Sign GHCR image (keyless) | |
| env: | |
| DIGEST: ${{ steps.push.outputs.digest }} | |
| run: cosign sign --yes "${GHCR_IMAGE}@${DIGEST}" | |
| - name: Attest build provenance (Docker Hub) | |
| uses: actions/attest-build-provenance@v4 | |
| with: | |
| subject-name: index.docker.io/${{ env.DOCKERHUB_IMAGE }} | |
| subject-digest: ${{ steps.push.outputs.digest }} | |
| push-to-registry: false | |
| - name: Attest build provenance (GHCR) | |
| uses: actions/attest-build-provenance@v4 | |
| with: | |
| subject-name: ${{ env.GHCR_IMAGE }} | |
| subject-digest: ${{ steps.push.outputs.digest }} | |
| push-to-registry: true |