Skip to content

Fix the released zip opening as a damaged app - #649

Merged
hannesa2 merged 1 commit into
gitx:masterfrom
goneng:fix-release-zip-symlinks
Sep 15, 2026
Merged

hannesa2 merged 1 commit into
gitx:masterfrom
goneng:fix-release-zip-symlinks

Conversation

@goneng

@goneng goneng commented Sep 14, 2026 •

Copy link
Copy Markdown
Collaborator

zip -r follows symlinks unless it is given -y, so the zip assets on the
releases page carry no symlinks at all. Every embedded framework has its
Versions/Current stored as a second copy of the directory instead of a link to
Versions/A, which leaves the bundle unverifiable, and macOS tells whoever
downloads it that the app is damaged and should be moved to the Trash.

The dmg is built a few lines earlier with hdiutil create -srcfolder, which
preserves the links, so only the zip is affected. Homebrew installs the dmg,
which is why this has gone unnoticed.

Changes

  • Pack with zip -r -y, which stores the symlinks rather than following them
  • Keep the packing quiet unless VERBOSE is set, since naming every file adds
    594 lines to a release log

Test plan

Packing a known-good signed GitX.app three ways and verifying the extracted
copy with codesign --verify --deep --strict:

packed with extracted with unzip extracted with ditto -x -k size
zip -r (before) fails, 0 symlinks fails, 0 symlinks 13.9 MB
zip -r -y (this) passes, 19 symlinks passes, 19 symlinks 5.96 MB
ditto -c -k fails, 593 ._* files passes, 19 symlinks 6.18 MB

ditto was the first attempt here. It only verifies when it is also the
extractor: unzipped, it scatters AppleDouble files and codesign reports a sealed resource is missing or invalid. zip -y holds up under both.

  • make -n package-signed expands as expected with the default variables and
    with the ones the workflow passes (EXPORT_DIR=., ZIP=GitX-arm64.zip), and
    drops -q under VERBOSE=1
  • The published GitX-arm64.zip for 1.5.7 reproduces the user-visible symptom:
    extract, launch, and macOS offers to move the app to the Trash. The 1.5.7 dmg
    launches normally.

Gatekeeper was not re-tested end to end: the bundle used here is Development
signed rather than notarized, so spctl rejects it whatever packs it. The
codesign results above are the meaningful ones.

`zip -r` follows symlinks unless it is given `-y`, so the zip assets on
the releases page carry no symlinks at all. Every embedded framework
has its `Versions/Current` stored as a second copy of the directory
rather than a link to `Versions/A`, which leaves the bundle
unverifiable, and macOS tells whoever downloads it that the app is
damaged and should be moved to the Trash.

The dmg is built a few lines earlier with `hdiutil create -srcfolder`,
which preserves the links, so only the zip is affected. Homebrew
installs the dmg, which is why this has gone unnoticed.

* Store the symlinks rather than following them, so the frameworks keep
  the layout the signature was made over
* Leave the packing quiet unless VERBOSE is set, since naming every
  file adds close to six hundred lines to a release log
@goneng
goneng force-pushed the fix-release-zip-symlinks branch from cc95307 to 2bfb037 Compare September 14, 2026 22:21
@goneng
goneng marked this pull request as ready for review September 14, 2026 22:30
@goneng goneng added pipeline CI pipeline bugfix and removed pipeline CI pipeline labels Sep 14, 2026
@hannesa2 hannesa2 added pipeline CI pipeline and removed bugfix labels Sep 15, 2026
@hannesa2
hannesa2 merged commit c6b5946 into gitx:master Sep 15, 2026
3 checks passed
@goneng
goneng deleted the fix-release-zip-symlinks branch September 15, 2026 05:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pipeline CI pipeline

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants