Skip to content
Back to skills

Release Worker

CSecurity

Build, test, package and deliver ONE altairsim release archive on THIS machine — for a tag someone else created. Use when asked to build the release package, build vX.Y.Z, run the release build on this box, or do DISTRIBUTION.md §4.2. A build machine never tags, never publishes, never picks a version.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 25, 2026
devopsc++shellbashawsgitapi

Works with

  • api

Security analysis

C68/100
  • criticalAccesses sensitive system or user directories
  • highPerforms destructive filesystem operations

Pro shows the line behind each finding and how to fix it

Scanned September 25, 2026

npx -y skills add deltecent/altairsim --skill release-worker --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Release Worker?

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

Security grade badge for Release Worker
[![Security: C — Skills Directory](https://www.skillsdirectory.com/api/skills/deltecent-release-worker/badge)](https://www.skillsdirectory.com/skills/deltecent-release-worker)

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: release-worker
description: Build, test, package and deliver ONE altairsim release archive on THIS machine — for a tag someone else created. Use when asked to build the release package, build vX.Y.Z, run the release build on this box, or do DISTRIBUTION.md §4.2. A build machine never tags, never publishes, never picks a version.
---

# Build one release archive on this machine

You are a **build machine**. You build one archive for this machine's platform, prove it, and
hand it to the coordinator. You **never** tag, push, create or publish a release, run `gh`, or
decide a version number. If you are asked to do any of that, that is the `release-coordinator`
skill, and it runs on the coordinator only.

**Every check below has a STOP. If a check fails, stop and report it — exact output included.
Do not work around it, do not decide it is probably fine, and do not deliver.** Nothing checks
the package after you hand it over; the next stop is a user's download.

## Before you start: what you need to be told

- **The version**, `X.Y.Z`. The tag is `vX.Y.Z`. If you were not given it, STOP and ask. Never
  guess it from `git tag`, `CMakeLists.txt` or the latest release.
- **Site values**, from `distribution.conf` in the repo root if it exists (see
  `distribution.conf.example` for every key), otherwise from whoever asked you — usually the
  coordinator, over ssh. Keys are prefixed by this machine's target in capitals
  (`LINUX_X86_64_PARALLEL`):
  - `<TARGET>_PARALLEL` — `no` means build without `--parallel`. If unknown, use `--parallel`
    only on a machine with 16 GB or more.
  - `<TARGET>_SERIAL_A` / `_SERIAL_B` — the null-modem pair, if this box has one.
  - `COORDINATOR_USER`, `COORDINATOR_HOST`, `COORDINATOR_DIST` — where step 8 delivers. If you
    do not have them, do steps 1–7 and report that you did not deliver.

**Your target** — find it, do not assume it:

| this machine | target | archive |
|---|---|---|
| macOS, `uname -m` = `arm64` | `macos-arm64` | `.tar.gz` |
| macOS, `uname -m` = `x86_64` | `macos-x86_64` | `.tar.gz` |
| Windows | `windows-x86_64` | `.zip` |
| Linux, `x86_64` | `linux-x86_64` | `.tar.gz` |

**Your shell does not keep environment variables between commands.** Anything a command needs
(`PATH`, `ALTAIR_SERIAL_A`) is set *in that same command*. If `cmake` is not found over a
non-login ssh shell, prefix the command with `export PATH="<TARGET>_PATH:$PATH"` — the
directory the login profile would have added.

## The eight steps — macOS and Linux

Run from the repo root.

```sh
# 1. The source AT THE TAG, never a branch.
#    --force and -f matter: a re-spin force-moves the tag, and a plain `git fetch --tags`
#    keeps the old one and silently builds the wrong commit.
git fetch --tags --force && git checkout -f vX.Y.Z

# 2. Configure, from a CLEAN build/. A reused build/ keeps its cached SDL3_DIR -- often
#    Homebrew's dylib -- and the configure below does not override it.
rm -rf build
cmake -B build -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_PREFIX_PATH="$HOME/opt/sdl3-static" \
      -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0          # macOS only; omit on Linux
```

**CHECK** the configure output contains `-- SDL3 found -- video boards enabled (windowed)`.
**STOP** if it says `-- SDL3 not found -- video boards build headless (null display)` — a
headless binary runs perfectly and draws nothing, and that is how v0.2.0 shipped. On macOS,
**never** pass `-DCMAKE_OSX_ARCHITECTURES`: each Mac builds native for itself.

```sh
# 3. Build. Drop --parallel if <TARGET>_PARALLEL=no (the compiler gets OOM-killed).
cmake --build build --config Release --parallel

# 4. Test -- everything except the slow CPU gate and the two tests that need hardware.
ctest --test-dir build -C Release -LE slow -E '^(serial-hw|tnfs-hw)$'
```

**CHECK** `100% tests passed out of N`. **STOP** on anything else. Read the pass line itself;
the absence of the word "error" proves nothing.

```sh
# 4b. The hardware tests -- WARN, never stop. Ports in the same command as ctest.
ALTAIR_SERIAL_A=<SERIAL_A> ALTAIR_SERIAL_B=<SERIAL_B> \
  ctest --test-dir build -C Release -R '^(serial-hw|tnfs-hw)$' --output-on-failure
```

**No ports configured? Leave the two variables off entirely.** An empty value is not the same
as unset: the test sees a variable, tries to open an empty path, and fails instead of skipping.

Report each of `serial-hw` and `tnfs-hw` as Passed, Skipped, or Failed. **If serial ports are
configured for this box and `serial-hw` is not Passed, warn loudly** (the cable, the ports,
or the serial code is wrong) — and carry on. `tnfs-hw` runs when `de-tnfsd` is on `PATH` and
skips otherwise; a skip is a note, a failure is a loud warning. Neither stops the release.

```sh
# 5. The binary knows exactly what it is.
./build/altairsim --version
```

**CHECK** exactly `AltairSim X.Y.Z`. **STOP** on a `-N-gsha` suffix (not on the tag) or
`(modified)` (dirty tree) — either means the binary cannot be traced to the release.

```sh
# 6. Package, with CI's manual handed in. The tag's tree already holds it; pandoc never runs.
tools/build-package.sh --pdf docs/altairsim-manual.pdf --target <target>

# 7. Prove the manual true against the ARCHIVE (extracts it outside the repo and runs the
#    manual's own `$ altairsim ...` commands).
tools/verify-package.sh dist/altairsim-X.Y.Z-<target>.tar.gz
```

**STOP** if `build-package.sh` refuses (headless binary, SDL linked by absolute path — it says
which). **CHECK** step 7 prints `verify-package: PASS -- N/N manual commands reached their
documented prompt`. **STOP** on any FAIL.

```sh
# 8. Deliver. The worker's only credential is the delivery key; it never touches GitHub.
scp dist/altairsim-X.Y.Z-<target>.tar.gz \
    <COORDINATOR_USER>@<COORDINATOR_HOST>:<COORDINATOR_DIST>/
```

Skip step 8 if you are the coordinator: your archive is already in `dist/`.

## Windows

Steps 1–5 in **PowerShell**, 6–8 in **Git Bash** (`build-package.sh` is `/bin/sh`). **No
Developer shell is needed:** the Visual Studio generator lets MSBuild find the toolchain. Do
not use Ninja for a release — it needs `vcvars` in the same command, every time. **MSVC is the
only supported Windows toolchain.**

```powershell
git fetch --tags --force; git checkout -f vX.Y.Z
Remove-Item -Recurse -Force build -ErrorAction SilentlyContinue
cmake -B build -G "Visual Studio 18 2026" -DCMAKE_BUILD_TYPE=Release `
      -DCMAKE_PREFIX_PATH="$env:USERPROFILE\opt\sdl3-static" `
      -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded
cmake --build build --config Release --parallel
ctest --test-dir build -C Release -LE slow -E '^(serial-hw|tnfs-hw)$'
# with ports; without, drop the two $env: assignments (an empty value fails, it does not skip)
$env:ALTAIR_SERIAL_A='<SERIAL_A>'; $env:ALTAIR_SERIAL_B='<SERIAL_B>'; ctest --test-dir build -C Release -R '^(serial-hw|tnfs-hw)$' --output-on-failure
.\build\Release\altairsim.exe --version
```

```sh
# Git Bash, repo root
tools/build-package.sh --pdf docs/altairsim-manual.pdf --target windows-x86_64
tools/verify-package.sh dist/altairsim-X.Y.Z-windows-x86_64.zip
scp dist/altairsim-X.Y.Z-windows-x86_64.zip <COORDINATOR_USER>@<COORDINATOR_HOST>:<COORDINATOR_DIST>/
```

Same CHECKs and STOPs as above. Windows-specific:

- **Name the generator.** Without `-G "Visual Studio 18 2026"` CMake picks the newest Visual
  Studio *it* knows, and an old CMake builds with 2022 silently. CI builds with 2026.
- **`MultiThreaded` is load-bearing.** It links the C runtime statically, so the `.exe` does
  not need the VC++ redistributable. SDL3 was built the same way; mixing the two fails to link.
- **`--config Release` is load-bearing** — the generator is multi-config. The binary lands in
  `build\Release\`; `build-package.sh` finds it there.
- **`verify-package` skips the pty checks on Windows** (there is no `expect`). A PASS line
  with those SKIPs is the expected result, not a failure.
- **The `.zip` is made by Windows' own `tar.exe`.** If it ever fails, do not fall back to
  `Compress-Archive`: PowerShell 5.1 writes backslashes that Unix `unzip` cannot extract.

## Report back

One block, whether you finished or stopped:

```
target        linux-x86_64
version       AltairSim X.Y.Z                (the --version line, verbatim)
tests         100% tests passed out of N     (verbatim)
serial-hw     Passed | Skipped | Failed      (+ ports used)
tnfs-hw       Passed | Skipped | Failed
SDL3          3.4.12                          (cat ~/opt/sdl3-static/.altairsim-sdl3-version)
verify        verify-package: PASS -- N/N ... (verbatim)
archive       altairsim-X.Y.Z-<target>.tar.gz  sha256 <hash>
delivered     yes | no -- <why>
stopped at    <step and the exact output>     (only if you stopped)
```

The SDL3 version matters: nothing makes the four machines agree, so this report is the only
record, and it is the first thing to check if a video bug shows on one platform only.

## First time on this machine

Done once, not at release time. If any is missing, STOP and report which.

- **A C++20 compiler, CMake ≥ 3.20, git.** No pandoc, no Chrome — the PDFs come from CI.
- **A checkout of the public repo over anonymous https**, no login and no token:
  `git clone https://github.com/deltecent/altairsim.git`, or on an existing clone
  `git remote set-url origin https://github.com/deltecent/altairsim.git`.
- **Static SDL3**, which the configure above expects at that prefix:
  `tools/build-sdl3-static.sh` (macOS, Linux) or `tools\build-sdl3-static.bat` (Windows).
  Idempotent. On Linux install the X11/Wayland headers first — `docs/building-linux.md` has the
  list, and `libxtst-dev` is required.
- **Windows:** `tools\windows\RUN-ME-setup-windows-worker.bat` installs and checks all of it
  (Visual Studio 2026 Build Tools, Git + Git Bash, OpenSSH Server, static SDL3).
- **Linux:** build on the oldest glibc you can — the binary will not start on a distro older
  than the one it was built on.
- **The delivery key.** A passphrase-less ed25519 key, `~/.ssh/altairsim_deploy`, used for
  nothing else, its public half in the coordinator's `~/.ssh/authorized_keys`, and in
  `~/.ssh/config`:

  ```
  Host <COORDINATOR_HOST>
      IdentityFile ~/.ssh/altairsim_deploy
      IdentitiesOnly yes
  ```

  It must have no passphrase because step 8 runs unattended. It writes to `dist/` and grants
  no GitHub access at all.

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…