Skip to content

feat(release): publish signed archives for Linux, macOS and Windows with install scripts - #4

Merged
HuiJun merged 9 commits into
developfrom
feat/release-line
Oct 30, 2026
Merged

HuiJun merged 9 commits into
developfrom
feat/release-line

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Gives SysPI the same binary line as OpenSysML, GitHub Actions only, so that package signing is in place from the first release.

release.yml (tag v*): gate (ubuntu, macos, windows: build, vet, gofmt, tidy, tests) → publish → validate-install. Nothing is published from a red tree. publish runs scripts/build-release-artifacts.sh <tag>, which cross-builds six static archives (CGO_ENABLED=0 -trimpath -ldflags "-s -w -X main.Version=<tag>"), checks every binary carries the tag, and writes SHA256SUMS.txt:

syspi-{linux,darwin}-{amd64,arm64}.tar.gz   syspi + LICENSE (GNU tar, SOURCE_DATE_EPOCH → reproducible)
syspi-windows-{amd64,arm64}.zip             syspi.exe + LICENSE
SHA256SUMS.txt, SHA256SUMS.txt.bundle

The manifest is signed keyless with cosign sign-blob (OIDC identity …/.github/workflows/release.yml@refs/tags/vX.Y.Z), verified in-job against the same regexp install.sh --verify-signature uses, then gh release create --verify-tag with notes taken from the tag's CHANGELOG.md section. validate-install then runs the published one-liners on all three systems.

Installers install.sh / install.ps1 at the repo root (curl … | sh, irm … | iex): --version <tag>|latest, --prefix/--bin-dir (-InstallDir), --os/--arch, --base-url, --verify-signature (sh), --dry-run, SYSPI_* env twins. latest resolves through the /releases/latest redirect and falls back to /latest/download for mirrors. The manifest is fetched before the archive, the archive digest is checked before anything is written, the install is atomic, and the binary is run once (syspi version) and must report the tag; a foreign --os/--arch is staged, not run.

Tests: scripts/install-test.sh builds real fake releases with the build script, serves them with scripts/install-test-server.py, and drives both installers through 20 bash cases and 15 PowerShell cases (tag/latest/mirror/dry-run/foreign platform, tampered archive, conflicting digests, binary reporting another version, missing asset, unknown release, bad inputs, unwritable prefix). ci.yml runs it on ubuntu, macos and windows (install-scripts job), adds windows to the Go gate, validates fragments (changelog-fragments job), and pins actions to commit SHAs.

Changelog: scripts/changelog.py check | release x.y.z | release-notes x.y.z folds changes/unreleased/ into CHANGELOG.md on the release branch (OpenSysML style; no CHANGELOG.md is created here). The stale fragments that described index emit / pkg:sysand and then removed them are rewritten into what 0.1.0 actually ships. README gains the install section; CONTRIBUTING documents the release procedure (release/x.y.z → develop → main → tag).

Not included, can follow as separate jobs: Authenticode/MSI for the Windows exe, Homebrew/Scoop/winget, nightly channel, SBOM/SLSA.

Verified locally: reproducible archives (two builds with the same SOURCE_DATE_EPOCH → identical SHA256SUMS.txt), scripts/install-test.sh all 35 cases passing, shellcheck and PSScriptAnalyzer clean. The tag workflow itself has not run yet: it needs main and v0.1.0.

…ith install scripts

The v* tag runs the gate on all three systems before anything is published, builds
syspi-<os>-<arch>.tar.gz (.zip on Windows) for amd64 and arm64 with LICENSE inside,
signs SHA256SUMS.txt with cosign keyless (identity: release.yml on the tag) and creates
the release with the CHANGELOG.md section as its notes; install.sh and install.ps1
install a release after checking the archive against the manifest and the binary against
the tag. scripts/install-test.sh runs both installers against a fake release served
locally; CI runs it on ubuntu, macos and windows. scripts/changelog.py folds the
fragments at release time; the fragments are rewritten to describe what 0.1.0 ships.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

…outs

scripts/release-archive (archive/tar, archive/zip) replaces GNU tar and zip, which the
Windows runner's bash lacks and macOS has only through brew, and makes the archives
byte-identical across hosts for one SOURCE_DATE_EPOCH. .gitattributes pins LF so gofmt
passes on the Windows gate; ci.yml moves to the Node 24 checkout/setup-go pins release.yml uses.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
devin-ai-integration Bot and others added 5 commits October 30, 2026 01:22
Get-Content of a one-line file is a string on Windows PowerShell, so [0] was its first character.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
MSYS sha256sum defaults to binary mode and marks names with '*', which the
installer tests on Windows did not match; the script now asserts the six
'<sha256>  <archive>' lines.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
GitHub's pwsh step hands back the exit code of the last native command, which is an
installer expected to fail.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
develop now installs mercurial and subversion on the Windows runner and requires
them; the release gate mirrors that instead of letting their tests skip.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
@devin-ai-integration
devin-ai-integration Bot marked this pull request as ready for review October 30, 2026 02:04
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration Bot and others added 2 commits October 30, 2026 02:08
…releases; -VerifySignature on Windows

The publish job's identity check looked for install.sh after cd dist, so no release
would have been created. The tag check allowed v1.2.3-rc.1 while the signing identity
regexp did not; both installers now accept the prerelease suffix. install.sh no longer
lets head's status hide a failing 'syspi version'. install.ps1 gains -VerifySignature
(cosign, same issuer and identity as install.sh), both suites cover asking for a
signature the release lacks, and the README states what the checksum does and does
not defend against.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
@HuiJun
HuiJun merged commit 66cbf99 into develop Oct 30, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant