The sweep (main's item 1): 199 tracked text files, 783 lines. The founder's full name, first name and possessive become "the founder" (sentence starts capitalised); the lowercase operating-system user name in WSL paths and commands becomes <user>; the second owner login becomes "the second owner login"; the three earlier businesses and the two other brands become "the other business", "the earlier entity", "the earlier business" and "another brand"; the Chrome profile rule names the igneum.network profile, not the profile's label. The standing commit login igneum-labs is not a founder term here: the fresh-repository step renames it in the history (docs/plans/history-rewrite.md, tools/repo/fresh-repo.sh). The patterns never appear in plain text in the tree (a plaintext list would be the hit): tools/ci/founder-strings.b64 (perl regex, tab, a sample per row) is read by tools/ci/founder-strings-check.sh (every tracked text file, perl, known-failed first: the self-test plants each row's sample in a fixture and the hit must name the file), by tools/community/discord-hooks.mjs (the guard's founder and business rows; the test takes its fixtures from the samples) and by tools/repo/fresh-repo.sh (the business names of the rewrite rules). site/forbidden-strings.txt carries the same patterns as b64: lines, decoded case-insensitive by site/scrub.mjs and tools/ci/launch-gates-check.mjs (whose fixture now plants an encoded made-up name). The check runs in the gate's tree checks on every merge. Not in this commit, by main's word: the 105 commit messages and 40 personal-identity commits that need the history rewrite (listed, not run), and the secrets found by gitleaks over the history (reported with owners). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
127 lines
10 KiB
Markdown
127 lines
10 KiB
Markdown
# Shipping an Igneum Miner version (packaging/README-ship.md)
|
|
|
|
One command cuts a version for both platforms. 4 October 2026: 0.3.1, 0.3.2 and 0.3.3 each took eight hand steps and
|
|
an hour; `tools/ship-app.mjs` is those steps in order, each one checked and resumable.
|
|
|
|
node tools/ship-app.mjs 0.3.4 --node vendor/igneum-node-v4 --notes "one line for the changelog"
|
|
|
|
Add `--dry-run` first: it reads everything, prints the plan and writes nothing.
|
|
|
|
## What it does
|
|
|
|
| Step | What happens | Skips itself when |
|
|
|---|---|---|
|
|
| preflight | this tree clean and on master, the fork worktree clean (`--node-commit <sha>` pins it), tools, binaries, secrets present, gh account, what is live | never (reads only) |
|
|
| bump | the six version files, written by one function and read back | the files already say the version |
|
|
| inputs | `packaging/windows/push-inputs.sh` with the fork's Windows exes (`IGNEUM_WIN_RELEASE`, `IGNEUM_NODE_SRC`) | the live `payload-inputs.json` carries these exact files from this fork commit |
|
|
| commit | `Igneum Miner <v>: <notes>`, push master (the push starts the Windows build) | committed and on origin/master |
|
|
| ci | the `windows.yml` run for that commit (dispatched when the push started none), polled every 30 s | a green run for the commit exists |
|
|
| fetch | `packaging/windows/fetch-ci-artifacts.sh <run>`: installer and payload zip into the downloads folder | the installer from that run is there |
|
|
| dmg | `packaging/mac/build-dmg.sh` under `tools/lock/with-lock.sh build` | the DMG is newer than the bump (`--rebuild` forces) |
|
|
| copy | the DMG into the downloads folder | same sha256 already there |
|
|
| manifest | `packaging/ota/publish-manifest.sh --no-deploy`: signed, signature verified locally | never (cheap) |
|
|
| deploy | the downloads folder, one Vercel deploy for the files and the manifest together | never |
|
|
| verify | HEAD and GET of the DMG, the installer and the zip (size and sha256 against the local copies); the live manifest through `igneum-ota-sign verify` | never |
|
|
| console | one `build` item on the console (version, sizes, hashes, run, commit), then `sync-dl` | never (upsert on `ship:<v>`) |
|
|
|
|
The six version files: `app/igneum-app/Cargo.toml`, `app/igneum-app/Cargo.lock`, `app/windows/version.h`,
|
|
`app/igneum-app/resources/igneum-app.rc`, `packaging/windows/Igneum-Miner.iss`, `packaging/mac/app/Info.plist`.
|
|
`node tools/ship-app.mjs --check` says whether they agree; `--self-test` runs the bump on a scratch copy.
|
|
|
|
## Flags
|
|
|
|
| Flag | Meaning |
|
|
|---|---|
|
|
| `--node <dir>` | the igneum-node worktree the node and miner were built from (required); binaries from its `target-integration/`, else `target/` |
|
|
| `--notes "..."` | the manifest's changelog line and the commit message |
|
|
| `--dry-run` | reads only, prints the plan (exit 1 when preflight would stop the real run) |
|
|
| `--from <step>` | resume at that step (preflight runs again first); the failure message prints this command |
|
|
| `--skip-windows`, `--skip-mac` | one platform only (the other entry is carried over when the live manifest is the same version) |
|
|
| `--node-commit <sha>` | the fork must be on this commit |
|
|
| `--win-release <dir>`, `--mac-release <dir>` | other binary folders |
|
|
| `--min-supported`, `--activation-height`, `--deadline-note`, `--channel` | passed to `publish-manifest.sh` |
|
|
| `--rebuild` | build the DMG again even when a fresh one exists |
|
|
| `--branch <name>` | accept another branch than master (a dry run from a worktree; the Windows build still runs on pushes to master) |
|
|
| `--public` | the manifest step also publishes the version into `dl/public/` (no token in any URL; its own signed manifest; the `/public/` aliases rewritten), the same deploy carries it, verify checks every public file and alias. The token folders are untouched |
|
|
|
|
## The public downloads path (5 October 2026, testnet launch)
|
|
|
|
`dl/public/` in the downloads folder holds only the current installers, the HiveOS package and the two signed manifests
|
|
(app and wallet) with URLs under `https://dl.igneum.network/dl/public/`, plus an unsigned index `igneum-downloads.json`
|
|
that the site build reads. Four stable aliases are rewrites in the downloads folder's `vercel.json`, written from what the
|
|
folder holds, so they follow every release by themselves:
|
|
|
|
| Alias | Rewrites to |
|
|
|---|---|
|
|
| `https://dl.igneum.network/public/igneum-miner-windows.exe` | `dl/public/Igneum-Miner-Setup-<v>.exe` |
|
|
| `https://dl.igneum.network/public/igneum-miner-mac.dmg` | `dl/public/Igneum-Miner-<v>.dmg` |
|
|
| `https://dl.igneum.network/public/igneum-miner-hive.tar.gz` | `dl/public/igneum-hive-<v>.tar.gz` |
|
|
| `https://dl.igneum.network/public/igneum-wallet-mac.dmg` | `dl/public/Igneum-Wallet-<v>.dmg` |
|
|
|
|
`packaging/ota/publish-public.sh --app | --wallet | --hive <tar.gz> [--deploy] [--verify] [--dry-run]` does the work;
|
|
`publish-manifest.sh --public` and `ship-app.mjs --public` call it, so every future release lands there too. The
|
|
HiveOS package comes from `packaging/hive/make-hive-package.sh` (Linux node and miner from a PC `build` job, the two GPU
|
|
workers from `infra/cross/build-workers-linux.sh`) and is published with `--hive`. The site (`site/build.mjs`) reads the
|
|
index at build time and stamps every download button with the version and size; `TESTNET_OPEN` there removes the
|
|
"Public testnet: not yet open" line on the go.
|
|
|
|
## When a step fails
|
|
|
|
The tool stops, prints why and the `--from` command to retry. Nothing is skipped silently. State that is not a secret
|
|
(commit, run id, bump time, the hashes) is in `~/.cache/igneum/ship/<version>.json`.
|
|
|
|
Secrets come from `~/.config/igneum` (dl-token, dlsite-dir, ota-signing-key, relay token and key, the Vercel login) and are
|
|
never printed; every output line is scrubbed. `gh auth switch --user igneum-labs` runs before every gh call and before the
|
|
push.
|
|
|
|
## What a cut needs before it starts
|
|
|
|
- The node fork built for both targets in `--node`: `target-integration/release/{igneumd,igneum-miner}` and
|
|
`target-integration/x86_64-pc-windows-gnu/release/{igneumd,igneum-miner}.exe` (`proto-cuda/windows-node/cross-build.sh`).
|
|
- The prebuilt workers (`proto-cuda/nvrtc/igneum-worker-cuda.exe`, `proto-opencl/igneum-worker-opencl.exe`) and the prover
|
|
(`proving/igneum-prove/target/release/igneum-prove-{host,export}`); missing ones are noted, not fatal.
|
|
- The Mac on mains, nothing else building (the DMG step waits for the build lock).
|
|
|
|
## The site project on Vercel (4 October 2026, checked by hand)
|
|
|
|
Two Vercel projects are called `igneum`, in two teams, and the link file under `site/.vercel` points at the wrong one:
|
|
|
|
| Team | Login (global config) | Project | Holds | Deploys |
|
|
|---|---|---|---|---|
|
|
| `igneum` | `igneum-labs` (`~/.config/igneum/vercel`) | `igneum` (`prj_HcNO2NLY4jkhikmLMugpJ8nLcWNW`, root directory `site`, build `node build.mjs`) | `igneum.network`, `igneum.com`; env `DATABASE_URL`, `LOG_INTAKE_KEY` | GitHub integration: every push to master is a production deploy, every branch push a preview (`igneum-git-<branch>-igneum.vercel.app`) |
|
|
| `other-business` | `<user>-4826` (the default `~/.vercel`) | `igneum` (`prj_y5lQg3C87fXAgoj3vug6iwWU3KwV`, same settings) | the 13 redirect domains (`igneum.app`, `.art`, `.co.uk`, `.email`, `.info`, `.io`, `.net`, `.online`, `.org`, `.pro`, `.shop`, `.store`, `.vip`, `.xyz`) | nothing live |
|
|
|
|
So `vercel env add` from `site/` fails with "Could not retrieve Project Settings" under the igneum login (the link file names
|
|
the other business's project, which that login cannot read), and would silently add the value to the wrong project under the default
|
|
login. The working commands, from `site/` in the shared checkout (the link step rewrites `site/.vercel/project.json`, which
|
|
is ignored by git):
|
|
|
|
cd site
|
|
npx --yes vercel@latest --global-config ~/.config/igneum/vercel link --scope igneum --project igneum --yes
|
|
npx --yes vercel@latest --global-config ~/.config/igneum/vercel env ls --scope igneum # names only
|
|
npx --yes vercel@latest --global-config ~/.config/igneum/vercel env add LOG_INTAKE_KEY_NEXT production --scope igneum
|
|
|
|
A production deploy by hand is `npx --yes vercel@latest --global-config ~/.config/igneum/vercel deploy --prod --yes --scope igneum`
|
|
from the repository root (the project's root directory is `site`), but the normal path is a push to master. The relay
|
|
(`igneum-relay`) and the downloads folder (`igneum-dl`) are the other two projects in the `igneum` team; both deploy by CLI
|
|
from their own folders (`relay/README.md`, `packaging/ota/README.md`). CLAUDE.md still says the site sits in the the other business
|
|
team and deploys with `--scope the other business` from `site/`: that was true on 3 October and is not now.
|
|
|
|
## Job scripts (5 October 2026, the lost-quote class)
|
|
|
|
A bash body in a PowerShell job (`relay/playbooks/*.ps1`, `tools/**/*.ps1`) is written to a file and run with
|
|
`bash <file>`, never inline. That is the 0.3.6 cut's rule. Twice on 5 October a body travelled inside a PowerShell
|
|
string, a quote was lost on the way through PowerShell, bash refused the whole body, and the job either reported exit 0
|
|
having done nothing (`tools/amd-prove/pc1-cpu-prove.ps1`, first version: an apostrophe inside a single-quoted awk
|
|
program) or failed in 4 s (the 0.3.10 installer job). The file shape keeps the body readable by `bash -n` before it runs;
|
|
`pc1-cpu-prove.ps1` does that in the job itself. `tools/ci/bash-body-check.sh` fails CI on an inline body that does not
|
|
parse: it finds every body handed to bash (`bash -c "..."`, `bash -lc $var`, a `+` concatenation, a here-string written to a
|
|
file and run), unescapes it the way PowerShell would, and runs `bash -n` on it. A body it sees but cannot read fails too.
|
|
`--self-test` shows it firing on the fixtures under `tools/ci/fixtures/`. A job script is published from a worktree and
|
|
never passes CI before it runs, so `packaging/ota/publish-jobs.sh add --kind run` runs the same check (and
|
|
`tools/ci/prover-socket-check.sh`, the root-socket class; `bash -n` for a `.sh` script) on the script before anything is
|
|
signed, and refuses the publish with the check's output. `packaging/ota/test-publish-jobs.sh` proves the refusals.
|
|
The wiped-jobs-folder class (5 October 2026, 21:49Z): an app install clears the jobs folder, so a run job that uses a kit
|
|
fetched by an earlier fetch job tests the kit is there (Test-Path on the kit root or any file under it) before its first
|
|
use, and the fetch is republished under a new id after any app update. `tools/ci/kit-path-check.sh` fails CI and the
|
|
publish on a kit path used before that check.
|