1 Commits
Author SHA1 Message Date
CarloandAllen Houchins 0594f653dd Propagate errors in macOS FMA install scripts (#50198)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #50056

## Summary

macOS FMA install scripts never checked the exit code of the install
command (`installer -pkg` / `cp -R`) — the script's last statement is
always `relaunch_application`, which exits 0 — so a failed install
exited 0 and Fleet reported it installed.

**Generated scripts.** The generator now propagates failure: both
`installer -pkg` variants end with `|| exit $?`, and the `cp -R` path
exits non-zero on a failed copy, removes the partial copy (so a failed
fresh install isn't inventoried as the new version), and restores the
app it moved aside. Regenerated `outputs/` for non-frozen generated apps
are produced by the `ingest-maintained-apps` job, so they aren't
committed here.

**Custom scripts.** 9 of the 18 custom input scripts had the same bug
and are fixed with the same pattern: Google Chrome, Zoom, Microsoft
Edge, GitHub Desktop, Webex, Cycling '74 Max, Pd, Grammarly Desktop, and
P4V. The DMG-based ones also now fail before removing/moving the
existing app when the mount or staging copy fails, so a bad download
can't leave a host with nothing. Their `outputs/*/darwin.json` are
updated in the same commit (script content + recomputed 8-char sha256
ref, versions untouched), following the precedent of #49033. Docker
Desktop (`set -euo pipefail`), 1Password/Slack/LogiTune (installer is
the last statement), and the rest already propagated errors.

**Frozen apps.** The ingest job never rewrites frozen outputs, so the 10
frozen apps with generated scripts (adobe-acrobat-pro, comet, evernote,
firealpaca, keeper-password-manager, nvidia-geforce-now, pritunl,
vnc-viewer, wins, worksheet-crafter) had the fix applied directly to
their published `darwin.json` scripts — the exact text the current
generator would emit, with pinned versions/URLs/hashes untouched. The
11th frozen app (logi-options+) uses a custom script that was already
correct and in sync.

# Checklist for submitter

- [x] Changes file added for user-visible changes in `changes/`
(`changes/50056-fma-install-scripts-ignore-errors`).
- [x] Untrusted data interpolated into shell scripts is validated
against shell metacharacters. (No new untrusted interpolation: the guard
reuses the same curated cask-derived name the adjacent lines already
interpolate.)

## Testing

- [x] Added/updated automated tests (three generator tests: pkg,
pkg-with-choices, cp-R restore — the last now pins the exact emitted
block).
- [x] All 19 updated output manifests validated: embedded scripts pass
`bash -n`, refs match `sha256(script)[:8]`, refs map stays key-sorted
like Go's encoder.
- [x] QA'd all new/changed functionality manually.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* macOS Fleet-maintained app installations now fail fast when
installers, DMG extraction/mounting, or app copy steps error.
* If an upgrade fails, the system removes any partial app and restores
the previously installed version when available.
* Improved robustness during app staging/copying, including safer
handling of paths with spaces or special characters.
* **Tests**
* Added unit coverage to verify installer failure propagation and
rollback behavior.
* **Documentation**
* Clarified that the install-script error handling applies to both
generated and custom scripts, including already-published frozen apps.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Allen Houchins <allenhouchins@mac.com>
2026-07-30 14:22:02 -05:00