Skip to content

release: cut the notarized pkg/dmg - version decision, Sparkle keys, notarization credentials #62

Description

@Adron

Summary

Ship the notarized .pkg + .dmg. This is orthogonal to parity and can run in parallel with every feature issue. The pipeline was audited end-to-end on 2026-09-05 and is sound; what remains is owner-held credentials, two open decisions, and the run itself.

Command-level detail lives in App-Dmg-Pkg-Deployment.md.

Two decisions the owner must make before anything is cut

1. The version number is inconsistent across three places

Where Value
MARKETING_VERSION (build settings) 0.1.0
releases/appcast.xml 0.0.1 — "Version 0.0.1 Alpha", enclosure InterlinedList-0.0.1-alpha.pkg
The tag step in the checklist v1.0.0

Pick one. ⚠️ The appcast enclosure filename must match what the script actually produces or Sparkle will 404 on every update check — a silent failure that only surfaces later.

2. The appcast URL is documented in two places

Info.plist's SUFeedURL points at https://interlinedlist.com/appcast.xml; the comment block inside releases/appcast.xml documents the feed as living at …/downloads/apple/appcast.xml. Harmless today, but reconcile so the served path and the polled path cannot drift.

Already fixed — do not re-litigate

notarize-and-package.sh derived the release version by reading CFBundleShortVersionString out of App/Resources/Info.plist, which stores the unexpanded $(MARKETING_VERSION). Every artifact would have been named InterlinedList-$(MARKETING_VERSION).pkg. It now resolves the value via xcodebuild -showBuildSettings and hard-fails with an actionable message if it is empty or still contains $(. Verified.

Also verified sound in the same audit: all 8 scripts/*.sh parse (bash -n), ExportOptions.plist is developer-id with automatic signing, the sync-agent embed paths and both entitlements files exist, the Sparkle path is fully wired (SparkleController + UpdatesMenuCommands, SUFeedURL set), and the appcast's minimumSystemVersion 15.0 matches MACOSX_DEPLOYMENT_TARGET.

Owner-held work (secrets and credentials — not delegable)

Sparkle keys

  • Generate the Ed25519 key pair: ./bin/generate_keys — store the private key in a password manager, never commit it
  • Paste the public key into App/Resources/Info.plistSUPublicEDKeyString (currently TODO_REPLACE_WITH_ED25519_PUBLIC_KEY)
  • Verify SUFeedURL and SUPublicEDKeyString resolve against the published appcast

Developer ID credentials

  • scripts/store-notarization-profile.sh (Apple ID, Team ID BJA9558E4B, app-specific password) → creates the NotarizationProfile Keychain item
  • GitHub Actions secrets (App-Dmg-Pkg-Deployment.md §1b): CERTIFICATES_P12, CERTIFICATES_P12_PASSWORD, CODESIGN_IDENTITY, INSTALLER_IDENTITY, NOTARIZATION_PASSWORD. ⚠️ The .env CODESIGN_IDENTITY / INSTALLER_IDENTITY values are placeholders — replace with real Developer ID certs.

The release run

  • scripts/notarize-and-package.sh (env per App-Dmg-Pkg-Deployment.md §3b) → .pkg + .dmg in releases/. This step also builds and embeds the Document Sync Agent.
  • ./bin/sign_update releases/InterlinedList-<version>.pkg; copy the edSignature and byte count into releases/appcast.xml, replacing TODO_REPLACE_WITH_SIGNATURE and length="0"
  • Upload .pkg, .dmg, .sha256 to https://interlinedlist.com/downloads/apple/
  • Publish releases/appcast.xml to the agreed feed URL (needs distribution infra on interlinedlist.com)
  • git tag v<version> && git push origin v<version> → triggers release.yml (draft GitHub release). Owner-driven, per project convention.
  • Publish the draft GitHub release

Backend prerequisite — gates a feature that already ships client-side

  • Run production migrations: npm run db:migrate:deploy. Two are pending: add_moderation_tables, add_moderation_versioning_sessions. Moderation ships in the client today and depends on these.
  • Resolve the GET /api/messages unauthenticated-behaviour decision (tracked with the backend asks).

Pre-flight

  • main is behind dev — catch it up before cutting.
  • Full E2E gate green on the commit being released.

Acceptance criteria

  • One version number, used consistently by the build, the appcast, and the tag.
  • A notarized .pkg installs on a clean machine and Sparkle finds the appcast.

Notes

work-consolidation.md §3a. The Document Sync Agent's on-device validation is a separate issue and is part of the same ship gate.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestneeds-decisionOwner decision required before any code

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions