Skip to content
Back to skills

Build And Release

ASecurity

Use when building Noctra locally, cross-compiling for Raspberry Pi, validating GoReleaser, or cutting a tagged release with cross-platform archives.

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 4, 2026
ai-agentsgoshellbashnodedockertestingrefactoringgitapibackend

Works with

  • cli
  • api

Security analysis

A100/100

Scanned October 5, 2026

npx -y skills add onelastcommit/noctra --skill build-and-release --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Build And Release?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Build And Release
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/onelastcommit-build-and-release/badge)](https://www.skillsdirectory.com/skills/onelastcommit-build-and-release)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: build-and-release
description: Use when building Noctra locally, cross-compiling for Raspberry Pi, validating GoReleaser, or cutting a tagged release with cross-platform archives.
---

# Build And Release Noctra

Use this playbook for local builds, Raspberry Pi binaries, and official releases.

## Local Development Build

```bash
make build
# equivalent:
go build -o noctra ./cmd/noctra
```

Run the binary:

```bash
./noctra version
./noctra doctor
./noctra
```

## Verification Before Shipping

Run the standard checks:

```bash
go test ./...
go vet ./...
```

If `golangci-lint` is available, run:

```bash
golangci-lint run
```

The repository uses `.golangci.yml` v2 with standard linters plus `gofmt`.

## Raspberry Pi Cross-Compile

For Pi 4/5 with a 64-bit OS:

```bash
GOOS=linux GOARCH=arm64 go build -o noctra ./cmd/noctra
scp noctra pi@your-pi:/srv/noctra/
```

For Pi 3 or 32-bit Raspberry Pi OS:

```bash
GOOS=linux GOARCH=arm GOARM=7 go build -o noctra ./cmd/noctra
scp noctra pi@your-pi:/srv/noctra/
```

The Makefile also has:

```bash
make build-pi
```

which produces an arm64 binary named `noctra-pi`.

## Systemd Host Upgrade

On a host running Noctra as a `systemd --user` service, `make update` pulls `main`, builds to a side file, **atomically swaps** it into place (safe while the old process is still executing) and restarts `noctra.service`. A failed build leaves the previous binary intact. `make start` / `stop` / `restart` / `status` / `logs` wrap `systemctl --user` and `journalctl --user-unit=noctra.service -f`.

On an installed host (release binary, no checkout), operate the service through the CLI: `noctra update` (add `--restart` to restart afterwards), `noctra start` / `stop` / `restart` / `status` and `noctra logs`. Recommend these over raw `systemctl --user` commands, which they wrap.

The startup banner (`pipeline.banner`) prints the resolved runtime config — repos, trigger, agent backend (`p.agent.Label()` + CLI), review gate, auto-iterate, notifications, GitHub identity — so a restart's `make logs` shows exactly what is live. Keep new operationally significant config visible there.

## Docker Image

`Dockerfile` is multi-stage: a `golang` stage compiles the static binary, and a `node:20-bookworm-slim` runtime adds `git`, `gh` and every agent CLI (`@anthropic-ai/claude-code`, `@openai/codex`, `@github/copilot`, via npm) — Noctra shells out to all of them, so the image can't be `scratch`.

- `docker-entrypoint.sh` sets a default git identity and wires `GH_TOKEN` into git/gh; a fresh container has neither (both were once silently inherited from the dev's machine).
- All mutable state goes under one `/data` volume via `REPOS_BASE` / `WORKTREE_BASE` / `LOG_DIR` / `STATE_DB` (plus legacy `STATE_FILE` as the one-time JSON migration source).
- Container auth is API-key based (no interactive login).
- `.github/workflows/docker.yml` builds on PRs and builds + pushes multi-arch (amd64/arm64) to GHCR on `main` and tags.
- Cloud templates consuming the image sit at the repo root: `fly.toml`, `render.yaml`, `railway.json`, `deploy/digitalocean-cloud-init.yaml`.

```bash
docker build -t noctra:local .
```

## GoReleaser Validation

Releases are configured in `.goreleaser.yaml` and `.github/workflows/release.yml`.

Before changing release config, validate locally:

```bash
goreleaser check
goreleaser release --snapshot --clean --skip=publish
```

GoReleaser builds:

1. Linux `amd64`, `arm64`, and `armv7`.
2. macOS `amd64` and `arm64`.
3. Archives and checksums.

The `main.version` variable is stamped through `-ldflags "-X main.version=..."`.

## Cutting A Release

### Label-driven (default)

Merging a PR to `main` runs `.github/workflows/tag-on-merge.yml`:

1. exactly one `release:major` / `release:minor` / `release:patch` label → compute the next semver from the latest `v*` tag; no label → no-op; several → fail;
2. create an annotated tag at the merge commit and push it;
3. run GoReleaser inline.

GoReleaser runs inside `tag-on-merge` because tags pushed with `GITHUB_TOKEN` don't trigger other workflows, so `release.yml` would never fire.

### Manual

```bash
git tag vX.Y.Z
git push origin vX.Y.Z
```

`.github/workflows/release.yml` publishes on any pushed `v*` tag — for hotfixes, backdates or testing.

### Changelog

GitHub Release notes are the changelog, generated by GoReleaser from Conventional Commits (Features, Bug Fixes, Performance, Refactoring; `docs:`/`test:`/`chore:`/`ci:` excluded). `CHANGELOG.md` only points at the Releases page.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.