Skip to content

v0.3.0: Discovery, resources, host requirements, and a hardened release path

Choose a tag to compare

@github-actions github-actions released this 05 Sep 00:42
· 15 commits to main since this release
433c0c0

packslip v0.3.0 is a large, format-shaping release for the draft release/v1 proposal. It defines how consumers discover and order releases, expands what a signed manifest can describe beyond executables, records what a release needs from the host, and hardens the CLI, GitHub Action, and release pipeline. packslip remains a work-in-progress proposal with only experimental mise support, and this release changes the version 1 format and CLI incompatibly.

Highlights

  • Discovery and ordering are now specified: releases are found through GitHub tag discovery or a signed release list, and versions are ranked by semver precedence derived from the version string rather than separate signed fields or list order.
  • A manifest can describe far more than binaries: resources (completions, man pages, usage CLI specs, agent skills, desktop/icon/app entries), host requirements (shared libraries and required commands), open extensions for vendor- and consumer-defined data, and per-platform/per-artifact scoping.
  • The release path is finished end to end: notarized macOS arm64, a native Windows arm64 build, crates.io publishing via Trusted Publishing, an attested CLI spec shipped with each release, and a GitHub Action that can run a caller-supplied CLI.

Added

  • Release discovery and required release lists. A GitHub tag names a release's version (v?<version>, optionally after a monorepo subpath or the repo name), so consumers can enumerate versions with a single API call. Projects off a forge publish a signed releases/v1 list at .well-known/packslip/<path>.json; a forge project may commit a supplementary signed list to yank or flag releases. Third-party publishers (registries, mirrors, scanners) can publish per-vendor lists carrying evidence and the vendor's tag, trusted per host. (#27, ec657a1 by @jdx)
  • Explicit artifact selection. Selection is a defined algorithm — absent os/arch/libc match any host, unlabelled artifacts are the default, most specific match wins, then the consumer's format preference, and a tie is a vendor error — exported as select_artifact. New formats gz, xz, zst, bz2, and tar are recognized, and a .exe is treated as a program unless its name says setup or install. (#27 by @jdx)
  • A resources list describing what a release ships beyond executables: completion, man, cli-spec (usage format), skill, desktop, icon, and app, each with exactly one verifiable source (archive, asset, repo, or exec), plus a usage CLI spec so consumers can derive completions, man pages, and docs without running vendor code at install time. Unknown kinds are allowed and ignored. Author via packslip create --resource KIND[/QUALIFIER]=SOURCE:VALUE (repeatable) or the Action's resources input. (#5, #33, #37, #41 by @jdx)
  • Resource scoping. Resources can be scoped by os/arch/libc for platform-specific layouts, and further scoped to one exact artifact filename, ranked ahead of platform-only entries. (#43 by @jdx)
  • Host requirements. Artifacts can declare what the host must already provide, in OS-resolved names rather than package names: requires.libs (shared libraries the binaries load, populated by create opening archives and parsing ELF/Mach-O/PE headers, with the C runtime baseline filtered out) and requires.bin (required commands via --require bin:NAME[@MIN]). Use --no-libs to skip opening archives; verify and create print per-artifact requirements. (#32 by @jdx)
  • extensions objects on the release predicate, each artifact and resource, and the release list and its entries, for vendor- (by domain) and consumer- (by name) defined JSON that never collides with a future field. Set release-level values with packslip create --extension NAME=JSON or the Action's extensions input. (#26 by @jdx)
  • Vendor-selected latest version. An optional signed release-list latest pointer lets a vendor recommend a specific version (for example, ship 3.0.0 while recommending 2.8.4). Set it with packslip releases --latest VERSION; resolution falls back to the GitHub latest pointer, then highest eligible semver. (#46 by @jdx)
  • TOML release manifests. packslip create --manifest release.toml describes per-artifact executables, formats, requirements, variants, portability, and scoped resources; CLI flags override it and positional artifacts merge with it. --bin tool is resolved to its real path inside an archive using pure-Rust decoders, and --provenance FILENAME=URL / releases --evidence URL=KIND[=DETAIL] are supported. (#27 by @jdx)
  • A generated CLI reference published on packslip.dev, kept in sync with the CLI via usage. (#15 by @jdx)
  • macOS arm64 releases are now signed and notarized, and a native Windows arm64 build ships (replacing darwin-x64, which Rosetta 2 covers); crates.io publishing moved to Trusted Publishing. (#54 by @jdx)
  • Each release now publishes packslip.usage.kdl as an attested asset and includes it as a verified cli-spec resource in the signed manifest. (#45 by @jdx)
  • The GitHub Action can run a caller-supplied packslip binary via packslip-path (a path or a name on PATH), skipping the download and its attestation check — useful on platforms packslip does not ship or on restricted runners. A binary the action did not download is not verified; the job vouches for it. (#55 by @jdx)

Fixed

  • create refuses two different assets that share a file name instead of silently collapsing them and giving a later resource the wrong digest. (#17 by @jdx)
  • Android detection now recognizes the armv7-linux-androideabi triple, which was previously misrecorded as linux/gnu. (#31 by @jdx)
  • The Windows install path in the Action unpacks release zips so packslip.exe lands on PATH. (#55 by @jdx)

Changed

  • The GitHub Action and CLI are now versioned in lockstep. For the current 0.x line, use jdx/packslip@v0; the former v1 alias no longer advances on 0.x releases. The explicit packslip-version override remains available. (#49 by @jdx)

Breaking Changes

  • Versions must be semver 2.0.0 (calver such as 2026.9.1 qualifies); create, releases, and verify reject anything else. The prerelease, channel, and version_order fields are removed from the predicates: a prerelease is a version with a prerelease part, the channel is derived from it, and consumers always rank by semver precedence rather than list order. The corresponding --prerelease, --channel, and --version-order flags and Action inputs are gone; verify still reports prerelease and channel, derived at read time. (#18 by @jdx)
  • The supersedes field and --supersedes flag are removed. Rollback protection lives in the signed release list's sequence. Documents that still carry the field remain parseable, but create no longer emits it. (#16 by @jdx)
  • The top-level sbom field and --sbom flag are removed; an SBOM is now a resource kind with a digested source. A bare-format artifact's bin must be the artifact's own file. (#27 by @jdx)
  • The Action drops the sbom URL input and keys provenance by file name. (#27 by @jdx)

New Contributors

  • @jdx made their first contribution in #4

Full Changelog: v0.2.0...v0.3.0