Add versioned release builds for coordinator and worker
This commit is contained in:
@@ -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 }}
|
||||||
@@ -16,6 +16,9 @@ RUN --mount=type=cache,target=/go/pkg/mod go mod download
|
|||||||
|
|
||||||
COPY . .
|
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
|
# 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
|
# *across* builds, so a rebuild after a code edit recompiles only what changed
|
||||||
# instead of the whole dependency tree.
|
# instead of the whole dependency tree.
|
||||||
@@ -25,7 +28,7 @@ COPY . .
|
|||||||
RUN --mount=type=cache,target=/go/pkg/mod \
|
RUN --mount=type=cache,target=/go/pkg/mod \
|
||||||
--mount=type=cache,target=/root/.cache/go-build \
|
--mount=type=cache,target=/root/.cache/go-build \
|
||||||
CGO_ENABLED=0 GOOS=linux 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
|
-o /out/coordinator ./cmd/coordinator
|
||||||
|
|
||||||
# --- runtime stage --------------------------------------------------------
|
# --- runtime stage --------------------------------------------------------
|
||||||
|
|||||||
@@ -31,16 +31,20 @@ DEMO_DIR ?= .demo
|
|||||||
# whenever workloads or their manifests change (requires the Python venv).
|
# whenever workloads or their manifests change (requires the Python venv).
|
||||||
WORKLOADS_JSON := internal/workloads/workloads.json
|
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
|
# The Go worker agent: a static coordinator client that executes SDK
|
||||||
# workloads in a Python subprocess per claimed task.
|
# workloads in a Python subprocess per claimed task.
|
||||||
agent:
|
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'
|
@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
|
# The coordinator server as a static binary, the same way the Docker image
|
||||||
# builds it (CGO_ENABLED=0, trimmed). Requires PostgreSQL at runtime.
|
# builds it (CGO_ENABLED=0, trimmed). Requires PostgreSQL at runtime.
|
||||||
coordinator:
|
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' \
|
@printf '%s\n' \
|
||||||
'Built bin/coordinator. Configure via environment:' \
|
'Built bin/coordinator. Configure via environment:' \
|
||||||
' DATABASE_URL, COORDINATOR_ADDR, COORDINATOR_TOKEN, UI_AUTH_TOKEN,' \
|
' DATABASE_URL, COORDINATOR_ADDR, COORDINATOR_TOKEN, UI_AUTH_TOKEN,' \
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
@@ -17,7 +19,17 @@ import (
|
|||||||
"github.com/emil28092005/SciMesh/coordinator/internal/workloads"
|
"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() {
|
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
|
// All work happens in run() so its defers (pool.Close, log flush, signal
|
||||||
// stop) still execute: os.Exit skips deferred calls entirely.
|
// stop) still execute: os.Exit skips deferred calls entirely.
|
||||||
if err := run(); err != nil {
|
if err := run(); err != nil {
|
||||||
|
|||||||
@@ -3,13 +3,25 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/emil28092005/SciMesh/coordinator/internal/agent"
|
"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() {
|
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()
|
config, err := agent.LoadConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("invalid configuration", "error", err)
|
slog.Error("invalid configuration", "error", err)
|
||||||
|
|||||||
@@ -67,6 +67,27 @@ make demo-ui
|
|||||||
# open http://localhost:18080/ui (root@scimesh.local / rootpassword)
|
# 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:
|
Build and serve this documentation site:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
Reference in New Issue
Block a user