Skip to content

Release

Release #26

Workflow file for this run

# Copyright (c) 2024 Hemi Labs, Inc.
# Use of this source code is governed by the MIT License,
# which can be found in the LICENSE file.
# GitHub Actions workflow to create releases.
# Releases are published from tags matching "v*.*.*".
name: "Release"
on:
push:
tags: [ "v*.*.*" ]
workflow_dispatch:
inputs:
version:
description: "Version"
type: string
required: true
docker:
description: "Build Docker images"
type: boolean
required: true
default: false
npm:
description: "Publish NPM packages"
type: boolean
required: true
default: false
release:
description: "Create GitHub release and publish Docker images"
type: boolean
required: true
default: false
concurrency:
group: "release-${{ github.ref }}"
cancel-in-progress: true
env:
GO_VERSION: "1.22.x"
PNPM_VERSION: "9.4.x"
GO_LDFLAGS: >-
-X 'github.com/hemilabs/heminetwork/version.Brand=Hemi Labs'
-X github.com/hemilabs/heminetwork/version.PreRelease=
jobs:
# Run tests
# TODO(joshuasing): run PoP Miner / NPM package tests once added
test:
name: "Test"
uses: ./.github/workflows/go.yml
# Prepare to release
prepare:
name: "Prepare"
runs-on: "ubuntu-latest"
permissions:
contents: read
outputs:
version: "${{ steps.version.outputs.version }}"
tag: "${{ steps.version.outputs.tag }}"
version_type: "${{ steps.version.outputs.type }}"
steps:
- name: "Determine version type"
id: version
env:
RAW_VERSION: "${{ inputs.version || github.ref_name }}"
# This script determines the version type (stability), e.g.
# 1.0.0 = stable, 1.1.0-rc.1 = unstable, 0.1.0 = unstable
run: |
VERSION=$(echo "$RAW_VERSION" | sed -e 's/^v//')
TAG=$(echo "$RAW_VERSION" | sed -E 's/^([^v])/v\1/g')
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
TYPE=unstable
if echo "$VERSION" | grep -Eq '^[1-9][0-9]*\.[0-9]+\.[0-9]+$'; then
TYPE=stable
fi
echo "Detected that $TAG is $TYPE"
echo "type=$TYPE" >> "$GITHUB_OUTPUT"
# Build binaries
build:
name: "Build (${{ matrix.goos }}/${{ matrix.goarch }})"
runs-on: "ubuntu-latest"
needs: [ "test", "prepare" ]
permissions:
contents: read
strategy:
fail-fast: true
matrix:
goos: [ "linux", "darwin" ]
goarch: [ "amd64", "arm64" ]
include:
- goos: "windows"
goarch: "amd64"
- goos: "openbsd"
goarch: "amd64"
steps:
- name: "Checkout repository"
uses: actions/checkout@v4
- name: "Setup Go ${{ env.GO_VERSION }}"
uses: actions/setup-go@v5
with:
go-version: "${{ env.GO_VERSION }}"
cache: true
check-latest: true
- name: "Download and verify dependencies"
run: make GOCACHE="$(go env GOCACHE)" go-deps
- name: "Create binary archive for ${{ matrix.goos }}/${{ matrix.goarch }}"
env:
GOOS: "${{ matrix.goos }}"
GOARCH: "${{ matrix.goarch }}"
CGO_ENABLED: 0 # Disable CGO.
GOGC: off # Disable GC during build, faster but uses more RAM.
GO_LDFLAGS: "${{ env.GO_LDFLAGS }}"
run: make GOCACHE="$(go env GOCACHE)" GO_LDFLAGS="$GO_LDFLAGS" archive
- name: "Upload artifacts"
uses: actions/upload-artifact@v4
with:
name: "${{ matrix.goos }}_${{ matrix.goarch }}"
retention-days: 1
path: |
dist/*
# Build and publish Docker images
docker:
name: "Docker (${{ matrix.service }})"
runs-on: "ubuntu-latest"
if: github.event_name == 'push' || inputs.docker
needs: [ "test", "prepare" ]
permissions:
contents: read
packages: write
strategy:
fail-fast: true
matrix:
include:
- service: "bfgd"
platforms: "linux/amd64,linux/arm64"
- service: "bssd"
platforms: "linux/amd64,linux/arm64"
- service: "popmd"
platforms: "linux/amd64,linux/arm64"
steps:
- name: "Checkout repository"
uses: actions/checkout@v4
- name: "Setup QEMU"
uses: docker/setup-qemu-action@v3
- name: "Setup Docker Buildx"
uses: docker/setup-buildx-action@v3
- name: "Login to DockerHub"
if: github.event_name == 'push' || inputs.release
uses: docker/login-action@v3
with:
username: "${{ secrets.DOCKERHUB_USERNAME }}"
password: "${{ secrets.DOCKERHUB_TOKEN }}"
- name: "Login to GitHub Container Registry"
if: github.event_name == 'push' || inputs.release
uses: docker/login-action@v3
with:
registry: ghcr.io
username: "${{ github.repository_owner }}"
password: "${{ secrets.GITHUB_TOKEN }}"
- name: "Prepare"
id: "prepare"
run: |
echo "build_date=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> "$GITHUB_OUTPUT"
- name: "Build and push"
uses: docker/build-push-action@v5
with:
context: "${{ github.workspace }}"
platforms: "${{ matrix.platforms }}"
file: "${{ github.workspace }}/docker/${{ matrix.service }}/Dockerfile"
push: "${{ github.event_name == 'push' || inputs.release }}"
build-args: |
VERSION=${{ needs.prepare.outputs.version }}
VCS_REF=${{ github.sha }}
BUILD_DATE=${{ steps.prepare.outputs.build_date }}
GO_LDFLAGS=${{ env.GO_LDFLAGS }}
tags: |
hemilabs/${{ matrix.service }}:latest
hemilabs/${{ matrix.service }}:${{ needs.prepare.outputs.tag }}
ghcr.io/hemilabs/${{ matrix.service }}:latest
ghcr.io/hemilabs/${{ matrix.service }}:${{ needs.prepare.outputs.tag }}
# Publish NPM packages
npm:
name: "npm"
runs-on: "ubuntu-latest"
if: github.event_name == 'push' || inputs.npm
needs: [ "prepare" ]
permissions:
contents: read
steps:
- name: "Checkout repository"
uses: actions/checkout@v4
- name: "Setup Go ${{ env.GO_VERSION }}"
uses: actions/setup-go@v5
with:
go-version: "${{ env.GO_VERSION }}"
cache: true
check-latest: true
- name: "Setup pnpm ${{ env.PNPM_VERSION }}"
uses: pnpm/action-setup@v4
with:
version: "${{ env.PNPM_VERSION }}"
- name: "Setup Node"
uses: actions/setup-node@v4
with:
node-version-file: "web/.nvmrc"
check-latest: true
cache: "pnpm"
cache-dependency-path: "web/**/pnpm-lock.yaml"
registry-url: "https://registry.npmjs.org"
- name: "Install dependencies"
working-directory: "web/"
run: pnpm install --frozen-lockfile
- name: "Install Go dependencies"
working-directory: "web/"
run: make deps
- name: "Set package.json versions"
working-directory: "web/"
env:
VERSION: "${{ needs.prepare.outputs.version }}"
run: |
# Prints all package.json files
PACKAGE_FILES=$(find . -path '**/node_modules' -prune -o -name 'package.json' -print)
for file in $PACKAGE_FILES; do
# Set "version" in package.json file to $VERSION.
TMP_FILE="$(mktemp)"
jq --arg v "$VERSION" '.version = $v' "$file" > "$TMP_FILE"
mv "$TMP_FILE" "$file"
done
# TODO(joshuasing): Install and use binaryen
- name: "Build @hemilabs/pop-miner WebAssembly binary"
working-directory: "web/"
run: make wasm
- name: "Build @hemilabs/pop-miner package"
working-directory: "web/"
run: pnpm build:pop-miner
- name: "Publish @hemilabs/pop-miner package"
working-directory: "web/"
run: pnpm publish packages/pop-miner --access public --no-git-checks
env:
NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}"
# Create GitHub Release
release:
name: "Release"
runs-on: "ubuntu-latest"
needs: [ "prepare", "build", "docker", "npm" ]
permissions:
# Permission to write contents is required to create GitHub releases.
# Builds are performed in a separate job with more restrictive permissions
# because this permission allows any action to write to the repository.
contents: write
steps:
- name: "Checkout repository"
uses: actions/checkout@v4
- name: "Create sources archive"
run: make sources
- name: "Download build artifacts"
uses: actions/download-artifact@v4
with:
pattern: "*_*"
path: "${{ github.workspace }}/dist/"
merge-multiple: true
- name: "Create checksums"
run: make checksums
- name: "Create GitHub release"
if: github.event_name == 'push' || inputs.release
env:
TAG: "${{ github.ref_name || needs.prepare.outputs.tag }}"
PRERELEASE: "${{ needs.prepare.outputs.version_type == 'unstable' }}"
GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
# Creates a GitHub release using the 'gh' CLI (https://github.com/cli/cli).
# Release notes will be generated by GitHub using the config at .github/release.yml.
run: |
gh release create "$TAG" ./dist/* --generate-notes --prerelease=$PRERELEASE