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
63 changes: 62 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ permissions:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# Superseded PR pushes are safe to cancel, but a master run may be midway
# through publishing a release, so let those finish.
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}

jobs:
test:
Expand Down Expand Up @@ -50,3 +52,62 @@ jobs:
GOARCH: ${{ matrix.goarch }}
CGO_ENABLED: "0"
run: go build -o /dev/null ./apps/...

# Master only: package the release tarballs, attach them to the run, and cut a
# GitHub release the first time a given version const reaches master.
dist:
needs: [ test, build ]
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4

- uses: actions/setup-go@v5
with:
go-version-file: go.mod

# Produces dist/nsq-<version>.linux-<arch>.go<x.y.z>.tar.gz, each holding
# bin/ so it unpacks over a prefix with `tar --strip-components=1`.
# Tests and the docker image are skipped: the jobs above already covered
# the former, and nothing here consumes the latter.
- name: package tarballs
env:
DIST_OS: linux
DIST_ARCH: amd64 arm64
DIST_TESTS: "0"
DIST_DOCKER: "0"
run: ./dist.sh

- name: read version
id: meta
run: |
version="$(awk '/const Binary/ {print $NF}' internal/version/binary.go | tr -d '"')"
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "tag=v$version" >> "$GITHUB_OUTPUT"

- uses: actions/upload-artifact@v4
with:
name: nsq-${{ steps.meta.outputs.version }}
path: dist/*.tar.gz
if-no-files-found: error
retention-days: 90

# Idempotent, so merging to master without touching
# internal/version/binary.go leaves the existing release alone. Bump the
# version const to cut a new one.
- name: publish release
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ steps.meta.outputs.tag }}
run: |
if gh release view "$TAG" >/dev/null 2>&1; then
echo "release $TAG already exists, leaving it untouched"
exit 0
fi
gh release create "$TAG" \
--target "$GITHUB_SHA" \
--title "$TAG" \
--notes "Built from ${GITHUB_SHA} by the ${GITHUB_WORKFLOW} workflow." \
dist/*.tar.gz
50 changes: 37 additions & 13 deletions dist.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#!/bin/bash

# The dist job in .github/workflows/ci.yml calls this script on every push to
# master to package the linux tarballs and publish them, so the steps below are
# only needed for a full local build across every platform.
#
# 1. commit to bump the version and update the changelog/readme
# 2. tag that commit
# 3. use dist.sh to produce tar.gz for linux and darwin
Expand All @@ -16,38 +20,58 @@
set -e

DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# Overridable so CI can package just the platforms it publishes, and skip the
# work it has already done. The defaults reproduce a full local release build.
DIST_OS="${DIST_OS:-linux darwin freebsd windows}"
DIST_ARCH="${DIST_ARCH:-$(go env GOARCH)}"
DIST_TESTS="${DIST_TESTS:-1}"
DIST_DOCKER="${DIST_DOCKER:-1}"

rm -rf $DIR/dist/docker
mkdir -p $DIR/dist/docker
dep ensure

BLDFLAGS='-ldflags="-s -w"'
arch=$(go env GOARCH)
version=$(awk '/const Binary/ {print $NF}' < $DIR/internal/version/binary.go | sed 's/"//g')
goversion=$(go version | awk '{print $3}')

echo "... running tests"
./test.sh
# Record the archived files as root-owned without needing to chown them first,
# which keeps this script runnable without sudo. GNU tar and the bsdtar that
# ships with macOS spell these flags differently.
if tar --version 2>/dev/null | grep -q '^tar (GNU tar)'; then
TAROWNER=(--numeric-owner --owner=0 --group=0)
else
TAROWNER=(--numeric-owner --uid 0 --gid 0 --uname root --gname root)
fi

for os in linux darwin freebsd windows; do
if [ "$DIST_TESTS" == "1" ]; then
echo "... running tests"
./test.sh
fi

for os in $DIST_OS; do
for arch in $DIST_ARCH; do
echo "... building v$version for $os/$arch"
BUILD=$(mktemp -d ${TMPDIR:-/tmp}/nsq-XXXXX)
TARGET="nsq-$version.$os-$arch.$goversion"
GOOS=$os GOARCH=$arch CGO_ENABLED=0 \
make DESTDIR=$BUILD PREFIX=/$TARGET BLDFLAGS="$BLDFLAGS" install
pushd $BUILD
if [ "$os" == "linux" ]; then
if [ "$os" == "linux" ] && [ "$arch" == "amd64" ]; then
cp -r $TARGET/bin $DIR/dist/docker/
fi
sudo chown -R 0:0 $TARGET
tar czvf $TARGET.tar.gz $TARGET
tar "${TAROWNER[@]}" -czf $TARGET.tar.gz $TARGET
mv $TARGET.tar.gz $DIR/dist
popd
make clean
sudo rm -r $BUILD
rm -r $BUILD
done
done

docker build -t nsqio/nsq:v$version .
if [[ ! $version == *"-"* ]]; then
echo "Tagging nsqio/nsq:v$version as the latest release."
docker tag -f nsqio/nsq:v$version nsqio/nsq:latest
if [ "$DIST_DOCKER" == "1" ]; then
docker build -t nsqio/nsq:v$version .
if [[ ! $version == *"-"* ]]; then
echo "Tagging nsqio/nsq:v$version as the latest release."
docker tag nsqio/nsq:v$version nsqio/nsq:latest
fi
fi
Loading