build: add Make and Gitea release targets

This commit is contained in:
Steve Cliff
2026-08-20 09:50:30 +01:00
parent c90b6d085e
commit 4dc85f5d60
2 changed files with 81 additions and 8 deletions
+36 -8
View File
@@ -7,8 +7,10 @@ are in [README.md](README.md).
## Requirements
- Go 1.24 or later
- PowerShell for the supplied Windows build script, or a POSIX shell for manual
cross-compilation
- PowerShell for the supplied Windows build script, or GNU Make and a POSIX
shell for the Make targets
- The Gitea `tea` CLI, authenticated for the repository, when publishing a
release
- Windows 11 for runtime integration testing
The project uses pure Go and sets `CGO_ENABLED=0`. No C compiler, Windows SDK,
@@ -65,6 +67,18 @@ startup failures in detached mode are shown with `MessageBoxW`.
## Cross-compiling
The standard x64 build can be produced from the repository root with:
```sh
make build
```
This runs the tests, cross-compiles `dist/fancywin.exe`, and copies the example
configuration to `dist/fancywin.yaml`. Override `GOARCH` for another Windows
architecture, for example `make build GOARCH=arm64`.
The equivalent commands are shown below for environments without GNU Make.
Build Windows x64 from Linux, macOS, or another Go-supported host:
```sh
@@ -287,16 +301,30 @@ state, UI surfaces, or lower-level input handling.
## Release preparation
For a distributable release:
The release version is read from the `version` constant in
`cmd/fancywin/main.go`. After committing and pushing that version, publish it
with:
```sh
make release
```
The target performs a fresh x64 build, refuses to publish from a dirty or
unpushed working tree, and creates a Gitea release and corresponding `vVERSION`
tag through the authenticated `tea` CLI. The executable and its SHA-256 checksum
are attached to the release; the YAML is not published, and users obtain the
documented example configuration from the repository. `REMOTE` defaults to
`origin`, and `GOARCH` defaults to `amd64`; either can be overridden on the
command line.
For a distributable release, ensure that you have also:
1. Run all tests, vet, both architecture builds, and the Windows smoke-test
checklist.
2. Update the `version` constant in `cmd/fancywin/main.go`.
3. Build x64 and ARM64 artifacts with `CGO_ENABLED=0`, `-trimpath`, and
`-ldflags='-s -w'`.
4. Include an example renamed to `fancywin.yaml` beside each executable.
5. Record SHA-256 hashes with `Get-FileHash` or `sha256sum`.
6. Code-sign public binaries if a trusted signing certificate and release
3. Build and test ARM64 separately when it is part of the release scope.
4. Complete the Windows smoke-test checklist.
5. Code-sign public binaries if a trusted signing certificate and release
process are available. Signing is not required for portability, but unsigned
downloads may receive stronger Microsoft Defender SmartScreen warnings.
+45
View File
@@ -0,0 +1,45 @@
SHELL := /bin/sh
GO ?= go
TEA ?= tea
GOARCH ?= amd64
REMOTE ?= origin
VERSION := $(shell sed -n 's/^const version = "\([^"]*\)".*/\1/p' cmd/fancywin/main.go)
HOST_GOOS := $(shell $(GO) env GOHOSTOS)
HOST_GOARCH := $(shell $(GO) env GOHOSTARCH)
TAG := v$(VERSION)
BINARY := dist/fancywin.exe
CONFIG := dist/fancywin.yaml
CHECKSUM := $(BINARY).sha256
.PHONY: build release
build:
@test -n "$(VERSION)" || { echo "Could not read the FancyWin version" >&2; exit 1; }
mkdir -p dist
GOOS=$(HOST_GOOS) GOARCH=$(HOST_GOARCH) $(GO) test -buildvcs=false ./...
CGO_ENABLED=0 GOOS=windows GOARCH=$(GOARCH) $(GO) build \
-buildvcs=false \
-trimpath \
-ldflags='-s -w' \
-o $(BINARY) \
./cmd/fancywin
cp fancywin.example.yaml $(CONFIG)
@echo "Built $(BINARY) for windows/$(GOARCH) (FancyWin $(VERSION))"
release: build
@command -v $(TEA) >/dev/null 2>&1 || { echo "The Gitea tea CLI is required for releases" >&2; exit 1; }
@test -z "$$(git status --porcelain)" || { echo "Refusing to release from a dirty working tree" >&2; exit 1; }
@test "$$(git rev-parse HEAD)" = "$$(git rev-parse '@{upstream}')" || { echo "Refusing to release: HEAD has not been pushed to its upstream branch" >&2; exit 1; }
@! git rev-parse --verify --quiet "refs/tags/$(TAG)" >/dev/null || { echo "Tag $(TAG) already exists locally" >&2; exit 1; }
sha256sum $(BINARY) > $(CHECKSUM)
$(TEA) releases create \
--remote $(REMOTE) \
--tag $(TAG) \
--target "$$(git rev-parse HEAD)" \
--title "FancyWin $(VERSION)" \
--note "Portable FancyWin $(VERSION) build for Windows $(GOARCH)." \
--asset $(BINARY) \
--asset $(CHECKSUM)
@echo "Released FancyWin $(VERSION) as $(TAG)"