artifactbundleindex について
主にプラグインで利用する際の実行可能ファイルをバンドルしたファイル形式
- artifactbundle
- artifactbundleindex
の2パターンある
まず結論から
2022/11/21 現在 Xcode14.1.0 では artifactbundleindex は利用できない
artifactbundle
mac や linux など複数環境の実行可能ファイルを artifactbundle ディレクトリにまとめたもの
<name>.artifactbundle
├ info.json
├ <artifact>
│ ├ <variant>
│ │ ├ <executable>
│ │ └ <other files>
│ └ <variant>
│ ├ <executable>
│ └ <other files>
├ <artifact>
│ └ <variant>
│ ├ <executable>
│ └ <other files>
│ <artifact>
┆ └┄
基本的には artifactbundleindex を気にせずこちらを利用すれば、情報量的にも問題ないはず
artifactbundleindex
artifactbundle との違いは上記の形式だと mac で利用する場合でも全ての variant を含めたデータをダウンロードする必要がある
それを避けるために variant 毎に分割した artifactbundle を用意して、そのパスを artifactbundleindex に記載する
index ファイルは軽量な JSON なので、その後自身の variant 向けの artifactbundle のみをダウンロードすることによって通常の artifactbundle の場合より通信量を削減できる
罠1
artifactbundleindex は .binaryTarget(name:url:checksum:)
で参照した場合のみ利用できる
そのためローカルで検証できない 🤯
(先の通り、リモートのための機能なので当然といえば当然だが…)
罠2
Xcode14.1 だと未サポート
.binaryTarget(name:url:checksum:)
に切り替えてみると以下のエラーが返る
unsupported extension for binary target 'xxx'; valid extensions are: 'zip'
valid extensions are: 'zip'
の部分は supportedRemoteBinaryDependencyExtensions
のデータが入るので artifactbundleindex
が入っていないのはおかしい
罠3
.binaryTarget(name:url:checksum:)
のチェックサムについては以下の説明がある
The checksum for each .zip file in the index is computed in the same manner as for other binary .zip files, i.e. using swift package compute-checksum. The checksum in the binary target that references the .artifactbundleindex is the checksum of the .artifactbundleindex file itself. In this way, SwiftPM can validate the integrity of any of the .zip archives referenced by the index file.
artifactbundle と同じように swift package compute-checksum
を使おうとすると zip ファイルしか対応していない
error: unexpected file type; supported extensions are: zip
代わりに以下を用いてチェックサムを求める
$ shasum -a 256 path/to/target.artifactbundleindex
罠2と罠3から混乱して artifactbundleindex.zip にしたりしてみたが、それは間違っていた
Xcode に入っている swift package
の代わりに
を利用する
Package.swift から Xcode を立ち上げ、 swift-build
をビルドする
生成された swift-build
をテストしたいディレクトリにコピーし、直接実行する
$ ./swift-build
罠4
プロポーザルのドキュメントでは、フォーマットが以下の説明になっているが一部間違っている
{
"schemaVersion": "1.0",
"bundles": [
{
"fileName": "<name of .zip file containing bundle>",
"checksum": "<checksum of .zip file>",
"supportedTriples": [ "<triple1>", ... ]
},
...
]
}
bundles
ではなく archives
が正しい
artifactsが正しいですかね?
SwiftLintのtemplate用のファイルだとこの感じで運用されているようでした
コメントありがとうございます!
artifactsが正しいですかね?
当時の検証環境は artifactbundleindex 周りがしっかりサポートされてない雰囲気でしたので、それから変わったのかもしれませんね。
ただ先程それっぽい定義を探してみたら archives を見ているような?感じで、改めて検証できたらなと思います!
(そこが使われているかは不明ですが…)
罠5
triple の指定が本来なら arm64-apple-macosx
のようだが、 swift-package-manager@main を利用している関係のせいか arm64-apple-macosx12.0
とバージョンまで含めなければならなかった
以上を直して、ビルド時にプラグインが実行されるように調整
...
targets: [
.binaryTarget(name: "example",
url: "https://github.com/swiftty/artifactbundle-example/releases/download/0.0.6/example.artifactbundleindex",
checksum: "12a309e590d14d94ef3cf61837eaf97b26170b41386184ca13426edbd4db1c1d"),
.plugin(name: "Example", capability: .buildTool(), dependencies: ["example"]),
],
...
ただしまだエラーが発生している…
./swift-build
Downloading binary artifact https://github.com/swiftty/artifactbundle-example/releases/download/0.0.6/example.artifactbundle.zip
Downloaded https://github.com/swiftty/artifactbundle-example/releases/download/0.0.6/example.artifactbundle.zip (0.49s)
error: plugin process ended by an uncaught signal: 5 <command: /usr/bin/sandbox-exec -p '(version 1)
(deny default)
(import "system.sb")
(allow file-read*)
(allow process*)
(allow file-write*
(subpath "/private/tmp")
(subpath "/private/var/folders/p0/00x0k5494wd6hfylzdkkl4tc0000gn/T")
)
(deny file-write*
(subpath "/Users/xxx")
)
(allow file-write*
(subpath "/Users/xxx/.build/plugins/outputs")
(subpath "/Users/xxx/.build/plugins/cache")
)
' /Users/xxx/.build/plugins/cache/Example>, <output:
'Swift/ErrorType.swift:200: Fatal error: Error raised at top level: Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "xcodeTargets", intValue: nil), Swift.DecodingError.Context(codingPath: [CreateBuildToolCommandsCodingKeys(stringValue: "context", intValue: nil)], debugDescription: "No value associated with key CodingKeys(stringValue: \"xcodeTargets\", intValue: nil) (\"xcodeTargets\").", underlyingError: nil))
'>
ひとまず artifactbundle 一式の取得までは成功している様子なので、新しい Xcode が出たら改めて調査を再開する
しばらく放置していたが、 Xcode15.2 現在では artifactbundleindex が機能するようになっていた
.binaryTarget(
name: "example",
url: "https://github.com/swiftty/artifactbundle-example/releases/download/0.0.8/example.artifactbundleindex",
checksum: "75747898724a3b40239aed5a8ffdc1d69050432b9d66f51210b7b4754fb56bf0"
),
.plugin(name: "Example", capability: .buildTool(), dependencies: ["example"]),
ただし、こちらのバージョンの件はまだ発生していた
挙動に関して apple/swift-package-manager に起票している