Skip to content

Commit 857d10f

Browse files
committed
feat: Add GitHub Actions workflow and Makefile support for multi-platform release builds
- Introduced `.github/workflows/build.yaml` for CI/CD, including build, checksum, and publish jobs - Supports Go cross-compilation for multiple OS/arch targets - Includes artifact attestation and checksum generation - Publishes artifacts to GitHub Releases on tag push - Extended `Makefile` with `release` target to generate static binaries per target - Supports GOOS/GOARCH/GOARM detection and naming
1 parent 1379030 commit 857d10f

File tree

2 files changed

+194
-0
lines changed

2 files changed

+194
-0
lines changed

.github/workflows/build.yaml

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
---
2+
name: build
3+
4+
on:
5+
push:
6+
branches: [main] # pushes TO main
7+
pull_request:
8+
branches: [main] # pull requests AGAINST main
9+
release:
10+
types: [published] # for release build
11+
12+
# cancel CI runs when a new commit is pushed to any branch except main
13+
concurrency:
14+
group: 'build-${{ github.ref }}'
15+
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
16+
17+
jobs:
18+
build:
19+
runs-on: ubuntu-latest
20+
timeout-minutes: 5
21+
22+
permissions:
23+
contents: read # for uses: actions/checkout
24+
id-token: write # for actions/attest-build-provenance
25+
attestations: write # for actions/attest-build-provenance
26+
27+
strategy:
28+
fail-fast: false
29+
matrix:
30+
# Static binaries are built with the `stable` version
31+
# If you want to add a target, add it below.
32+
include:
33+
- {goos: 'darwin', goarch: 'amd64'}
34+
- {goos: 'darwin', goarch: 'arm64'}
35+
- {goos: 'linux', goarch: 'amd64'}
36+
- {goos: 'linux', goarch: 'arm', goarm: '6'}
37+
- {goos: 'linux', goarch: 'arm', goarm: '7'}
38+
- {goos: 'linux', goarch: 'arm64'}
39+
- {goos: 'linux', goarch: 'riscv64'}
40+
- {goos: 'windows', goarch: 'amd64'}
41+
- {goos: 'windows', goarch: 'arm64',}
42+
43+
steps:
44+
- name: Checkout
45+
uses: actions/checkout@v4
46+
with:
47+
# Security measures
48+
# See also: https://github.com/actions/checkout/issues/485
49+
persist-credentials: false
50+
51+
- name: Setup golang
52+
uses: actions/setup-go@v5
53+
with:
54+
go-version: stable
55+
# Disabled in multi-platform builds due to complex caching strategies
56+
cache: false
57+
58+
- run: make release
59+
env:
60+
DIST_PATH: dist
61+
GOOS: ${{ matrix.goos }}
62+
GOARCH: ${{ matrix.goarch }}
63+
GOARM: ${{ matrix.goarch == 'arm' && matrix.goarm || '' }}
64+
65+
- name: Generate artifact attestation
66+
uses: actions/attest-build-provenance@v2
67+
# Since the necessary permissions cannot be set in the pull_request event, it is limited to push events.
68+
if: ${{ !startsWith(github.event_name, 'pull') }}
69+
with:
70+
subject-path: dist/go-httpbin-*
71+
72+
- name: Check artifacts
73+
run: |
74+
file dist/go-httpbin-*
75+
stat dist/go-httpbin-*
76+
77+
- name: Upload artifacts
78+
uses: actions/upload-artifact@v4
79+
with:
80+
name: go-httpbin-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.goarch == 'arm' && format('v{0}', matrix.goarm) || '' }}
81+
path: dist/
82+
83+
checksum:
84+
needs: [build]
85+
runs-on: ubuntu-latest
86+
timeout-minutes: 5
87+
88+
permissions:
89+
id-token: write # for uses: aactions/attest-build-provenance
90+
attestations: write # for uses: aactions/attest-build-provenance
91+
92+
steps:
93+
- name: Download artifacts
94+
uses: actions/download-artifact@v4
95+
with:
96+
path: dist/
97+
pattern: go-httpbin-*
98+
merge-multiple: true
99+
100+
- name: Check artifacts
101+
run: tree --charset ASCII dist/
102+
103+
- name: Verify artifacts
104+
# Since the necessary permissions cannot be set in the pull_request event, it is limited to push events.
105+
if: ${{ !startsWith(github.event_name, 'pull') }}
106+
run: |
107+
cd dist
108+
for f in $(find . -type f -name 'go-httpbin-*' -printf '%f\n' | sort); do
109+
gh attestation verify "$f" -R "${GITHUB_REPOSITORY}";
110+
done
111+
env:
112+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
113+
114+
- name: Generate sha256 checksums
115+
run: |
116+
cd dist
117+
echo -n > SHA256SUMS
118+
for f in $(find . -type f -name 'go-httpbin-*' -printf '%f\n' | sort); do
119+
sha256sum "$f" | tee -a SHA256SUMS;
120+
done
121+
122+
- name: Verify sha256 checksums
123+
run: cd dist && sha256sum -c SHA256SUMS
124+
125+
- name: Generate artifact attestation
126+
# Since the necessary permissions cannot be set in the pull_request event, it is limited to push events.
127+
if: ${{ !startsWith(github.event_name, 'pull') }}
128+
uses: actions/attest-build-provenance@v2
129+
with:
130+
subject-path: dist/SHA256SUMS
131+
132+
- name: Upload sha256 checksum
133+
uses: actions/upload-artifact@v4
134+
with:
135+
name: checksum-sha256sums
136+
path: dist/SHA256SUMS
137+
138+
publish:
139+
needs: [build, checksum]
140+
runs-on: ubuntu-latest
141+
timeout-minutes: 5
142+
143+
permissions:
144+
contents: write # for gh release upload
145+
id-token: write # for actions/attest-build-provenance
146+
attestations: write # for actions/attest-build-provenance
147+
148+
steps:
149+
- name: Download binary artifacts
150+
uses: actions/download-artifact@v4
151+
with:
152+
path: dist/
153+
pattern: go-httpbin-*
154+
merge-multiple: true
155+
156+
- name: Download checksum artifacts
157+
uses: actions/download-artifact@v4
158+
with:
159+
path: dist/
160+
pattern: checksum-*
161+
merge-multiple: true
162+
163+
- name: Check artifacts
164+
run: tree --charset ASCII dist/
165+
166+
- name: Publish artifacts
167+
if: startsWith(github.ref, 'refs/tags/')
168+
run: |-
169+
gh release upload "$(echo "${GITHUB_REF}" | sed -E 's!refs/tags/!!')" dist/* -R "${GITHUB_REPOSITORY}"
170+
env:
171+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Makefile

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,21 @@ STATICCHECK := go run honnef.co/go/tools/cmd/staticcheck@2025.1.1
2121
HOST ?= 127.0.0.1
2222
PORT ?= 8080
2323

24+
# Determine the name of the static binary for the release build
25+
GOOS ?= $(shell go env GOOS)
26+
GOARCH ?= $(shell go env GOARCH)
27+
ifeq (x$(GOOS)x,xwindowsx)
28+
GOENVS ?= GOOS=$(GOOS) GOARCH=$(GOARCH)
29+
BINNAME ?= go-httpbin-$(GOOS)-$(GOARCH).exe
30+
else
31+
ifeq (x$(GOARCH)x,xarmx)
32+
GOENVS ?= GOOS=$(GOOS) GOARCH=$(GOARCH) GOARM=$(GOARM)
33+
BINNAME ?= go-httpbin-$(GOOS)-$(GOARCH)v$(GOARM)
34+
else
35+
GOENVS ?= GOOS=$(GOOS) GOARCH=$(GOARCH)
36+
BINNAME ?= go-httpbin-$(GOOS)-$(GOARCH)
37+
endif
38+
endif
2439

2540
# =============================================================================
2641
# build
@@ -99,3 +114,11 @@ imagepush:
99114
docker buildx build --push --platform linux/amd64,linux/arm64 -t $(DOCKER_TAG) .
100115
docker buildx rm httpbin
101116
.PHONY: imagepush
117+
118+
# =============================================================================
119+
# release build
120+
# =============================================================================
121+
release:
122+
mkdir -p $(DIST_PATH)
123+
CGO_ENABLED=0 $(GOENVS) go build -trimpath -ldflags '-s -w -buildid=' -o $(DIST_PATH)/$(BINNAME) ./cmd/go-httpbin
124+
.PHONY: release

0 commit comments

Comments
 (0)