5 Commits
Author SHA1 Message Date
petrbalvin 88f0e24b46 ci(release): simplify tag pattern and bump action versions
Test / vet (push) Successful in 1m8s
Test / test (push) Successful in 2m47s
Test / build (push) Successful in 1m2s
2026-07-26 23:29:55 +02:00
petrbalvin 603e1e344b fix(ci): use single-line JSON for curl and add missing GITEA_REF_NAME
Release / build (amd64, freebsd) (push) Successful in 56s
Release / build (amd64, linux) (push) Successful in 58s
Release / build (arm64, freebsd) (push) Successful in 58s
Release / build (arm64, linux) (push) Successful in 58s
Release / build (loong64, linux) (push) Successful in 1m3s
Release / build (riscv64, freebsd) (push) Successful in 1m1s
Release / build (riscv64, linux) (push) Successful in 1m1s
Release / release (push) Successful in 20s
2026-07-26 21:48:17 +02:00
petrbalvin 96e47ab87a fix(ci): pass Gitea context vars via env instead of GITHUB_*
Release / build (amd64, freebsd) (push) Successful in 57s
Release / build (amd64, linux) (push) Successful in 1m0s
Release / build (arm64, freebsd) (push) Successful in 1m2s
Release / build (arm64, linux) (push) Successful in 1m0s
Release / build (loong64, linux) (push) Successful in 1m1s
Release / build (riscv64, freebsd) (push) Successful in 59s
Release / build (riscv64, linux) (push) Successful in 59s
Release / release (push) Failing after 18s
2026-07-26 21:29:45 +02:00
petrbalvin c3418b3c3b fix(ci): use GITHUB_* env vars for Gitea release workflow
Release / build (amd64, freebsd) (push) Successful in 59s
Release / build (amd64, linux) (push) Successful in 59s
Release / build (arm64, freebsd) (push) Successful in 57s
Release / build (arm64, linux) (push) Successful in 58s
Release / build (riscv64, freebsd) (push) Canceled after 0s
Release / build (riscv64, linux) (push) Canceled after 0s
Release / release (push) Canceled after 0s
Release / build (loong64, linux) (push) Canceled after 51s
2026-07-26 21:24:48 +02:00
petrbalvin 5048968cdf fix(ci): restrict smoke test to native linux/amd64 builds
Release / build (amd64, freebsd) (push) Successful in 1m0s
Release / build (amd64, linux) (push) Successful in 1m1s
Release / build (arm64, freebsd) (push) Successful in 57s
Release / build (arm64, linux) (push) Successful in 58s
Release / build (loong64, linux) (push) Successful in 1m3s
Release / build (riscv64, freebsd) (push) Successful in 56s
Release / build (riscv64, linux) (push) Successful in 1m0s
Release / release (push) Failing after 20s
2026-07-26 21:15:45 +02:00
4 changed files with 53 additions and 59 deletions
+26 -31
View File
@@ -1,8 +1,10 @@
# Release — Go binaries. Runs on version tags (v1.2.3) pushed to main.
# Builds the platform matrix, creates the Gitea release, uploads binaries.
name: Release name: Release
on: on:
push: push:
tags: ["v*.*.*"] tags: ["v*"]
jobs: jobs:
build: build:
@@ -26,33 +28,31 @@ jobs:
- goos: freebsd - goos: freebsd
goarch: riscv64 goarch: riscv64
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v7
- uses: actions/setup-go@v5 - uses: actions/setup-go@v6
with: with:
go-version: "1.26" go-version: "1.26"
- name: Download dependencies - name: Download dependencies
run: go mod download run: go mod download
- name: Build - name: Validate tag and build
id: build id: build
env: env:
REF: ${{ gitea.ref }} VERSION: ${{ gitea.ref_name }}
run: | run: |
set -euo pipefail set -euo pipefail
VERSION="${REF##*/}" if ! echo "$VERSION" | grep -qE '^v[0-9]+(\.[0-9]+){0,2}([-+].*)?$'; then
echo "ERROR: expected a semver tag like v1.2.3, got: '$VERSION'"
if [[ ! "$VERSION" =~ ^v[0-9]+(\.[0-9]+){0,2}([-+].*)?$ ]]; then
echo "ERROR: expected a semver tag like v1.2.3, got: '$VERSION' (ref: '$REF')"
exit 1 exit 1
fi fi
VERSION_NO_V="${VERSION#v}" VERSION_NO_V="${VERSION#v}"
echo "version_no_v=${VERSION_NO_V}" >> "$GITEA_OUTPUT" echo "version_no_v=${VERSION_NO_V}" >> "$GITEA_OUTPUT"
# The tag is the source of truth — inject it into the binary.
LDFLAGS="-s -w -X sourcedock.dev/petrbalvin/nuntius/internal/version.Version=${VERSION_NO_V}" LDFLAGS="-s -w -X sourcedock.dev/petrbalvin/nuntius/internal/version.Version=${VERSION_NO_V}"
mkdir -p bin mkdir -p bin
GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} CGO_ENABLED=0 \ GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} CGO_ENABLED=0 \
@@ -60,6 +60,7 @@ jobs:
-o "bin/nuntius-${VERSION_NO_V}-${{ matrix.goos }}-${{ matrix.goarch }}" \ -o "bin/nuntius-${VERSION_NO_V}-${{ matrix.goos }}-${{ matrix.goarch }}" \
./cmd/server ./cmd/server
# Artifacts stay on v3 — v4 detects Gitea as GHES and aborts.
- name: Upload artifact - name: Upload artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
@@ -67,6 +68,7 @@ jobs:
path: bin/nuntius-${{ steps.build.outputs.version_no_v }}-${{ matrix.goos }}-${{ matrix.goarch }} path: bin/nuntius-${{ steps.build.outputs.version_no_v }}-${{ matrix.goos }}-${{ matrix.goarch }}
if-no-files-found: error if-no-files-found: error
# Only binaries matching the runner can be smoke-tested.
- name: Smoke test - name: Smoke test
if: matrix.goos == 'linux' && matrix.goarch == 'amd64' if: matrix.goos == 'linux' && matrix.goarch == 'amd64'
run: | run: |
@@ -76,8 +78,10 @@ jobs:
release: release:
runs-on: fedora runs-on: fedora
needs: build needs: build
permissions:
releases: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v7
- name: Download all artifacts - name: Download all artifacts
uses: actions/download-artifact@v3 uses: actions/download-artifact@v3
@@ -109,17 +113,12 @@ jobs:
- name: Create release - name: Create release
env: env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
GITEA_SERVER_URL: ${{ gitea.server_url }}
GITEA_REPOSITORY: ${{ gitea.repository }}
GITEA_REF_NAME: ${{ gitea.ref_name }}
run: | run: |
set -euo pipefail set -euo pipefail
# JSON-escape the release body with sed: backslashes first, then BODY=$(sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' -e 's/\t/\\t/g' -e 's/\r//g' release-body.md | sed ':a;N;$!ba;s/\n/\\n/g')
# quotes, tabs, and carriage returns, and finally fold newlines into
# \n. Wrap the result in quotes to form a JSON string.
BODY=$(sed -e 's/\\/\\\\/g' \
-e 's/"/\\"/g' \
-e 's/\t/\\t/g' \
-e 's/\r//g' \
release-body.md \
| sed ':a;N;$!ba;s/\n/\\n/g')
BODY="\"${BODY}\"" BODY="\"${BODY}\""
response=$(curl -sS -w '\n%{http_code}' \ response=$(curl -sS -w '\n%{http_code}' \
@@ -127,31 +126,27 @@ jobs:
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-X POST \ -X POST \
"${GITEA_SERVER_URL}/api/v1/repos/${GITEA_REPOSITORY}/releases" \ "${GITEA_SERVER_URL}/api/v1/repos/${GITEA_REPOSITORY}/releases" \
-d "{ -d "{\"tag_name\":\"${GITEA_REF_NAME}\",\"name\":\"${GITEA_REF_NAME}\",\"body\":${BODY},\"draft\":false,\"prerelease\":false}")
\"tag_name\": \"${GITEA_REF_NAME}\",
\"name\": \"${GITEA_REF_NAME}\",
\"body\": ${BODY},
\"draft\": false,
\"prerelease\": false
}")
http_code=$(echo "$response" | tail -1) http_code=$(echo "$response" | tail -1)
body=$(echo "$response" | sed '$d') payload=$(echo "$response" | sed '$d')
echo "HTTP ${http_code}" echo "HTTP ${http_code}"
if [ "$http_code" != "201" ]; then if [ "$http_code" != "201" ]; then
echo "Failed to create release: ${body}" echo "Failed to create release: ${payload}"
exit 1 exit 1
fi fi
RELEASE_ID=$(echo "$body" | grep -oE '"id"[[:space:]]*:[[:space:]]*[0-9]+' | head -1 | grep -oE '[0-9]+') RELEASE_ID=$(echo "$payload" | grep -oE '"id"[[:space:]]*:[[:space:]]*[0-9]+' | head -1 | grep -oE '[0-9]+')
echo "Created release ID=${RELEASE_ID}" echo "Created release ID=${RELEASE_ID}"
printf '%s' "${RELEASE_ID}" > release-id.txt printf '%s' "${RELEASE_ID}" > release-id.txt
- name: Upload assets - name: Upload assets
env: env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
GITEA_SERVER_URL: ${{ gitea.server_url }}
GITEA_REPOSITORY: ${{ gitea.repository }}
GITEA_REF_NAME: ${{ gitea.ref_name }}
run: | run: |
set -euo pipefail set -euo pipefail
RELEASE_ID=$(cat release-id.txt) RELEASE_ID=$(cat release-id.txt)
+22 -17
View File
@@ -1,3 +1,4 @@
# Test — Go. Runs on push and pull request to development. Never on main.
name: Test name: Test
on: on:
@@ -10,9 +11,9 @@ jobs:
vet: vet:
runs-on: fedora runs-on: fedora
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v7
- uses: actions/setup-go@v5 - uses: actions/setup-go@v6
with: with:
go-version: "1.26" go-version: "1.26"
@@ -20,12 +21,11 @@ jobs:
run: go mod download run: go mod download
- name: gofmt - name: gofmt
# `gofmt -l` prints the names of unformatted files. An empty # gofmt -l prints unformatted files; an empty output is the only pass.
# output is the only acceptable result.
run: | run: |
unformatted=$(gofmt -l cmd internal pkg) unformatted=$(gofmt -l .)
if [ -n "$unformatted" ]; then if [ -n "$unformatted" ]; then
echo "The following files need gofmt:" echo "These files need gofmt:"
echo "$unformatted" echo "$unformatted"
exit 1 exit 1
fi fi
@@ -37,36 +37,44 @@ jobs:
runs-on: fedora runs-on: fedora
needs: vet needs: vet
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v7
- uses: actions/setup-go@v5 - uses: actions/setup-go@v6
with: with:
go-version: "1.26" go-version: "1.26"
- name: Download dependencies - name: Download dependencies
run: go mod download run: go mod download
- name: Install build tools # The runner images have no gcc; the race detector needs CGO.
- name: Install gcc
run: dnf install -y gcc run: dnf install -y gcc
- name: go test -race - name: go test -race
run: go test -race -count=1 ./... run: go test -race -count=1 ./...
- name: Check coverage threshold # Coverage is measured over the library packages; cmd/ is thin glue.
- name: Coverage gate — 80 % minimum
run: | run: |
set -euo pipefail
go test -coverprofile=coverage.out ./internal/... ./pkg/... go test -coverprofile=coverage.out ./internal/... ./pkg/...
go tool cover -func=coverage.out | grep '^total:' | python3 -c "import sys; pct=float(sys.stdin.read().split()[2].rstrip('%')); sys.exit(0 if pct >= 80 else 1)" || (echo "ERROR: coverage < 80%"; exit 1) coverage=$(go tool cover -func=coverage.out | awk '/^total:/ { gsub("%", "", $3); print $3 }')
echo "Total coverage: ${coverage}%"
if awk -v c="$coverage" 'BEGIN { exit !(c+0 < 80) }'; then
echo "ERROR: coverage ${coverage}% is below the 80% threshold"
exit 1
fi
- name: go test ./examples - name: Build examples
run: go build ./examples/... run: go build ./examples/...
build: build:
runs-on: fedora runs-on: fedora
needs: test needs: test
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v7
- uses: actions/setup-go@v5 - uses: actions/setup-go@v6
with: with:
go-version: "1.26" go-version: "1.26"
@@ -76,8 +84,5 @@ jobs:
- name: Build - name: Build
run: go build -ldflags="-s -w" -o bin/nuntius ./cmd/server run: go build -ldflags="-s -w" -o bin/nuntius ./cmd/server
- name: Test
run: go test ./...
- name: Smoke test - name: Smoke test
run: ./bin/nuntius --version run: ./bin/nuntius --version
+4 -10
View File
@@ -7,14 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [development] ## [development]
## [1.1.1] — 2026-07-26
### Fixed
- **Smoke test restricted to native builds** — cross-compiled binaries
(FreeBSD, ARM64, RISC-V, LoongArch) now skip the smoke test step since
they cannot execute on the Linux amd64 CI runner.
## [1.1.0] — 2026-07-26 ## [1.1.0] — 2026-07-26
### Added ### Added
@@ -53,9 +45,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
when it finds unformatted files. when it finds unformatted files.
- **Missing `just fmt` recipe** — added `gofmt -w` target. - **Missing `just fmt` recipe** — added `gofmt -w` target.
- **Copyright headers** — added to all Go and Python source files. - **Copyright headers** — added to all Go and Python source files.
- **Smoke test restricted to native builds** — cross-compiled binaries now
skip the smoke test step since they cannot execute on the Linux amd64 CI
runner.
[development]: https://sourcedock.dev/petrbalvin/nuntius/compare/v1.1.1...development [development]: https://sourcedock.dev/petrbalvin/nuntius/compare/v1.1.0...development
[1.1.1]: https://sourcedock.dev/petrbalvin/nuntius/releases/tag/v1.1.1
[1.1.0]: https://sourcedock.dev/petrbalvin/nuntius/releases/tag/v1.1.0 [1.1.0]: https://sourcedock.dev/petrbalvin/nuntius/releases/tag/v1.1.0
## [1.0.0] — 2026-06-20 ## [1.0.0] — 2026-06-20
+1 -1
View File
@@ -10,4 +10,4 @@ package version
const Name = "nuntius" const Name = "nuntius"
// Version is the nuntius release version. Follows SemVer. // Version is the nuntius release version. Follows SemVer.
var Version = "1.1.1" var Version = "1.1.0"