Files
clawgo/.github/workflows/release.yml
2026-03-12 20:26:16 +08:00

236 lines
7.4 KiB
YAML

name: release
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
tag:
description: 'Release tag (e.g. v1.2.3). If empty, uses current ref name.'
required: false
type: string
build_targets:
description: 'Space-separated GOOS/GOARCH targets. Leave empty to use Makefile defaults.'
required: false
type: string
channel_variants:
description: 'Space-separated package variants. Leave empty to use full none and all single-channel variants.'
required: false
type: string
permissions:
contents: write
jobs:
prepare-release:
runs-on: ubuntu-latest
outputs:
raw_tag: ${{ steps.prepare.outputs.raw_tag }}
version: ${{ steps.prepare.outputs.version }}
targets_json: ${{ steps.prepare.outputs.targets_json }}
channel_variants: ${{ steps.prepare.outputs.channel_variants }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Resolve release inputs
id: prepare
shell: bash
run: |
set -euo pipefail
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ -n "${{ inputs.tag }}" ]; then
raw_tag="${{ inputs.tag }}"
elif [[ "${GITHUB_REF}" == refs/tags/* ]]; then
raw_tag="${GITHUB_REF_NAME}"
else
raw_tag="$(git describe --tags --always --dirty 2>/dev/null || echo dev)"
fi
build_targets="${{ inputs.build_targets || '' }}"
channel_variants="${{ inputs.channel_variants || '' }}"
if [ -z "$build_targets" ]; then
build_targets="linux/amd64 linux/arm64 linux/riscv64 darwin/amd64 darwin/arm64 windows/amd64 windows/arm64"
fi
if [ -z "$channel_variants" ]; then
channel_variants="full none telegram discord feishu maixcam qq dingtalk whatsapp"
fi
version="${raw_tag#v}"
targets_json="$(python3 -c 'import json, sys; print(json.dumps(sys.argv[1].split()))' "$build_targets")"
echo "raw_tag=$raw_tag" >> "$GITHUB_OUTPUT"
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "targets_json=$targets_json" >> "$GITHUB_OUTPUT"
echo "channel_variants=$channel_variants" >> "$GITHUB_OUTPUT"
echo "Build version: $version (from $raw_tag)"
echo "Targets: $build_targets"
echo "Variants: $channel_variants"
prepare-go-cache:
needs: prepare-release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Go
shell: bash
run: |
set -euo pipefail
go_version="$(awk '/^go / {print $2; exit}' go.mod)"
arch="$(dpkg --print-architecture)"
case "$arch" in
amd64) go_arch="amd64" ;;
arm64) go_arch="arm64" ;;
*)
echo "Unsupported runner architecture for Go install: $arch" >&2
exit 1
;;
esac
curl -fsSL "https://go.dev/dl/go${go_version}.linux-${go_arch}.tar.gz" -o /tmp/go.tgz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf /tmp/go.tgz
echo "/usr/local/go/bin" >> "$GITHUB_PATH"
/usr/local/go/bin/go version
- name: Warm Go module cache
shell: bash
run: |
set -euo pipefail
mkdir -p /tmp/go-cache
go mod download
GOMODCACHE="$(go env GOMODCACHE)"
tar -C "$GOMODCACHE" -czf /tmp/go-cache/gomodcache.tar.gz .
- name: Upload Go module cache
uses: actions/upload-artifact@v4
with:
name: go-mod-cache
path: /tmp/go-cache/gomodcache.tar.gz
if-no-files-found: error
build-and-package:
needs:
- prepare-release
- prepare-go-cache
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
target: ${{ fromJson(needs.prepare-release.outputs.targets_json) }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Go
shell: bash
run: |
set -euo pipefail
go_version="$(awk '/^go / {print $2; exit}' go.mod)"
arch="$(dpkg --print-architecture)"
case "$arch" in
amd64) go_arch="amd64" ;;
arm64) go_arch="arm64" ;;
*)
echo "Unsupported runner architecture for Go install: $arch" >&2
exit 1
;;
esac
curl -fsSL "https://go.dev/dl/go${go_version}.linux-${go_arch}.tar.gz" -o /tmp/go.tgz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf /tmp/go.tgz
echo "/usr/local/go/bin" >> "$GITHUB_PATH"
/usr/local/go/bin/go version
- name: Download Go module cache
uses: actions/download-artifact@v4
with:
name: go-mod-cache
path: /tmp/go-cache
- name: Restore Go module cache
shell: bash
run: |
set -euo pipefail
GOMODCACHE="$(go env GOMODCACHE)"
mkdir -p "$GOMODCACHE"
tar -C "$GOMODCACHE" -xzf /tmp/go-cache/gomodcache.tar.gz
- name: Install packaging tools
run: |
sudo apt-get update
sudo apt-get install -y zip
- name: Resolve matrix target
id: target
shell: bash
run: |
set -euo pipefail
target="${{ matrix.target }}"
goos="${target%/*}"
goarch="${target#*/}"
echo "goos=$goos" >> "$GITHUB_OUTPUT"
echo "goarch=$goarch" >> "$GITHUB_OUTPUT"
echo "artifact_name=release-$goos-$goarch" >> "$GITHUB_OUTPUT"
- name: Build and package matrix artifacts
shell: bash
run: |
set -euo pipefail
make clean
make package-all \
VERSION="${{ needs.prepare-release.outputs.version }}" \
BUILD_TARGETS="${{ matrix.target }}" \
CHANNEL_PACKAGE_VARIANTS="${{ needs.prepare-release.outputs.channel_variants }}"
rm -f build/checksums.txt
- name: Upload matrix artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ steps.target.outputs.artifact_name }}
path: |
build/*.tar.gz
build/*.zip
if-no-files-found: error
publish-release:
needs:
- prepare-release
- build-and-package
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch'
steps:
- name: Download packaged artifacts
uses: actions/download-artifact@v4
with:
pattern: release-*
merge-multiple: true
path: build
- name: List downloaded artifacts
run: find build -maxdepth 2 -type f | sort
- name: Generate checksums
shell: bash
run: |
set -euo pipefail
cd build
if command -v sha256sum >/dev/null 2>&1; then
sha256sum *.tar.gz *.zip > checksums.txt
else
shasum -a 256 *.tar.gz *.zip > checksums.txt
fi
cat checksums.txt
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.prepare-release.outputs.raw_tag }}
name: ${{ needs.prepare-release.outputs.raw_tag }}
generate_release_notes: true
files: |
build/*.tar.gz
build/*.zip
build/checksums.txt