ReviewOS

pantry-pm/pantry

feat(release): add macOS App Store and S3-compatible distribution targets

#219
Open chris opened this 2 months ago ·
2 months ago

Goal

Extend Pantry's existing release action without weakening its current GitHub Release behavior. A release should still produce one changelog, one immutable artifact set, checksums, and attached binaries, then optionally mirror or submit those same verified artifacts to additional destinations.

This is the distribution companion to the Stacks desktop/App Store work. The Stacks issue will link back here once created.

Current behavior to preserve

  • GitHub Release creation remains the source of truth.
  • Automatically generated changelogs remain attached to the release.
  • Release binaries and checksum files remain attached.
  • Existing action inputs remain backward compatible.
  • Rerunning a release remains safe and idempotent.

macOS App Store target

Add an opt-in release target for a prebuilt, already signed Mac App Store .pkg:

  • Validate the package signature before network mutation (pkgutil --check-signature).
  • Validate the package with App Store Connect before upload.
  • Authenticate with App Store Connect API key ID, issuer ID, and a .p8 key supplied only through secrets.
  • Upload through an Apple-supported CLI path (xcrun altool or Transporter/JWT), with clear structured errors.
  • Support validate-only, upload, and retry-existing-build modes.
  • Record the bundle ID, marketing version, build number, SHA-256, and App Store Connect delivery ID in a release manifest.
  • Never attempt to generate Apple signing identities or accept legal agreements inside the release action.
  • Keep signing/package construction in the calling project's build workflow; Pantry owns validation, upload, release metadata, and artifact integrity.

Apple references:

Hetzner S3-compatible registry target

Add an opt-in S3-compatible mirror suitable for Hetzner Object Storage:

  • Inputs: endpoint, region, bucket, prefix, public base URL, path-style toggle, cache-control policy, and optional channel (stable, beta, etc.).
  • Secrets: access key ID and secret access key.
  • Upload the exact GitHub Release artifact bytes, checksum file, changelog, and a machine-readable release manifest.
  • Use deterministic keys such as <prefix>/<project>/<version>/<artifact> plus atomic channel metadata (latest.json).
  • Verify uploaded object size/checksum where the provider supports it.
  • Set correct content types and immutable caching for versioned artifacts; short caching for channel pointers.
  • Permit private buckets and optional presigned/public URLs without logging credentials.
  • Be provider-neutral enough to work with AWS S3, Cloudflare R2, MinIO, and Hetzner.

Action/API shape

Suggested opt-in inputs:

  • release-macos-app-store
  • release-macos-package
  • release-app-store-validate-only
  • release-s3
  • release-s3-endpoint
  • release-s3-region
  • release-s3-bucket
  • release-s3-prefix
  • release-s3-public-base-url
  • release-s3-path-style

Suggested secrets/environment:

  • APP_STORE_CONNECT_API_KEY_ID
  • APP_STORE_CONNECT_API_ISSUER_ID
  • APP_STORE_CONNECT_API_KEY
  • S3_ACCESS_KEY_ID
  • S3_SECRET_ACCESS_KEY

Safety and observability

  • Redact every credential in logs and process output.
  • Fail before upload when artifacts/checksums do not match.
  • Emit a dry-run/plan showing destinations and object keys without secrets.
  • Distinguish build/signing failures (caller responsibility) from validation/upload failures (Pantry responsibility).
  • Use bounded retries for transient provider errors and never create duplicate immutable versions.
  • Preserve a JSON receipt as a GitHub Release asset.

Tests

  • Input schema and backward compatibility tests.
  • App Store validate-only/upload command construction tests with a fake runner.
  • S3 endpoint/path-style/key layout/content-type tests.
  • Idempotent retry tests.
  • Secret redaction tests.
  • End-to-end fixture against a local S3-compatible server.
  • Release-action fixture proving changelog, binaries, checksums, GitHub Release, and optional mirrors all reference identical bytes.

Acceptance criteria

  • Existing GitHub-only release consumers require no changes.
  • A signed Mac App Store package can be validated and uploaded using API-key auth.
  • A release can be mirrored to Hetzner Object Storage with deterministic keys and verified checksums.
  • The GitHub Release, App Store receipt, and S3 manifest all identify the same source revision and artifact hashes.
  • Documentation includes a least-privilege secret setup guide and a Stacks example.
  • CI covers dry-run, idempotency, redaction, and S3 integration behavior.
8 days ago

Stacks implementation and Apple provisioning tracker: stacksjs/stacks#2199.

8 days ago

Integration evidence from stacksjs/stacks: the Pantry action successfully generated changelog-based release notes and attached all five Buddy binary archives for v0.70.212, while the clean npm install and downstream Homebrew job also passed: https://github.com/stacksjs/stacks/actions/runs/30403752773.

That confirms the existing GitHub-release path remains the baseline. This issue should add Mac App Store/App Store Connect and S3-compatible (including Hetzner) destinations without regressing those release notes, checksums, binary attachments, or retry/reconciliation guarantees. The Stacks-side Apple workflow is tracked at stacksjs/stacks#2199.

8 days ago

Implemented the provider-neutral release and Apple automation layers on main and shipped the new minor tag v0.11.0.

Delivered:

  • Pantry Action Mac App Store validation/upload with API-key auth, validate-only and duplicate-safe retries
  • provider-neutral S3 mirroring for Hetzner/AWS/Backblaze, deterministic keys, immutable assets, latest.json, checksums, and receipts
  • shared ts-pantry App Store Connect client for Bundle IDs, capabilities, certificates, profiles, app/version reconciliation, build polling, and build attachment
  • ts-pantry app-store:csr and app-store:provision plan/apply automation with no-overwrite keys, no certificate revocation, downloaded profiles/certificates, and optional P12 export
  • release receipts containing bundle ID, marketing version, build number, source revision, SHA-256, and delivery ID
  • least-privilege setup guidance and Stacks workflow integration

Verification: 396 focused Pantry/Action tests pass (6 integration tests skipped), plus TypeScript typecheck, focused lint, Action build, compiled CLI smoke test, and Zig credential tests. Follow-up CI fixes for Redis OpenSSL ABI metadata and Zig portability are also on main and will be included in the next patch after the v0.11.0 publication completes.

Stacks integration remains tracked in stacksjs/stacks#2199.

8 days ago

Final shipped checkpoint:

  • The generic macOS/App Store distribution surface is Pantry-owned, not Stacks-owned. Pantry v0.11.0 introduced the App Store Connect client, provisioning CLI, Mac App Store Action delivery, receipts, and provider-neutral S3 mirroring; the hardened current release is v0.11.5: https://github.com/pantry-pm/pantry/releases/tag/v0.11.5
  • v0.11.5 published seven platform archives plus release-manifest.json and all npm workspaces, including ts-pantry@0.11.5: https://github.com/pantry-pm/pantry/actions/runs/30411647401
  • The Action preserves GitHub changelogs/releases and immutable artifacts, validates signed Mac App Store packages before API-key upload, supports validate-only and duplicate-safe retries, and records bundle/version/build/source/hash/delivery metadata.
  • S3 mirroring supports Hetzner, AWS, Backblaze, and compatible endpoints with deterministic immutable keys, checksums, receipts, latest.json, path-style or virtual-hosted addressing, and plan-only mode.
  • Apple automation covers CSR/private-key generation, P12 export, Bundle IDs, capabilities, certificates, profiles, safe provision plan/apply, app/version reconciliation, build polling, and build attachment. It does not pretend enrollment, contracts, banking/tax, privacy, age rating, or owner review decisions are automatable.
  • Verification includes 59 Pantry Action tests, full TypeScript and Zig CI, typecheck, lint, Action bundle portability checks, secret/redaction and idempotency coverage, a live pinned Redis service fixture, and clean release setup with canonical Zig lock metadata: https://github.com/pantry-pm/pantry/actions/runs/30411583185

Stacks integration and Buddy commands are tracked in stacksjs/stacks#2199. This issue remains open for the two credentialed integration fixtures that public CI cannot honestly supply: an Apple-account signed package validation/upload and a local/private S3 end-to-end server proving identical remote bytes. Those fixtures should use the same receipt/hash contract already shipped.

Sign in to comment on this issue.