Skip to content

Commit 4fc9180

Browse files
Merge updated CI
Squashed commit of the following: commit 4dac7db79049eb28d1efcdb31154b3f7e86fd792 Author: Killian Meersman <hi@killianm.dev> Date: Fri Apr 4 14:57:36 2025 +0200 Update release CI commit 9f03853 Author: Killian Meersman <hi@killianm.dev> Date: Fri Apr 4 14:52:19 2025 +0200 WIP multi-arch CI
1 parent 1c77e8c commit 4fc9180

File tree

6 files changed

+220
-22
lines changed

6 files changed

+220
-22
lines changed

.github/workflows/container.yaml

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,60 @@ on:
44
push:
55
branches:
66
- dev
7+
- ci
8+
tags:
9+
- v*
710

811
jobs:
9-
build:
10-
runs-on: ubuntu-latest
11-
permissions:
12-
packages: write
13-
contents: read
14-
steps:
15-
- uses: actions/checkout@v4
16-
- name: Setup Go
17-
uses: actions/setup-go@v5
18-
with:
19-
go-version: 1.23
20-
- name: Test
21-
run: make test
22-
- name: Log in to Github registry
23-
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
24-
- name: Push image
25-
run: TAG=${{ github.ref_name }} make publish
12+
# Build multi-arch image.
13+
build_container:
14+
runs-on: ubuntu-latest
15+
permissions:
16+
packages: write
17+
contents: read
18+
attestations: write
19+
id-token: write
20+
env:
21+
REGISTRY: ghcr.io
22+
IMAGE_NAME: ${{ github.repository }}
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v4
26+
- name: Set up QEMU
27+
uses: docker/setup-qemu-action@v3
28+
- name: Set up Docker Buildx
29+
uses: docker/setup-buildx-action@v3
30+
31+
- name: Docker meta
32+
id: meta
33+
uses: docker/metadata-action@v5
34+
with:
35+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
36+
tags: |
37+
type=ref,event=branch
38+
type=ref,event=pr
39+
type=semver,pattern={{version}}
40+
type=semver,pattern={{major}}.{{minor}}
41+
42+
- name: Log in to the Github Container registry
43+
uses: docker/login-action@v2
44+
with:
45+
registry: ghcr.io
46+
username: ${{ github.actor }}
47+
password: ${{ secrets.GITHUB_TOKEN }}
48+
49+
- name: Build and push
50+
uses: docker/build-push-action@v6
51+
id: push
52+
with:
53+
push: true
54+
tags: ${{ steps.meta.outputs.tags }}
55+
labels: ${{ steps.meta.outputs.labels }}
56+
platforms: linux/arm/v7,linux/arm64/v8,linux/arm64,linux/amd64
57+
58+
- name: Generate artifact attestation
59+
uses: actions/attest-build-provenance@v2
60+
with:
61+
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
62+
subject-digest: ${{ steps.push.outputs.digest }}
63+
push-to-registry: true

.github/workflows/release.yaml

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
name: Create release
2+
run-name: Release ${{ github.ref_name }}
3+
on:
4+
push:
5+
tags:
6+
- v
7+
8+
jobs:
9+
build_windows_binaries:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
- uses: actions/setup-go@v5
14+
with:
15+
go-version: '^1.23.0'
16+
- run: |
17+
GOOS=windows GOARCH=amd64 go build -buildvcs=false -o dist/chaperone_windows_x64.exe
18+
GOOS=windows GOARCH=386 go build -buildvcs=false -o dist/chaperone_windows_x32.exe
19+
- name: 'Upload build artifacts'
20+
uses: actions/upload-artifact@v4
21+
with:
22+
name: windows-builds
23+
path: dist/*
24+
retention-days: 3
25+
26+
build_mac_binaries:
27+
runs-on: ubuntu-latest
28+
steps:
29+
- uses: actions/checkout@v4
30+
- uses: actions/setup-go@v5
31+
with:
32+
go-version: '^1.23.0'
33+
- run: |
34+
GOOS=darwin GOARCH=amd64 go build -buildvcs=false -o dist/chaperone_darwin_x64
35+
GOOS=darwin GOARCH=arm64 go build -buildvcs=false -o dist/chaperone_mac_arm64
36+
- name: 'Upload build artifacts'
37+
uses: actions/upload-artifact@v4
38+
with:
39+
name: mac-builds
40+
path: dist/*
41+
retention-days: 3
42+
43+
build_linux_binaries:
44+
runs-on: ubuntu-latest
45+
steps:
46+
- uses: actions/checkout@v4
47+
- uses: actions/setup-go@v5
48+
with:
49+
go-version: '^1.23.0'
50+
- run: |
51+
GOOS=linux GOARCH=amd64 go build -buildvcs=false -o dist/chaperone_linux_x64
52+
GOOS=linux GOARCH=386 go build -buildvcs=false -o dist/chaperone_linux_x32
53+
- name: 'Upload build artifacts'
54+
uses: actions/upload-artifact@v4
55+
with:
56+
name: linux-builds
57+
path: dist/*
58+
retention-days: 3
59+
60+
github_release:
61+
runs-on: ubuntu-latest
62+
permissions:
63+
contents: write
64+
needs:
65+
- build_windows_binaries
66+
- build_mac_binaries
67+
- build_linux_binaries
68+
steps:
69+
- name: Download all workflow run artifacts
70+
uses: actions/download-artifact@v4
71+
- uses: ncipollo/release-action@v1
72+
with:
73+
artifacts: "windows-builds/*,mac-builds/*,linux-builds/*"
74+
allowUpdates: true
75+
makeLatest: true
76+
prerelease: false
77+
replacesArtifacts: true
78+
artifactErrorsFailBuild: true
79+
generateReleaseNotes: true

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Build artifacts
2+
dist/

Dockerfile

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
FROM golang:1-alpine AS builder
1+
FROM --platform=$BUILDPLATFORM golang:1-alpine AS builder
2+
3+
# Default BuildKit arguments, need to be defined as ARG to be useable in the Dockerfile.
4+
# See https://www.docker.com/blog/faster-multi-platform-builds-dockerfile-cross-compilation-guide/
5+
ARG TARGETOS
6+
ARG TARGETARCH
27

38
LABEL org.opencontainers.image.source=https://github.com/KillianMeersman/chaperone
49
LABEL org.opencontainers.image.description="A rate-limiting & caching forward HTTP proxy."
@@ -8,15 +13,17 @@ WORKDIR /app
813
ENV GOCACHE=/app/.gocache
914

1015
COPY . .
11-
RUN --mount=type=cache,id=gocache,target=/app/.gocache,sharing=locked go build -o chaperone ./cmd/chaperone/main.go
16+
17+
RUN --mount=type=cache,id=gocache,target=/app/.gocache,sharing=private \
18+
GOOS="$TARGETOS" GOARCH="$TARGETARCH" go build -o chaperone ./cmd/chaperone/main.go
1219
RUN chmod +x chaperone
1320

1421
FROM alpine:3 AS main
1522

1623
WORKDIR /app
1724
COPY --from=builder /app/chaperone chaperone
1825

19-
RUN adduser --disabled-password user
20-
USER user:user
26+
RUN adduser --disabled-password chaperone
27+
USER chaperone:chaperone
2128

2229
ENTRYPOINT [ "/app/chaperone" ]

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fuzz: vendor
2424

2525
build: vendor vet test
2626
mkdir dist || true
27-
go build -o dist/$(TARGET) ./cmd/$(TARGET)/main.go
27+
go build -o dist/chaperone ./cmd/chaperone/main.go
2828

2929
container:
3030
docker build -t $(CONTAINER):$(TAG) .

release.sh

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#!/bin/bash
2+
3+
if [ $# -lt 1 ]; then
4+
echo "Please provide a semantic version, 'major', 'minor' or 'patch'"
5+
exit 1
6+
fi
7+
8+
9+
NEW_VERSION="$1"
10+
TAG_COMMIT='HEAD'
11+
12+
# Fetch existing tags before choosing what the next one should be.
13+
echo 'Fetching existing tags...'
14+
git fetch --tags
15+
16+
# Parse major, minor and patch groups of latest tag.
17+
LATEST_RELEASE_TAG=$(git tag | grep -iE 'v.*' | sort -V | tail -n 1)
18+
if [[ -z "${LATEST_RELEASE_TAG}" ]]; then
19+
echo "No release tags found. Please create an initial release tag first."
20+
exit 1
21+
fi
22+
23+
NEW_RELEASE_MAJOR=$(echo ${LATEST_RELEASE_TAG//v} | cut -d. -f 1)
24+
NEW_RELEASE_MINOR=$(echo ${LATEST_RELEASE_TAG//v} | cut -d. -f 2)
25+
NEW_RELEASE_PATCH=$(echo ${LATEST_RELEASE_TAG//v} | cut -d. -f 3)
26+
27+
# Set the major, minor and patch groups of the new tag.
28+
if [[ "${NEW_VERSION}" == 'major' ]]; then
29+
NEW_RELEASE_MAJOR=$(($NEW_RELEASE_MAJOR + 1))
30+
NEW_RELEASE_MINOR='0'
31+
NEW_RELEASE_PATCH='0'
32+
elif [[ "${NEW_VERSION}" == 'minor' ]]; then
33+
NEW_RELEASE_MINOR=$(($NEW_RELEASE_MINOR + 1))
34+
NEW_RELEASE_PATCH='0'
35+
elif [[ "${NEW_VERSION}" == 'patch' ]]; then
36+
NEW_RELEASE_PATCH=$(($NEW_RELEASE_PATCH + 1))
37+
elif [[ "${NEW_VERSION}" =~ v.*\..*\..* ]]; then
38+
NEW_RELEASE_MAJOR=$(echo ${NEW_VERSION//v} | cut -d. -f 1)
39+
NEW_RELEASE_MINOR=$(echo ${NEW_VERSION//v} | cut -d. -f 2)
40+
NEW_RELEASE_PATCH=$(echo ${NEW_VERSION//v} | cut -d. -f 3)
41+
else
42+
echo "Invalid argument. Please provide a semantic version, 'major', 'minor' or 'patch'"
43+
exit 1
44+
fi
45+
46+
# Construct the new release tag.
47+
echo "Latest release tag is '${LATEST_RELEASE_TAG}'"
48+
NEW_RELEASE="v${NEW_RELEASE_MAJOR}.${NEW_RELEASE_MINOR}.${NEW_RELEASE_PATCH}"
49+
echo "Creating release '${NEW_RELEASE}'"
50+
51+
# Construct the tag message.
52+
# If the tag message is empty, use the default message.
53+
TAG_MESSAGE_FILE=$(mktemp)
54+
TAG_MESSAGE_HEADER="Version ${NEW_RELEASE_MAJOR}.${NEW_RELEASE_MINOR}.${NEW_RELEASE_PATCH}"
55+
TAG_MESSAGE_CHANGES=$(git log --pretty=format:"- %s" -n 20 "${LATEST_RELEASE_TAG}..${TAG_COMMIT}")
56+
57+
echo "${TAG_MESSAGE_HEADER}" > "${TAG_MESSAGE_FILE}"
58+
echo '' >> "${TAG_MESSAGE_FILE}"
59+
echo "Commits since ${LATEST_RELEASE_TAG}:" >> "${TAG_MESSAGE_FILE}"
60+
echo "${TAG_MESSAGE_CHANGES}" >> "${TAG_MESSAGE_FILE}"
61+
${EDITOR} "${TAG_MESSAGE_FILE}"
62+
63+
git tag -a "${NEW_RELEASE}" -F "${TAG_MESSAGE_FILE}" "${TAG_COMMIT}"
64+
65+
while true; do
66+
read -p "Release tag created, push, delete or keep? [${bold}P${normal}ush/${bold}K${normal}eep/${bold}D${normal}elete]: " choice
67+
case $choice in
68+
[Pp]*) git push origin ${NEW_RELEASE} ; break ;;
69+
[Kk]*) break ;;
70+
[Dd]*) git tag -d ${NEW_RELEASE} ; break ;;
71+
esac
72+
done

0 commit comments

Comments
 (0)