Skip to content

Releases: jdx/packslip

v1.0.0: The format goes to version 1

Choose a tag to compare

@github-actions github-actions released this 05 Sep 03:46
0121abf

packslip declares its manifest format stable at version 1 and cuts the CLI and GitHub Action to 1.0.0. The rest of this release is a batch of fixes and small CLI additions found while wiring packslip into the release runs of the jdx.dev CLIs. packslip remains a work-in-progress proposal with only experimental mise support; version 1 fixes the field meanings, names, vocabularies, and selection rules that consumers rely on, but "version 1" of the format and the crate's semver are different numbers, and a future version 2 would be its own predicate type published alongside this one rather than a break of anything signed under release/v1.

Added

  • Platform scoping for packslip create --resource, so a release with a per-platform layout no longer needs a generated packslip.toml for a one-line difference. The scope goes after the kind head as @os, @os/arch, or @os/arch/libc; the @ is only split off the closed grammar of the kind, so an @ inside an exec argv or a repo path is left untouched. The Action's resources: lines pass through unchanged, so this works there with no new input. (#64, @jdx)

    packslip create --resource 'man@linux=archive:share/man/man1/tool.1'
    packslip create --resource 'completion/zsh@darwin/aarch64=archive:share/zsh/site-functions/_tool'
  • A --format FILENAME=FORMAT flag and a matching formats input on the Action, so a vendor can name an artifact's file type without a manifest when inference cannot read it from the name. The value stays open, so a vendor may declare a type this specification does not name. (#65, @jdx)

  • A tests/conformance/ suite of plain-JSON cases covering artifact selection, resource selection, tag parsing, and statement validity, for other implementations (mise's consumer being the immediate reader) to test against. (#62, @jdx)

Fixed

  • packslip create now infers format = "raw" for a bare executable whose name ends in a dotted version, such as mise-v2026.9.1-linux-x64. Previously the version tail was mistaken for an extension, no known format matched, and the bare artifact landed in the manifest with no format field at all, leaving a consumer nothing to go on. (#59, @jdx)
  • An archive resource source no longer applies to a bare-format artifact (raw, gz, xz, zst, bz2). An archive entry names a path inside the selected artifact, but a bare artifact has no paths inside it, so a consumer that picked the bare executable was being told to hunt for a file inside the binary. The same resource can still reach a bare artifact through an asset or repo source. Naming a bare artifact from an archive entry is now its own document error rather than being misreported as a platform-scope problem. This lets a project that ships both tarballs and a bare executable per platform collapse many hand-named entries into a single unscoped one. (#63, @jdx)
  • The packslip.dev/releases/v1 predicate URL, written into every signed release list, previously 404'd; it is now an alias onto the specification, and the generated JSON schemas now carry an $id naming their published URL. (#62, @jdx)

Changed

  • The GitHub Action's attest input gains a third mode, link. It writes the provenance links onto the manifest without re-attesting, for workflows where the build jobs already attested each artifact — the stronger claim, since the attestation is made by the job that did the build. GitHub serves an artifact's provenance at the same URL whoever attested it, so link needs no attestations: write permission. It belongs only in a workflow that really does attest every file it publishes, since an unattested artifact would leave a dead link. An unrecognized attest value now fails the step instead of being silently treated as false. (#60, @jdx)

Breaking Changes

  • Every artifact in a signed release must now declare a format. An artifact with no format is unselectable by construction — select_artifact skips it — so this is enforced in the spec, the JSON schema, validate (which now names the offending artifact), and packslip create (which refuses to write one and names the two ways out: set --format or leave the file out of artifacts). Broad artifacts globs that previously swept up non-installable files such as .dylib/.dll FFI libraries or C headers will now fail at create time until those files are excluded or given a format. (#65, @jdx)
  • The format is declared stable at version 1, and the CLI and Action move to 1.0.0. From this release the Rust API is covered by the crate's semver and checked by semver_check; a verify-only consumer takes the crate with default-features = false. (#62, @jdx)

Full Changelog: v0.3.1...v1.0.0

v0.3.1: Slim verify-only builds via optional Cargo features

Choose a tag to compare

@github-actions github-actions released this 05 Sep 02:19
6b81b37

A small release that makes the packslip crate's CLI, generator, and signing paths optional Cargo features, so verify-only consumers can pull in a much slimmer dependency graph. packslip remains a work-in-progress proposal with only experimental mise support; the release/v1 format and CLI may still change.

Changed

  • The crate is now split into additive Cargo features, all on by default, so the packslip binary and existing dependents are unaffected. A consumer that only verifies a manifest can take the crate with default-features = false, dropping the archive readers, the ELF/Mach-O/PE decoder, the Fulcio/OIDC and minisign signing path, the JSON Schema generator, and the CLI — roughly seventy fewer crates in the dependency graph. (#57, @jdx)

    cargo add packslip --no-default-features

    With defaults off you keep the statement types, verify, verify_release_list, select_artifact, and select_resources. Available features:

    Feature Adds
    cli (default) The packslip binary; implies the rest.
    create Build a statement from built artifacts; implies archive, linkage, sign.
    archive Read tar and zip archives to resolve declared executable paths.
    linkage Derive requires.libs from ELF, Mach-O, and PE executables.
    sign Sign statements, keylessly through Fulcio or with a minisign key.
    manifest Read a packslip.toml.
    schema Statement::schema() and ReleaseListStatement::schema().

Full Changelog: v0.3.0...v0.3.1

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
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

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 03 Sep 18:07

Full Changelog: v0.1.0...v0.2.0

v0.1.0

Choose a tag to compare

@github-actions github-actions released this 03 Sep 14:42