Skip to content
Merged
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
68 changes: 68 additions & 0 deletions .github/workflows/build_and_publish.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Publish Docker image

on:
push:
tags:
# Release tags only, so `latest` is never moved by an ad-hoc tag.
- "v*"

env:
REGISTRY: ghcr.io
IMAGE_NAME: 0xPolygon/polygon-cli

jobs:
build-and-push-image:
runs-on: ubuntu-latest

permissions:
contents: read
packages: write
attestations: write
id-token: write

steps:
# No QEMU needed: the Dockerfile cross-compiles on the native build
# platform and the final stage only COPYs the static binary.
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

Check failure on line 27 in .github/workflows/build_and_publish.yaml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use full commit SHA hash for this dependency.

See more on https://sonarcloud.io/project/issues?id=0xPolygon_polygon-cli&issues=AZ-ATZ77S69aJiTmWGRP&open=AZ-ATZ77S69aJiTmWGRP&pullRequest=963
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
Comment thread
minhd-vu marked this conversation as resolved.
Dismissed

- name: Checkout repository
uses: actions/checkout@v4
with:
# Full history + tags so the Makefile's `git describe --tags` can stamp
# the version into the binary.
fetch-depth: 0

- name: Log in to the Container registry
uses: docker/login-action@v3

Check failure on line 37 in .github/workflows/build_and_publish.yaml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use full commit SHA hash for this dependency.

See more on https://sonarcloud.io/project/issues?id=0xPolygon_polygon-cli&issues=AZ-ATZ77S69aJiTmWGRQ&open=AZ-ATZ77S69aJiTmWGRQ&pullRequest=963
Comment thread
minhd-vu marked this conversation as resolved.
Dismissed
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5

Check failure on line 45 in .github/workflows/build_and_publish.yaml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use full commit SHA hash for this dependency.

See more on https://sonarcloud.io/project/issues?id=0xPolygon_polygon-cli&issues=AZ-ATZ77S69aJiTmWGRR&open=AZ-ATZ77S69aJiTmWGRR&pullRequest=963
Comment thread
minhd-vu marked this conversation as resolved.
Dismissed
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=tag
type=semver,pattern={{version}}
type=raw,value=latest,enable=${{ !contains(github.ref_name, '-') }}

- name: Build and push Docker image
id: push
uses: docker/build-push-action@v6

Check failure on line 55 in .github/workflows/build_and_publish.yaml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use full commit SHA hash for this dependency.

See more on https://sonarcloud.io/project/issues?id=0xPolygon_polygon-cli&issues=AZ-ATZ77S69aJiTmWGRS&open=AZ-ATZ77S69aJiTmWGRS&pullRequest=963
Comment thread
minhd-vu marked this conversation as resolved.
Dismissed
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64

- name: Generate artifact attestation
uses: actions/attest-build-provenance@v2
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
55 changes: 55 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Container image for polycli. Primarily to run `polycli p2p sensor` on
# Container-Optimized OS (no on-host Go toolchain), but usable for any polycli
# subcommand.
#
# The build stage always runs on the native BUILDPLATFORM and cross-compiles to
# the target arch. CGO is required (vectorized-poseidon-gold has no pure-Go
# path), so cross-compiling with a real C toolchain avoids the very slow QEMU
# emulation a per-platform native build would need.
FROM --platform=$BUILDPLATFORM golang:1.26 AS build

# TARGETARCH is provided automatically by buildx (amd64, arm64, ...).
ARG TARGETARCH

WORKDIR /src

# make reuses the Makefile's version stamping; gcc-aarch64-linux-gnu is the same
# cross compiler the release workflow (make cross) uses for arm64. amd64 uses the
# native gcc already in the golang image. NOTE: because vectorized-poseidon-gold
# compiles the amd64 path with -march=native, the amd64 image must be built on an
# amd64 host (true on the ubuntu-latest CI runner); arm64 cross-compiles cleanly.
RUN apt-get update \
&& apt-get install -y --no-install-recommends make gcc-aarch64-linux-gnu \
&& rm -rf /var/lib/apt/lists/*

# Cache modules first (same cache mount as the build step so they aren't
# downloaded twice on a cold build).
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod go mod download

COPY . .

# Cross-compile a static, version-stamped binary. git describe reads the tags
# from the build context — the publish workflow checks out with fetch-depth: 0.
# Build cache mounts keep re-tag builds fast.
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg/mod \
GOARCH="$TARGETARCH" \
CC="$([ "$TARGETARCH" = arm64 ] && echo aarch64-linux-gnu-gcc || echo gcc)" \
make docker-build

# Staged empty dir so the final image's working directory is owned by the
# nonroot user (distroless has no shell to chown it there).
RUN mkdir -p /data

# The binary is fully static, so distroless/static (no glibc) is enough.
FROM gcr.io/distroless/static-debian12:nonroot

Check warning on line 46 in Dockerfile

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

This image might run with "root" as the default user. Make sure it is safe here.

See more on https://sonarcloud.io/project/issues?id=0xPolygon_polygon-cli&issues=AZ-AkVgrwUGMYK4dXTNr&open=AZ-AkVgrwUGMYK4dXTNr&pullRequest=963

# The sensor writes a nodes.json discovery cache to its working directory, so it
# must be owned by the nonroot runtime user (uid 65532).
COPY --from=build --chown=65532:65532 /data /data
WORKDIR /data

COPY --from=build /src/out/polycli /usr/local/bin/polycli

ENTRYPOINT ["/usr/local/bin/polycli"]
11 changes: 11 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ $(BUILD_DIR): ## Create the build folder.
build: $(BUILD_DIR) ## Build go binary.
go build -ldflags "$(VERSION_FLAGS)" -o $(BUILD_DIR)/$(BIN_NAME) main.go

.PHONY: docker-build
docker-build: $(BUILD_DIR) ## Build a fully static linux binary for the Dockerfile (GOARCH/CC come from the environment).
# Fully static (netgo + -extldflags "-static") like the `cross` target, so the
# image can ship on distroless/static. GOARCH and CC are set by the Dockerfile
# so it can cross-compile on the native build platform instead of emulating.
CGO_ENABLED=1 GOOS=linux go build \
-ldflags '$(VERSION_FLAGS) -s -w -linkmode external -extldflags "-static"' \
-tags netgo \
-o $(BUILD_DIR)/$(BIN_NAME) \
main.go

.PHONY: install
install: build ## Install the go binary.
$(RM) $(INSTALL_DIR)/$(BIN_NAME)
Expand Down