Skip to content

Keep runtime hydration repository neutral (#217) #180

Keep runtime hydration repository neutral (#217)

Keep runtime hydration repository neutral (#217) #180

Workflow file for this run

# Boatstack-owned control plane.
name: Release Boatstack helper
on:
push:
tags: ["v*"]
workflow_dispatch:
inputs:
prerelease_tag:
description: "New prerelease tag to publish from the selected branch (for example v2.0.0-rc.1)"
required: true
type: string
permissions:
contents: write
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- goos: linux
goarch: amd64
asset: boatstack-helper_linux_amd64
- goos: linux
goarch: arm64
asset: boatstack-helper_linux_arm64
- goos: darwin
goarch: amd64
asset: boatstack-helper_darwin_amd64
- goos: darwin
goarch: arm64
asset: boatstack-helper_darwin_arm64
- goos: windows
goarch: amd64
asset: boatstack-helper_windows_amd64.exe
- goos: windows
goarch: arm64
asset: boatstack-helper_windows_arm64.exe
steps:
- uses: actions/checkout@v7
- uses: actions/setup-go@v7
with:
go-version-file: boatstack/go.mod
cache-dependency-path: boatstack/go.mod
- name: Build native helper
shell: bash
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
CGO_ENABLED: "0"
ASSET: ${{ matrix.asset }}
VERSION: ${{ inputs.prerelease_tag || github.ref_name }}
run: |
source_commit="$(git rev-parse HEAD)"
mkdir -p dist
cd boatstack
go build -trimpath \
-ldflags "-s -w -X github.com/operatorstack/boatstack/boatstack/internal/buildinfo.Version=$VERSION -X github.com/operatorstack/boatstack/boatstack/internal/buildinfo.SourceCommit=$source_commit -X github.com/operatorstack/boatstack/boatstack/internal/buildinfo.ChecksumsSHA256=per-asset-sidecar" \
-o "../dist/$ASSET" ./cmd/boatstack-helper
cd ../dist
sha256sum "$ASSET" > "$ASSET.sha256"
- uses: actions/upload-artifact@v4
with:
name: ${{ matrix.asset }}
path: dist/${{ matrix.asset }}*
release:
if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch'
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true
- name: Publish release assets
env:
GH_TOKEN: ${{ github.token }}
RELEASE_TAG: ${{ inputs.prerelease_tag || github.ref_name }}
RELEASE_SOURCE: ${{ github.sha }}
MANUAL_PRERELEASE: ${{ github.event_name == 'workflow_dispatch' }}
shell: bash
run: |
if [[ "$MANUAL_PRERELEASE" == true ]]; then
[[ "$GITHUB_REF" == refs/heads/* ]] || {
echo "BLOCKED: manual prereleases must be dispatched from a branch" >&2
exit 2
}
[[ "$RELEASE_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$ ]] || {
echo "BLOCKED: manual release tags must use vMAJOR.MINOR.PATCH-rc.NUMBER" >&2
exit 2
}
if git ls-remote --exit-code --tags origin "refs/tags/$RELEASE_TAG" >/dev/null 2>&1; then
echo "BLOCKED: release tag $RELEASE_TAG already exists" >&2
exit 2
fi
remote_source="$(git ls-remote origin "refs/heads/$GITHUB_REF_NAME" | awk 'NR == 1 {print $1}')"
[[ -n "$remote_source" && "$remote_source" == "$RELEASE_SOURCE" ]] || {
echo "BLOCKED: selected branch no longer resolves to exact source $RELEASE_SOURCE" >&2
exit 2
}
fi
previous_tag="$(git describe --tags --abbrev=0 "${RELEASE_SOURCE}^" 2>/dev/null || true)"
if [[ -n "$previous_tag" ]]; then
rewritten_notes=()
while IFS= read -r note; do
rewritten_notes+=("$note")
done < <(git diff --name-only --diff-filter=MD --no-renames \
"$previous_tag" "$RELEASE_SOURCE" -- 'release-notes/*.md')
release_notes=()
while IFS= read -r note; do
release_notes+=("$note")
done < <(git diff --name-only --diff-filter=A --no-renames \
"$previous_tag" "$RELEASE_SOURCE" -- 'release-notes/*.md' | LC_ALL=C sort)
else
rewritten_notes=()
release_notes=()
while IFS= read -r note; do
release_notes+=("$note")
done < <(git ls-tree -r --name-only "$RELEASE_SOURCE" -- \
'release-notes/*.md' | LC_ALL=C sort)
fi
if (( ${#rewritten_notes[@]} > 0 )); then
echo "BLOCKED: Boatstack release notes are append-only:" >&2
printf ' %s\n' "${rewritten_notes[@]}" >&2
exit 1
fi
if (( ${#release_notes[@]} == 0 )); then
echo "BLOCKED: this tag contains no release-level Boatstack message." >&2
exit 1
fi
release_body="$(mktemp)"
{
echo "## What's in this release"
echo
for note in "${release_notes[@]}"; do
cat "$note"
echo
done
} > "$release_body"
if [[ "$MANUAL_PRERELEASE" == true ]]; then
gh release create "$RELEASE_TAG" dist/* \
--repo "$GITHUB_REPOSITORY" \
--target "$RELEASE_SOURCE" \
--title "$RELEASE_TAG" \
--notes-file "$release_body" \
--prerelease
else
gh release create "$RELEASE_TAG" dist/* \
--repo "$GITHUB_REPOSITORY" \
--notes-file "$release_body" \
--verify-tag
fi