build: add cross-platform release target, tea publish, and Gitea Actions release
release / release (push) Successful in 3m33s
release / release (push) Successful in 3m33s
- Makefile `release`: cross-compiles CGO-free static binaries for linux/amd64, linux/arm64, darwin/amd64, darwin/arm64, windows/amd64 into dist/, named emcli_<version>_<os>_<arch>[.exe] (matching skills/emcli/scripts/install.sh), plus a sha256 checksums.txt. VERSION is injected into internal/version.String. - Makefile `publish`: creates the Gitea release and uploads all dist/ assets via tea. - .gitea/workflows/release.yml: on a v* tag, build + publish via the Gitea API. - RELEASING.md: the local (make) and CI flows. Verified end-to-end: `make release VERSION=v0.4.0` builds all five assets with the version baked in; serving them locally, skills/emcli/scripts/install.sh downloads, passes checksum verification, and the installed binary reports v0.4.0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
# Builds cross-platform binaries and publishes a Gitea release when a version tag
|
||||
# (e.g. v0.4.0) is pushed. Produces the same assets as `make release` and uploads
|
||||
# them — so the skill installer (skills/emcli/scripts/install.sh) can fetch them.
|
||||
#
|
||||
# Requires: Gitea Actions enabled with a runner that has Go, make, curl, and jq
|
||||
# (the actions/checkout + actions/setup-go steps need the instance's Actions proxy).
|
||||
# This workflow has not been exercised against this repo's runners yet; if a step
|
||||
# is unavailable on your runner, the same result comes from `make release && make
|
||||
# publish` locally (see RELEASING.md).
|
||||
name: release
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
|
||||
- name: Build release artifacts
|
||||
run: make release VERSION="${GITHUB_REF_NAME}"
|
||||
|
||||
- name: Create release and upload assets
|
||||
env:
|
||||
TOKEN: ${{ github.token }}
|
||||
SERVER: ${{ github.server_url }}
|
||||
REPO: ${{ github.repository }}
|
||||
TAG: ${{ github.ref_name }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Create the release for the pushed tag.
|
||||
id=$(curl -fsSL -X POST \
|
||||
-H "Authorization: token ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${SERVER}/api/v1/repos/${REPO}/releases" \
|
||||
-d "{\"tag_name\":\"${TAG}\",\"name\":\"${TAG}\"}" | jq -r '.id')
|
||||
echo "release id: ${id}"
|
||||
# Upload every built asset (binaries + checksums.txt).
|
||||
for f in dist/*; do
|
||||
name=$(basename "$f")
|
||||
echo "uploading ${name}"
|
||||
curl -fsSL -X POST \
|
||||
-H "Authorization: token ${TOKEN}" \
|
||||
-F "attachment=@${f}" \
|
||||
"${SERVER}/api/v1/repos/${REPO}/releases/${id}/assets?name=${name}" >/dev/null
|
||||
done
|
||||
echo "published ${TAG}"
|
||||
@@ -1,12 +1,52 @@
|
||||
BINARY := emcli
|
||||
LDFLAGS := -s -w
|
||||
BINARY := emcli
|
||||
DIST := dist
|
||||
VERPKG := git.dcglab.co.uk/steve/emcli/internal/version
|
||||
|
||||
# VERSION defaults to the current git tag/description; override for a release:
|
||||
# make release VERSION=v0.4.0
|
||||
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo v0.0.0-dev)
|
||||
VER_NO_V := $(patsubst v%,%,$(VERSION))
|
||||
|
||||
LDFLAGS := -s -w -X $(VERPKG).String=$(VERSION)
|
||||
|
||||
# Platforms to cross-compile for a release. Must match skills/emcli/scripts/install.sh.
|
||||
PLATFORMS := linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64
|
||||
|
||||
.PHONY: build test vet release clean-dist publish
|
||||
|
||||
.PHONY: build test vet
|
||||
build:
|
||||
CGO_ENABLED=0 go build -ldflags "$(LDFLAGS)" -o $(BINARY) ./cmd/emcli
|
||||
CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o $(BINARY) ./cmd/emcli
|
||||
|
||||
test:
|
||||
go test ./...
|
||||
|
||||
vet:
|
||||
go vet ./...
|
||||
|
||||
# release cross-compiles a static binary per platform into dist/, named
|
||||
# emcli_<version>_<os>_<arch>[.exe], plus a checksums.txt of all assets.
|
||||
release: clean-dist
|
||||
@mkdir -p $(DIST)
|
||||
@for p in $(PLATFORMS); do \
|
||||
os=$${p%/*}; arch=$${p#*/}; ext=; \
|
||||
[ "$$os" = windows ] && ext=.exe; \
|
||||
out=$(DIST)/$(BINARY)_$(VER_NO_V)_$${os}_$${arch}$${ext}; \
|
||||
echo " building $$out"; \
|
||||
CGO_ENABLED=0 GOOS=$$os GOARCH=$$arch \
|
||||
go build -trimpath -ldflags "$(LDFLAGS)" -o $$out ./cmd/emcli || exit 1; \
|
||||
done
|
||||
@cd $(DIST) && { command -v sha256sum >/dev/null 2>&1 \
|
||||
&& sha256sum $(BINARY)_* > checksums.txt \
|
||||
|| shasum -a 256 $(BINARY)_* > checksums.txt; }
|
||||
@echo "release $(VERSION) artifacts in $(DIST)/:"
|
||||
@ls -1 $(DIST)
|
||||
|
||||
clean-dist:
|
||||
@rm -rf $(DIST)
|
||||
|
||||
# publish creates the Gitea release for $(VERSION) and uploads every dist asset.
|
||||
# Run `make release VERSION=vX.Y.Z` first. Requires the `tea` CLI to be logged in.
|
||||
publish:
|
||||
@test -d $(DIST) || { echo "no $(DIST)/ — run 'make release VERSION=$(VERSION)' first"; exit 1; }
|
||||
tea releases create --repo steve/emcli --tag $(VERSION) --title $(VERSION) \
|
||||
$(foreach a,$(wildcard $(DIST)/*),--asset $(a))
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# Releasing emcli
|
||||
|
||||
A release publishes one static binary per platform plus a `checksums.txt`, named so the agent skill
|
||||
installer (`skills/emcli/scripts/install.sh`) can fetch them:
|
||||
|
||||
```
|
||||
emcli_<version>_<os>_<arch>[.exe] e.g. emcli_0.4.0_linux_amd64
|
||||
checksums.txt sha256, one "<sum> <asset>" line per asset
|
||||
```
|
||||
|
||||
Platforms: `linux/amd64`, `linux/arm64`, `darwin/amd64`, `darwin/arm64`, `windows/amd64`. The binary
|
||||
is CGO-free, so cross-compilation needs only the Go toolchain.
|
||||
|
||||
## Option A — local (Makefile + tea)
|
||||
|
||||
```bash
|
||||
# 1. Build the artifacts into dist/ (version is injected into `emcli version`)
|
||||
make release VERSION=v0.4.0
|
||||
|
||||
# 2. Create the Gitea release for the tag and upload every dist/ asset
|
||||
make publish VERSION=v0.4.0
|
||||
```
|
||||
|
||||
`make publish` uses the `tea` CLI (already configured for this repo). It runs:
|
||||
|
||||
```
|
||||
tea releases create --repo steve/emcli --tag v0.4.0 --title v0.4.0 --asset dist/<each-file>
|
||||
```
|
||||
|
||||
Inspect `dist/` and `dist/checksums.txt` before publishing if you want to double-check.
|
||||
|
||||
## Option B — CI (Gitea Actions)
|
||||
|
||||
Push a version tag and let `.gitea/workflows/release.yml` build and publish:
|
||||
|
||||
```bash
|
||||
git tag v0.4.0
|
||||
git push origin v0.4.0 # (push via the tokenized HTTPS URL this repo uses)
|
||||
```
|
||||
|
||||
The workflow runs `make release` and uploads the assets to the release via the Gitea API. It needs
|
||||
Gitea Actions enabled with a runner that provides Go, make, curl, and jq. It hasn't been exercised
|
||||
against this repo's runners yet — if it doesn't fit your runner setup, fall back to Option A.
|
||||
|
||||
## After a release
|
||||
|
||||
The skill installer defaults to `EMCLI_VERSION=v0.4.0`. When you cut a different version, either
|
||||
publish under that tag or update the default in `skills/emcli/scripts/install.sh` (and the note in
|
||||
`skills/emcli/references/install.md`).
|
||||
|
||||
## Versioning
|
||||
|
||||
`VERSION` is injected at build time into `internal/version.String` via `-ldflags -X`, so
|
||||
`emcli version` prints the released tag. Without an explicit `VERSION`, the Makefile derives one from
|
||||
`git describe`.
|
||||
Reference in New Issue
Block a user