Add versioned release builds for coordinator and worker

This commit is contained in:
Emil
2026-08-02 17:54:06 +03:00
parent 5665e7df98
commit f2977a990e
6 changed files with 159 additions and 3 deletions
+104
View File
@@ -0,0 +1,104 @@
name: release
# Builds static coordinator and worker-agent binaries for every major
# platform on a v* tag push, attaches them (plus SHA-256 checksums) to the
# GitHub Release, and pushes the coordinator image to GHCR.
#
# git tag v1.0.0 && git push origin v1.0.0
on:
push:
tags: ["v*"]
permissions:
contents: write
packages: write
jobs:
binaries:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
os: [linux, darwin, windows]
arch: [amd64, arm64]
defaults:
run:
working-directory: coordinator
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: coordinator/go.mod
cache-dependency-path: coordinator/go.sum
- name: vet
run: go vet ./...
- name: build coordinator and worker-agent
env:
VERSION: ${{ github.ref_name }}
run: |
mkdir -p dist
for cmd in coordinator worker-agent; do
CGO_ENABLED=0 GOOS=${{ matrix.os }} GOARCH=${{ matrix.arch }} \
go build -trimpath \
-ldflags="-s -w -X main.version=${VERSION#v}" \
-o "dist/${cmd}-${{ matrix.os }}-${{ matrix.arch }}${{ matrix.os == 'windows' && '.exe' || '' }}" \
"./cmd/${cmd}"
done
- uses: actions/upload-artifact@v4
with:
name: binaries-${{ matrix.os }}-${{ matrix.arch }}
path: coordinator/dist/*
if-no-files-found: error
release:
needs: binaries
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: checksums
working-directory: artifacts
run: sha256sum * > SHA256SUMS.txt
- uses: softprops/action-gh-release@v2
with:
files: artifacts/*
generate_release_notes: true
image:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/metadata-action@v5
id: meta
with:
images: ghcr.io/${{ github.repository }}/coordinator
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest
- uses: docker/build-push-action@v6
with:
context: coordinator
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
VERSION=${{ github.ref_name }}
+4 -1
View File
@@ -16,6 +16,9 @@ RUN --mount=type=cache,target=/go/pkg/mod go mod download
COPY . .
# Release builds inject the tag via build-arg; local builds stay "dev".
ARG VERSION=dev
# The cache mounts persist the module cache and the compiler's build cache
# *across* builds, so a rebuild after a code edit recompiles only what changed
# instead of the whole dependency tree.
@@ -25,7 +28,7 @@ COPY . .
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
CGO_ENABLED=0 GOOS=linux go build \
-trimpath -ldflags="-s -w" \
-trimpath -ldflags="-s -w -X main.version=${VERSION#v}" \
-o /out/coordinator ./cmd/coordinator
# --- runtime stage --------------------------------------------------------
+6 -2
View File
@@ -31,16 +31,20 @@ DEMO_DIR ?= .demo
# whenever workloads or their manifests change (requires the Python venv).
WORKLOADS_JSON := internal/workloads/workloads.json
# Version injected into the binaries via -ldflags; falls back to "dev".
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo dev)
LDFLAGS := -s -w -X main.version=$(VERSION)
# The Go worker agent: a static coordinator client that executes SDK
# workloads in a Python subprocess per claimed task.
agent:
CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o bin/worker-agent ./cmd/worker-agent
CGO_ENABLED=0 go build -trimpath -ldflags="$(LDFLAGS)" -o bin/worker-agent ./cmd/worker-agent
@printf '%s\n' 'Built bin/worker-agent. Configure via environment:' ' COORDINATOR_URL, WORKER_AUTH_TOKEN, WORK_DIR, CPU_COUNT, MEMORY_MB,' ' POLL_INTERVAL, REQUEST_TIMEOUT, HEARTBEAT_INTERVAL, CAPABILITIES,' ' TASK_RUNNER, MAX_TASKS, EXIT_WHEN_IDLE, WORKER_NAME, WORKER_ID'
# The coordinator server as a static binary, the same way the Docker image
# builds it (CGO_ENABLED=0, trimmed). Requires PostgreSQL at runtime.
coordinator:
CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o bin/coordinator ./cmd/coordinator
CGO_ENABLED=0 go build -trimpath -ldflags="$(LDFLAGS)" -o bin/coordinator ./cmd/coordinator
@printf '%s\n' \
'Built bin/coordinator. Configure via environment:' \
' DATABASE_URL, COORDINATOR_ADDR, COORDINATOR_TOKEN, UI_AUTH_TOKEN,' \
+12
View File
@@ -2,6 +2,8 @@ package main
import (
"context"
"flag"
"fmt"
"log/slog"
"os"
"os/signal"
@@ -17,7 +19,17 @@ import (
"github.com/emil28092005/SciMesh/coordinator/internal/workloads"
)
// version is injected at build time (-ldflags "-X main.version=...") and
// reported by --version. "dev" marks a local build.
var version = "dev"
func main() {
showVersion := flag.Bool("version", false, "print the build version and exit")
flag.Parse()
if *showVersion {
fmt.Println("coordinator " + version)
return
}
// All work happens in run() so its defers (pool.Close, log flush, signal
// stop) still execute: os.Exit skips deferred calls entirely.
if err := run(); err != nil {
+12
View File
@@ -3,13 +3,25 @@
package main
import (
"flag"
"fmt"
"log/slog"
"os"
"github.com/emil28092005/SciMesh/coordinator/internal/agent"
)
// version is injected at build time (-ldflags "-X main.version=...") and
// reported by --version. "dev" marks a local build.
var version = "dev"
func main() {
showVersion := flag.Bool("version", false, "print the build version and exit")
flag.Parse()
if *showVersion {
fmt.Println("worker-agent " + version)
return
}
config, err := agent.LoadConfig()
if err != nil {
slog.Error("invalid configuration", "error", err)
+21
View File
@@ -67,6 +67,27 @@ make demo-ui
# open http://localhost:18080/ui (root@scimesh.local / rootpassword)
```
## Prebuilt binaries
Every `v*` tag pushes a GitHub Release with static binaries for
`coordinator` and `worker-agent` on linux/darwin/windows × amd64/arm64
(plus SHA-256 checksums) and the `coordinator` image on GHCR. Download and
run:
```bash
curl -L -o coordinator https://github.com/emil28092005/SciMesh/releases/latest/download/coordinator-linux-amd64
chmod +x coordinator
```
- **worker-agent** runs anywhere with Python: it spawns
`python -m scimesh.worker.task`, so the machine needs the `scimesh`
package in a venv (`pip install scimesh`) and the usual environment:
`COORDINATOR_URL`, `WORKER_AUTH_TOKEN`, `WORK_DIR`.
- **coordinator** needs PostgreSQL with the applied migrations (the binary
never migrates on startup) plus `DATABASE_URL`, `COORDINATOR_STORAGE_DIR`,
and `JWT_SECRET`; the UI login additionally requires `USERSERVICE_URL`.
`coordinator --version` / `worker-agent --version` print the build tag.
Build and serve this documentation site:
```bash