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
14 changes: 14 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@ jobs:
make tidy
git diff --exit-code -- go.mod go.sum

platforms:
name: builds for every platform
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
# The same script the release runs, so a tag is never the first time a
# target is built.
- run: ./scripts/build-release.sh dev dist
- name: the checksums match the files
run: cd dist && sha256sum -c SHA256SUMS

race:
name: race detector
runs-on: ubuntu-latest
Expand Down
38 changes: 38 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,41 @@ jobs:
fi

gh release create "$TAG" --verify-tag --title "$TAG" "${notes[@]}" "${flags[@]}"

binaries:
name: publish binaries
# Archives for every platform, for hosts with no Docker and no Go: Windows
# servers, 32-bit ARM, FreeBSD. After the release page exists, because they
# are attached to it.
needs: release
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod

- name: Build every platform
env:
TAG: ${{ github.ref_name }}
run: ./scripts/build-release.sh "${TAG#v}" dist

# A binary that does not report the tag was not stamped with it, and
# would be published as a release it is not.
- name: The Linux build reports this release
env:
TAG: ${{ github.ref_name }}
run: |
tar -xzf "dist/certpilot-agent_${TAG#v}_linux_amd64.tar.gz" -C "$RUNNER_TEMP"
got=$("$RUNNER_TEMP/certpilot-agent_${TAG#v}_linux_amd64/certpilot-agent" version)
[ "$got" = "${TAG#v}" ] || { echo "binary says $got, tag is $TAG"; exit 1; }

- name: Attach them to the release
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ github.ref_name }}
# --clobber so re-running a tag's workflow replaces its files.
run: gh release upload "$TAG" dist/* --clobber
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ the key does not, and there is no code path that would let it.
go install github.com/certpilot/certpilot-agent/cmd@latest
```

No Go or Docker on the host? Each [release](https://github.com/certpilot/certpilot-agent/releases)
has a static binary for Linux (amd64, arm64, armv7, 386), Windows (amd64, arm64),
macOS and FreeBSD, with a `SHA256SUMS` file to check it against.

```
docker run --rm -v certpilot-agent:/var/lib/certpilot-agent \
ghcr.io/certpilot/agent:latest --help
Expand Down
62 changes: 62 additions & 0 deletions scripts/build-release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/usr/bin/env bash
#
# Build the agent for every platform it is released for.
#
# ./scripts/build-release.sh 0.2.4 dist stamp 0.2.4, write archives to dist/
# ./scripts/build-release.sh dev dist unstamped, as CI builds it
#
# One script for CI and for the release, so a tag is never the first time a
# target is built. Each target is a static binary (CGO off) in an archive with
# the licence and README, and SHA256SUMS lists them all.
#
set -euo pipefail

cd "$(dirname "$0")/.."

version="${1:?usage: build-release.sh VERSION OUTDIR}"
out="${2:?usage: build-release.sh VERSION OUTDIR}"

# os/arch[/goarm]
targets=(
linux/amd64 linux/arm64 linux/arm/7 linux/386
windows/amd64 windows/arm64
darwin/amd64 darwin/arm64
freebsd/amd64
)

# An unstamped build keeps the -dev default compiled into the source, rather
# than claiming a release number it is not.
ldflags="-s -w"
if [ "$version" != dev ]; then
ldflags="$ldflags -X github.com/certpilot/certpilot-agent.Version=$version"
fi

rm -rf "$out"
mkdir -p "$out"
out="$(cd "$out" && pwd)"
work="$(mktemp -d)"
trap 'rm -rf "$work"' EXIT

for target in "${targets[@]}"; do
IFS=/ read -r goos goarch goarm <<<"$target"
name="certpilot-agent_${version}_${goos}_${goarch}${goarm:+v$goarm}"
bin=certpilot-agent
[ "$goos" = windows ] && bin=certpilot-agent.exe

dir="$work/$name"
mkdir -p "$dir"
CGO_ENABLED=0 GOOS="$goos" GOARCH="$goarch" GOARM="${goarm:-}" \
go build -trimpath -ldflags="$ldflags" -o "$dir/$bin" ./cmd/
cp LICENSE README.md "$dir/"

if [ "$goos" = windows ]; then
(cd "$work" && zip -qr "$out/$name.zip" "$name")
else
tar -C "$work" -czf "$out/$name.tar.gz" "$name"
fi
echo "built $name"
done

sum() { if command -v sha256sum >/dev/null; then sha256sum "$@"; else shasum -a 256 "$@"; fi; }
(cd "$out" && sum certpilot-agent_* > SHA256SUMS)
echo "wrote $(ls "$out" | wc -l | tr -d ' ') files to $out"
Loading