Skip to content

issue 86 macos pkg install scripts_ja

Kazushi Kamegawa edited this page Aug 17, 2026 · 1 revision

Issue #86: macos — pre/post-install script サポート(sub-issue #87 / #88 / #89 / #90 を含む)

English

Tracking

Context

ユーザーは実運用の Intune テナントで macOS 向け PowerShell 7 を配布する際、pre-install script(Homebrew 版 pwsh の除去、古い pwsh symlink 削除、空き容量チェック)と post-install script(インストール確認、/etc/paths.d への /usr/local/bin 追加)を使っている。Relaypublisher の manifest には現在これを表現する手段がない。

Graph API 側は対応済み(Microsoft Learn で確認済み):

doc/01-manifest-schema.md §5.4 の比較表には既に「pre/post install script: lob=不可 / pkg=可」と記載があるが、schema フィールド・validation・Graph mapping は未実装。

設計方針

manifest schema(app entry 直下、macOS AppType: pkg 限定)

  - Platform: macos
    Architecture: arm64
    InstallerType: pkg
    AppType: pkg
    DisplayName: PowerShell [macOS Arm64]

    Scripts:                                          # 任意。AppType: pkg のみ
      PreInstall: scripts/macos/powershell/preinstall.sh
      PostInstall: scripts/macos/powershell/postinstall.sh
  • 値は repository-relative path(--repo-root 起点)。Icon / Detection.ScriptFile と同じ扱い。
  • PreInstall / PostInstall は片方だけの指定も可。Scripts ブロック自体が任意。

実装上の決定事項

  1. AppType: lob / Platform: windows に Scripts があれば validation error(Graph 側にプロパティが無いため)。
  2. スクリプト内容は決定的 inputHash に含めない。Icon / Detection.ScriptFile と同じ前例。app メタデータの PATCH(UpdateAppAsync)は publish のたび無条件に走るため、スクリプト編集は最大 8 GB になり得る pkg の再アップロードを強制せずに反映される。
  3. PlanService.EnumerateReferencedFiles を拡張し、scripts/** の変更が changed detection に載るようにする。
  4. 改行コードは base64 化の直前に CRLF → LF へ正規化する(Windows で checkout された .sh が CRLF のままだと macOS 側で shebang が壊れる)。
  5. UTF-8 BOM 付きは validation error(shebang の前に BOM があるとスクリプトが起動しない)。
  6. shebang(#!)で始まらないファイルは validation error(Intune の shell script 前提条件)。

検証の層(Graph 呼び出し前にすべて fail させる)

ManifestValidator(純粋、I/O なし):

  • Platform: windows に Scripts → error
  • AppType: lob に Scripts → error
  • PreInstall / PostInstall が path-safety 違反(traversal、絶対パス)→ error
  • 拡張子が .sh 以外 → error
  • Scripts ブロックがあるのに両方 null → error

ManifestAssetValidator(--repo-root が必要、Icon の検証と同じ場所):

  • ファイルが存在しない → error
  • 15360 文字以上 → error
  • UTF-8 BOM 付き → error
  • shebang で始まらない → error

変更対象ファイル

  • Core モデル/validation: MacOsScriptsManifest.cs(新規)、AppManifest.cs、ManifestValues.cs、ManifestValidator.cs、ManifestAssetValidator.cs
  • Publish パス: MacOsAppPayload.cs、MacOsAppPayloadMapper.cs、ManifestAssetReader.cs、MacOsAppPublisher.cs、Planning/PlanService.cs
  • ドキュメント: doc/00-overview.md §6.13、doc/01-manifest-schema.md §5.3/§5.4(+ 新規 §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(新規)、doc/relaypublisher-design-and-copilot-issues.md
  • サンプル: samples/scripts/macos/powershell/{preinstall,postinstall}.sh(新規)、PowerShell 7.6.5 macOS manifest、samples/manifests/README.md/_ja
  • テスト: ManifestValidationTests、ManifestAssetValidatorTests、MacOsAppPayloadMapperTests、GraphMacOsAppClientTests、ManifestLoaderTests、PlanService reverse-lookup テストへの追加(MSTest)

対象外

  • macOSLobApp / macOSDmgApp への script 対応(Graph 側にプロパティが存在しないため不可)
  • スタンドアロンの shell script policy(deviceShellScript)の管理
  • スクリプトの構文チェック(shellcheck 等)— 利用側リポジトリの CI に委ねる

検証手順

dotnet build IntuneLobPublisher.slnx
dotnet test IntuneLobPublisher.slnx
dotnet 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-run

異常系の確認: 存在しない Scripts.PreInstall パス、AppType: lob エントリへの Scripts 付与、15360 文字を超える .sh は、それぞれ Graph 呼び出し前に validate が fail すること。

実テナントでの最終確認(任意、運用者環境): publish 後に Intune 管理センターで対象 app の「プログラム」タブに pre/post-install script が入っていること、および GET /beta/deviceAppManagement/mobileApps/{id} の preInstallScript.scriptContent / postInstallScript.scriptContent を base64 デコードして内容が一致することを確認する。

Clone this wiki locally