-
Notifications
You must be signed in to change notification settings - Fork 0
issue 86 macos pkg install scripts
- Parent: #86 macos: pre/post-install script サポート
- Sub-issues: #87 manifest model/validation, #88 Graph payload mapping/publisher wiring, #89 documentation, #90 samples/tests
The operator distributes PowerShell 7 for macOS through a real Intune tenant using a pre-install script (removes a Homebrew-installed pwsh, removes a stale pwsh symlink, checks free disk space) and a post-install script (verifies the install, adds /usr/local/bin to /etc/paths.d). Relaypublisher's manifest currently has no way to express this.
The Graph API already supports it (verified via Microsoft Learn):
-
macOSPkgApphaspreInstallScript/postInstallScript, typedmacOSAppScriptwith a singlescriptContentproperty (base64-encoded.sh). -
macOSLobApp/macOSDmgAppdo not have this property — it isAppType: pkg(beta-only) exclusive. - Constraints (https://learn.microsoft.com/intune/app-management/deployment/add-unmanaged-pkg-macos):
- Each script must be under 15360 characters.
- Requires Intune management agent for macOS 2309.007+.
- A non-zero pre-install exit code fails the install; it is retried on the next device check-in.
- Post-install failure is not reported (the app still reports "success").
doc/01-manifest-schema.md §5.4 already documents this constraint in its comparison table ("pre/post install script: lob=no / pkg=yes"), but no schema field, validation, or Graph mapping exists yet.
- Platform: macos
Architecture: arm64
InstallerType: pkg
AppType: pkg
DisplayName: PowerShell [macOS Arm64]
Scripts: # optional, AppType: pkg only
PreInstall: scripts/macos/powershell/preinstall.sh
PostInstall: scripts/macos/powershell/postinstall.sh- Values are repository-relative paths (resolved from
--repo-root), the same convention asIconandDetection.ScriptFile. - Either
PreInstallorPostInstallalone is allowed; theScriptsblock itself is optional.
-
AppType: loborPlatform: windowswith aScriptsblock is a validation error — Graph has no such property there. - Script content is not included in the deterministic inputHash — same precedent as
Icon/Detection.ScriptFile. The app metadata PATCH (UpdateAppAsync) always runs on publish, so script edits are picked up without forcing a full re-upload of a package that can be up to 8 GB. -
PlanService.EnumerateReferencedFilesis extended to include the script paths, soscripts/**changes are picked up by changed detection. - Line endings are normalized CRLF → LF immediately before base64 encoding (a Windows-checked-out
.shwith CRLF breaks the shebang on macOS). - A UTF-8 BOM is a validation error (a BOM before the shebang prevents the script from launching).
- A file not starting with a shebang (
#!) is a validation error, per Intune's shell-script prerequisites.
ManifestValidator (pure, no I/O):
-
Scriptsset onPlatform: windows→ error -
Scriptsset onAppType: lob→ error -
PreInstall/PostInstallfailing path-safety checks (traversal, absolute path) → error - Extension other than
.sh→ error -
Scriptsblock present but both fields null → error
ManifestAssetValidator (needs --repo-root, same location as the Icon checks):
- File does not exist → error
- 15360 characters or more → error
- UTF-8 BOM present → error
- Does not start with a shebang → error
- Core model/validation:
MacOsScriptsManifest.cs(new),AppManifest.cs,ManifestValues.cs,ManifestValidator.cs,ManifestAssetValidator.cs - Publish path:
MacOsAppPayload.cs,MacOsAppPayloadMapper.cs,ManifestAssetReader.cs,MacOsAppPublisher.cs,Planning/PlanService.cs - Docs:
doc/00-overview.md§6.13,doc/01-manifest-schema.md§5.3/§5.4 (+ new §5.4.2),README.md/_ja,doc/05-operation.md/_ja,doc/06-troubleshooting.md/_ja,doc/issues/issue-020-macos-pkg-install-scripts.md(new),doc/relaypublisher-design-and-copilot-issues.md - Samples:
samples/scripts/macos/powershell/{preinstall,postinstall}.sh(new), PowerShell 7.6.5 macOS manifests,samples/manifests/README.md/_ja - Tests: MSTest additions across
ManifestValidationTests,ManifestAssetValidatorTests,MacOsAppPayloadMapperTests,GraphMacOsAppClientTests,ManifestLoaderTests,PlanServicereverse-lookup tests
- Script support for
macOSLobApp/macOSDmgApp(the Graph property does not exist there) - Managing standalone shell script policies (
deviceShellScript) - Script linting (shellcheck etc.) — left to the consuming repository's own CI
dotnet build IntuneLobPublisher.slnx
dotnet test IntuneLobPublisher.slnxdotnet run --project src/IntuneLobPublisher.Cli -- validate --repo-root samples --manifest-root manifests
dotnet run --project src/IntuneLobPublisher.Cli -- package --repo-root samples --manifest samples/manifests/Microsoft/Microsoft.PowerShell/7.6.5/powershell-macos-arm64.yaml --output out
dotnet run --project src/IntuneLobPublisher.Cli -- publish --repo-root samples --manifest samples/manifests/Microsoft/Microsoft.PowerShell/7.6.5/powershell-macos-arm64.yaml --package-dir out --dry-runNegative-path checks: a missing Scripts.PreInstall path, a Scripts block on an AppType: lob entry, and a .sh file over 15360 characters must each fail validate before any Graph call.
Real-tenant verification (optional, operator environment): after publish, confirm the Intune admin center shows the pre/post-install scripts on the app's "Program" tab, and that GET /beta/deviceAppManagement/mobileApps/{id} returns matching base64-decoded preInstallScript.scriptContent / postInstallScript.scriptContent.