SeaLegs releases must be reproducible, explicit about signing state, and consistent with the privacy-sensitive permissions used by the app.
0.x: public GitHub releases. The DMG is ad-hoc signed with Hardened Runtime, but is not signed with Developer ID and is not notarized by Apple.1.0and later stable releases: Developer ID signed and Apple notarized before publication.
Tag releases as vX.Y.Z. Keep CFBundleShortVersionString, the changelog, the
tag, the DMG filename, and the GitHub Release title on the same version.
For 0.x, the bundle version, tag, changelog entry, and release version remain
numeric (for example, 0.2.0 and v0.2.0). The DMG artifact directories and
filenames use the numeric version format.
- Confirm the release source is committed and the worktree is clean.
- Run
bundle install, thenbundle exec ruby SeaLegs/Scripts/generate_xcodeproj.rbfrom the repository root. - Confirm the generated
project.pbxprojand sharedSeaLegs.xcschemeare committed and unchanged after a second generator run. - Run
git diff --check. - Run the complete XCTest suite and read the xcresult summary.
- Run Xcode Analyze and a Release build.
- Confirm
README.md,README.ko.md,CHANGELOG.md,SECURITY.md, and the release notes are current. - Confirm privacy statements still match implementation.
- Scan the worktree and Git history with Gitleaks.
- Enable private vulnerability reporting before or immediately after the repository becomes public, then verify the reporting URL anonymously.
Build from a clean detached worktree at the exact release commit or tag. The
script refuses a dirty worktree unless --allow-dirty is supplied for local
validation. Do not use ExportOptions.plist for this path because that
file is reserved for Developer ID export.
A clean release build also requires an annotated vX.Y.Z tag at HEAD and
records it in BUILD_MANIFEST.txt. Dirty validation builds cannot write to the
canonical release directory; point them to a separate location instead:
SEALEGS_OUTPUT_DIR=/tmp/sealegs-validation \
./Scripts/build_dmg.sh --allow-dirty --overwritecd SeaLegs
./Scripts/build_dmg.shThe script:
- Regenerates the Xcode project with the requested version and build number.
- Archives an arm64 Release build with an ad-hoc signature and Hardened Runtime.
- Verifies bundle version
0.2.0, build2, architecture, and code seal. - Creates a compressed DMG containing
SeaLegs.appand anApplicationsshortcut. - Attaches the DMG read-only and verifies its mounted contents.
- Writes
SHA256SUMS.txtandBUILD_MANIFEST.txtonly after all checks pass.
Default output:
dist/v0.2.0/SeaLegs-0.2.0-arm64.dmg
dist/v0.2.0/SHA256SUMS.txt
dist/v0.2.0/BUILD_MANIFEST.txt
An existing artifact set is not replaced unless --overwrite is supplied.
Gatekeeper rejection is expected for this Developer ID unsigned and
unnotarized release and is recorded in the manifest; it is not a build failure.
cd dist/v0.2.0
shasum -a 256 -c SHA256SUMS.txt
hdiutil verify SeaLegs-0.2.0-arm64.dmgAlso test from a fresh macOS user account:
- Open the DMG and drag SeaLegs to Applications.
- Attempt the first launch and confirm Gatekeeper blocks it.
- Use System Settings > Privacy & Security > Open Anyway.
- Confirm the manual overlay works without Screen Recording permission.
- Confirm the Adaptive permission guidance, restart, and Refresh flow.
- Confirm the app process exits after Quit.
Do not instruct users to disable Gatekeeper globally or use xattr as the
primary installation path.
- Push the verified release commit to
main. - Create and push an annotated tag such as
v0.2.0. - Create a GitHub Release.
- Use the changelog entry as the release body.
- Attach the DMG,
SHA256SUMS.txt, andBUILD_MANIFEST.txt. - Download the published assets again and verify their size and SHA-256.
For the planned 1.0 stable release, use a Developer ID certificate and a configured notarization keychain profile.
cd SeaLegs
xcodebuild archive \
-scheme SeaLegs \
-configuration Release \
-archivePath build/SeaLegs.xcarchive
xcodebuild -exportArchive \
-archivePath build/SeaLegs.xcarchive \
-exportPath build/export \
-exportOptionsPlist ExportOptions.plist
ditto -c -k --keepParent build/export/SeaLegs.app build/SeaLegs.zip
xcrun notarytool submit build/SeaLegs.zip \
--keychain-profile "notary-profile" \
--wait
xcrun stapler staple build/export/SeaLegs.app
xcrun stapler validate build/export/SeaLegs.app
spctl --assess --type execute --verbose=4 build/export/SeaLegs.appTest the transition from the final ad-hoc release to the Developer ID build before 1.0 because Screen Recording and Input Monitoring permissions may need to be granted again when the code identity changes.
- Verify the GitHub Release tag and target commit.
- Verify every uploaded asset and checksum.
- Confirm the repository visibility and public unauthenticated access.
- Confirm private vulnerability reporting is enabled.
- Start a new empty
Unreleasedsection inCHANGELOG.md.