Skip to content

feat: publish pre-built binaries with releases #209

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
171 changes: 171 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
---
name: build

on:
push:
branches: [main] # pushes TO main
pull_request:
branches: [main] # pull requests AGAINST main
release:
types: [published] # for release build

# cancel CI runs when a new commit is pushed to any branch except main
concurrency:
group: 'build-${{ github.ref }}'
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 5

permissions:
contents: read # for uses: actions/checkout
id-token: write # for actions/attest-build-provenance
attestations: write # for actions/attest-build-provenance

strategy:
fail-fast: false
matrix:
# Static binaries are built with the `stable` version
# If you want to add a target, add it below.
include:
- {goos: 'darwin', goarch: 'amd64'}
- {goos: 'darwin', goarch: 'arm64'}
- {goos: 'linux', goarch: 'amd64'}
- {goos: 'linux', goarch: 'arm', goarm: '6'}
- {goos: 'linux', goarch: 'arm', goarm: '7'}
- {goos: 'linux', goarch: 'arm64'}
- {goos: 'linux', goarch: 'riscv64'}
- {goos: 'windows', goarch: 'amd64'}
- {goos: 'windows', goarch: 'arm64',}

steps:
- name: Checkout
uses: actions/checkout@v4
with:
# Security measures
# See also: https://github.com/actions/checkout/issues/485
persist-credentials: false

- name: Setup golang
uses: actions/setup-go@v5
with:
go-version: stable
# Disabled in multi-platform builds due to complex caching strategies
cache: false

- run: make release
env:
DIST_PATH: dist
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
GOARM: ${{ matrix.goarch == 'arm' && matrix.goarm || '' }}

- name: Generate artifact attestation
uses: actions/attest-build-provenance@v2
# Since the necessary permissions cannot be set in the pull_request event, it is limited to push events.
if: ${{ !startsWith(github.event_name, 'pull') }}
with:
subject-path: dist/go-httpbin-*

- name: Check artifacts
run: |
file dist/go-httpbin-*
stat dist/go-httpbin-*

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: go-httpbin-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.goarch == 'arm' && format('v{0}', matrix.goarm) || '' }}
path: dist/

checksum:
needs: [build]
runs-on: ubuntu-latest
timeout-minutes: 5

permissions:
id-token: write # for uses: aactions/attest-build-provenance
attestations: write # for uses: aactions/attest-build-provenance

steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
path: dist/
pattern: go-httpbin-*
merge-multiple: true

- name: Check artifacts
run: tree --charset ASCII dist/

- name: Verify artifacts
# Since the necessary permissions cannot be set in the pull_request event, it is limited to push events.
if: ${{ !startsWith(github.event_name, 'pull') }}
run: |
cd dist
for f in $(find . -type f -name 'go-httpbin-*' -printf '%f\n' | sort); do
gh attestation verify "$f" -R "${GITHUB_REPOSITORY}";
done
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Generate sha256 checksums
run: |
cd dist
echo -n > SHA256SUMS
for f in $(find . -type f -name 'go-httpbin-*' -printf '%f\n' | sort); do
sha256sum "$f" | tee -a SHA256SUMS;
done

- name: Verify sha256 checksums
run: cd dist && sha256sum -c SHA256SUMS

- name: Generate artifact attestation
# Since the necessary permissions cannot be set in the pull_request event, it is limited to push events.
if: ${{ !startsWith(github.event_name, 'pull') }}
uses: actions/attest-build-provenance@v2
with:
subject-path: dist/SHA256SUMS

- name: Upload sha256 checksum
uses: actions/upload-artifact@v4
with:
name: checksum-sha256sums
path: dist/SHA256SUMS

publish:
needs: [build, checksum]
runs-on: ubuntu-latest
timeout-minutes: 5

permissions:
contents: write # for gh release upload
id-token: write # for actions/attest-build-provenance
attestations: write # for actions/attest-build-provenance

steps:
- name: Download binary artifacts
uses: actions/download-artifact@v4
with:
path: dist/
pattern: go-httpbin-*
merge-multiple: true

- name: Download checksum artifacts
uses: actions/download-artifact@v4
with:
path: dist/
pattern: checksum-*
merge-multiple: true

- name: Check artifacts
run: tree --charset ASCII dist/

- name: Publish artifacts
if: startsWith(github.ref, 'refs/tags/')
run: |-
gh release upload "$(echo "${GITHUB_REF}" | sed -E 's!refs/tags/!!')" dist/* -R "${GITHUB_REPOSITORY}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
23 changes: 23 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,21 @@ STATICCHECK := go run honnef.co/go/tools/cmd/[email protected]
HOST ?= 127.0.0.1
PORT ?= 8080

# Determine the name of the static binary for the release build
GOOS ?= $(shell go env GOOS)
GOARCH ?= $(shell go env GOARCH)
ifeq (x$(GOOS)x,xwindowsx)
GOENVS ?= GOOS=$(GOOS) GOARCH=$(GOARCH)
BINNAME ?= go-httpbin-$(GOOS)-$(GOARCH).exe
else
ifeq (x$(GOARCH)x,xarmx)
GOENVS ?= GOOS=$(GOOS) GOARCH=$(GOARCH) GOARM=$(GOARM)
BINNAME ?= go-httpbin-$(GOOS)-$(GOARCH)v$(GOARM)
else
GOENVS ?= GOOS=$(GOOS) GOARCH=$(GOARCH)
BINNAME ?= go-httpbin-$(GOOS)-$(GOARCH)
endif
endif

# =============================================================================
# build
Expand Down Expand Up @@ -99,3 +114,11 @@ imagepush:
docker buildx build --push --platform linux/amd64,linux/arm64 -t $(DOCKER_TAG) .
docker buildx rm httpbin
.PHONY: imagepush

# =============================================================================
# release build
# =============================================================================
release:
mkdir -p $(DIST_PATH)
CGO_ENABLED=0 $(GOENVS) go build -trimpath -ldflags '-s -w -buildid=' -o $(DIST_PATH)/$(BINNAME) ./cmd/go-httpbin
.PHONY: release