Skip to content

ci(release): sign and publish through the shared workflow - #87

Merged
MotherSphere merged 4 commits into
mainfrom
ci/shared-signing
Oct 8, 2026
Merged

MotherSphere merged 4 commits into
mainfrom
ci/shared-signing

Conversation

@MotherSphere

Copy link
Copy Markdown
Member

Colony's release now signs and publishes through the organisation's shared workflow, Project-Colony-Resources/.github/workflows/sign-and-publish.yml, pinned at 619460ff4dc0049f129955f0988d368427b9eedb. It also adds what SignPath Foundation needs before it can Authenticode-sign colony-windows.exe. SignPath stays off: signpath-project-slug is commented out until the project is accepted.

Release workflow (release-please.yml)

  • The build legs now only build, smoke-test and upload each binary as an artifact (build-<asset>). They no longer upload to the release.
  • The sign job is replaced by sign-and-publish, which calls the shared workflow. It checks that the release is still a draft, runs Authenticode through SignPath once enabled, then writes .sig, .meta and .meta.sig over the final bytes. It uploads everything to the draft, downloads it again, verifies every signature and digest, and only then publishes. Authenticode rewrites the PE, so the ed25519 signing has to come after it.
  • These guarantees are unchanged:
    • The same 16 assets: colony-linux, colony-windows.exe, colony-macos and colony-macos-x86, each with .sig, .meta and .meta.sig. These are the names launcher_asset_name() and the self-update download ask for.
    • The same .meta format, byte for byte.
    • The draft hold after release-please, and the target job that refuses a published tag.
    • The smoke tests and the macOS x86 architecture check.
    • aur-publish.yml, still chained with needs: after signing. It is a workflow_call, so the GITHUB_TOKEN publish inside the shared workflow does not need to trigger anything.
  • The release legs have no rust-cache, because SignPath forbids reusing unverified build outputs.
  • Permissions are now set per job, with permissions: {} at the top. The build legs get contents: read, and their checkout does not persist credentials, because they run every dependency's build script.
  • The Windows leg checks VersionInfo.ProductName == "Colony" and ProductVersion == <tag without v> right after the smoke test.
  • The two secrets are passed by name, never with inherit.
  • release-type: rust is kept. I corrected the comment that explained why. It said manifest mode would change the action's outputs. In release-please-action v5 both modes go through the same outputReleases, and the root package's outputs are unprefixed. The accurate reason for the gh-based draft hold is simpler: the action ignores config files whenever release-type is set.
  • Recovery dispatches should now start from the tag: gh workflow run release-please.yml --ref vX.Y.Z -f tag=vX.Y.Z. With SignPath on, the shared workflow refuses a run whose commit is not the tag's.

Windows version resource

  • build.rs uses winresource (no default features, so it only adds version_check, which is already in the lockfile). It embeds ProductName and FileDescription "Colony", and ProductVersion and FileVersion from CARGO_PKG_VERSION. It does this only when CARGO_CFG_TARGET_OS is windows.
  • The Windows CI leg builds colony.exe and checks both fields, so this PR proves it on windows-latest. The checks use -cne, because PowerShell's -ne ignores case and the crate default would be "colony".
  • Checked locally with a cross-build to x86_64-pc-windows-msvc (llvm-rc and lld-link with an xwin sysroot). The release colony.exe carries a VERSIONINFO resource with ProductName Colony, ProductVersion 0.10.4, FileVersion 0.10.4 and FileDescription Colony.

README

  • New ## Code signing policy section with the SignPath Foundation attribution, the team roles, and a note that Windows builds ship without Authenticode until SignPath accepts the project.
  • A privacy policy written from the code. Colony contacts only GitHub, has no telemetry, and the policy says what is sent and when:
    • the catalogue fetch at start and on Refresh;
    • update checks, on by default;
    • downloads on install or update;
    • the optional GitHub device-flow sign-in.
  • The shared workflow links release notes to this anchor.
  • docs/release-signing.md and the template pointer now describe the new flow.

Checked locally

  • cargo fmt --check, cargo clippy --all-targets -- -D warnings and cargo test (150 passed), all with isolated XDG dirs.
  • Every workflow YAML parses.
  • The Windows cross-build and its version resource.
  • Not checked locally: the MSRV (1.88) leg, because no 1.88 toolchain is installed here. CI covers it.

Only proven at the next release

  • The shared workflow end to end on Colony: artifacts, signing, upload, download and verify, then publish.
  • The release-leg VersionInfo check against the tag.
  • The AUR job after sign-and-publish.
  • The "Code signing policy" link in the release notes.
  • Merging the next release PR exercises all of these. If anything fails, the release stays a draft, and "Re-run failed jobs" or a dispatch from the tag finishes it.

SignPath signs only an executable whose ProductName is the project name and
whose ProductVersion is set. build.rs now embeds ProductName and
FileDescription "Colony" and ProductVersion and FileVersion from
CARGO_PKG_VERSION, through winresource without default features, and only
when the target is Windows. The Windows CI leg builds colony.exe and fails
if either field is not what is expected.
The build legs now only build, smoke-test and upload each binary as an
artifact. The new sign-and-publish job calls
Project-Colony-Resources/.github/workflows/sign-and-publish.yml, pinned by
commit, which checks the draft, Authenticode-signs colony-windows.exe through
SignPath once signpath-project-slug is set, writes .sig, .meta and .meta.sig
over the final bytes, uploads them to the draft, downloads and verifies them,
and publishes. Asset names, the .meta format, the draft hold and the AUR job
chained after signing are unchanged.

Also: no build cache in the release legs (SignPath forbids it), a read-only
token without persisted credentials for the build legs, per-job permissions,
a check of the Windows version resource against the tag, and a corrected note
on why the draft hold is a gh call.
The README gets the "Code signing policy" section SignPath Foundation asks
for, with the team roles and a privacy policy that lists every server Colony
contacts, when, and what it sends, as the code does it. The release signing
guide and the workflow template pointer now describe the shared
sign-and-publish workflow and the Authenticode step before ed25519 signing.
@MotherSphere
MotherSphere merged commit 350b649 into main Oct 8, 2026
5 checks passed
@MotherSphere
MotherSphere deleted the ci/shared-signing branch October 8, 2026 11:26
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