mirror of
https://github.com/taiki-e/install-action.git
synced 2026-05-12 07:30:18 +00:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d865d5cc6 | ||
|
|
78e479f933 | ||
|
|
3da8dc3058 | ||
|
|
dcad28ece2 | ||
|
|
2c637c3acd | ||
|
|
ef1e8ec3f0 | ||
|
|
0673e7604e | ||
|
|
06203676c6 | ||
|
|
c35d18270e | ||
|
|
525387f706 | ||
|
|
7a6eff0bac | ||
|
|
458413b553 | ||
|
|
b988c18e3d | ||
|
|
5fe6797db0 |
4
.github/.cspell/project-dictionary.txt
vendored
4
.github/.cspell/project-dictionary.txt
vendored
@@ -20,16 +20,18 @@ libicu
|
|||||||
linkcheck
|
linkcheck
|
||||||
mdbook
|
mdbook
|
||||||
microdnf
|
microdnf
|
||||||
|
minisig
|
||||||
mirrorlist
|
mirrorlist
|
||||||
nextest
|
nextest
|
||||||
pluginconf
|
pluginconf
|
||||||
ppcle
|
ppcle
|
||||||
prek
|
prek
|
||||||
quickinstall
|
quickinstall
|
||||||
rclone
|
|
||||||
rdme
|
rdme
|
||||||
rootfs
|
rootfs
|
||||||
sccache
|
sccache
|
||||||
|
SHASUMS
|
||||||
|
sigstore
|
||||||
syft
|
syft
|
||||||
tombi
|
tombi
|
||||||
udeps
|
udeps
|
||||||
|
|||||||
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -11,7 +11,7 @@ on:
|
|||||||
- dev
|
- dev
|
||||||
- ci-*
|
- ci-*
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 0 * * *'
|
- cron: '0 2 * * *'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
|||||||
1
.github/workflows/release.yml
vendored
1
.github/workflows/release.yml
vendored
@@ -44,4 +44,5 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: write # for taiki-e/create-gh-release-action
|
contents: write # for taiki-e/create-gh-release-action
|
||||||
id-token: write # for rust-lang/crates-io-auth-action
|
id-token: write # for rust-lang/crates-io-auth-action
|
||||||
|
attestations: write # unused (used when options for uploading binaries are set)
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|||||||
29
CHANGELOG.md
29
CHANGELOG.md
@@ -10,6 +10,30 @@ Note: In this file, do not use the hard wrap in the middle of a sentence for com
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [2.69.7] - 2026-03-23
|
||||||
|
|
||||||
|
- Update `prek@latest` to 0.3.8.
|
||||||
|
|
||||||
|
- Update `mise@latest` to 2026.3.12.
|
||||||
|
|
||||||
|
- Update `cargo-valgrind@latest` to 2.4.1.
|
||||||
|
|
||||||
|
## [2.69.6] - 2026-03-21
|
||||||
|
|
||||||
|
- Support signature verification for `mise` and `syft`. ([#1611](https://github.com/taiki-e/install-action/pull/1611))
|
||||||
|
|
||||||
|
- Update `mise@latest` to 2026.3.10.
|
||||||
|
|
||||||
|
- Update `knope@latest` to 0.22.4.
|
||||||
|
|
||||||
|
- Update `cargo-binstall@latest` to 1.17.8.
|
||||||
|
|
||||||
|
- Update `tombi@latest` to 0.9.9.
|
||||||
|
|
||||||
|
## [2.69.5] - 2026-03-21
|
||||||
|
|
||||||
|
- Update `cargo-nextest@latest` to 0.9.132.
|
||||||
|
|
||||||
## [2.69.4] - 2026-03-20
|
## [2.69.4] - 2026-03-20
|
||||||
|
|
||||||
- Support artifact attestations verification for `biome`, `cargo-cyclonedx`, `cargo-hack`, `cargo-llvm-cov`, `cargo-minimal-versions`, `cargo-no-dev-deps`, `martin`, `parse-changelog`, `parse-dockerfile`, `prek`, `uv`, `wasmtime`, `zizmor`, and `zola`. ([#1606](https://github.com/taiki-e/install-action/pull/1606))
|
- Support artifact attestations verification for `biome`, `cargo-cyclonedx`, `cargo-hack`, `cargo-llvm-cov`, `cargo-minimal-versions`, `cargo-no-dev-deps`, `martin`, `parse-changelog`, `parse-dockerfile`, `prek`, `uv`, `wasmtime`, `zizmor`, and `zola`. ([#1606](https://github.com/taiki-e/install-action/pull/1606))
|
||||||
@@ -5983,7 +6007,10 @@ Note: This release is considered a breaking change because installing on version
|
|||||||
|
|
||||||
Initial release
|
Initial release
|
||||||
|
|
||||||
[Unreleased]: https://github.com/taiki-e/install-action/compare/v2.69.4...HEAD
|
[Unreleased]: https://github.com/taiki-e/install-action/compare/v2.69.7...HEAD
|
||||||
|
[2.69.7]: https://github.com/taiki-e/install-action/compare/v2.69.6...v2.69.7
|
||||||
|
[2.69.6]: https://github.com/taiki-e/install-action/compare/v2.69.5...v2.69.6
|
||||||
|
[2.69.5]: https://github.com/taiki-e/install-action/compare/v2.69.4...v2.69.5
|
||||||
[2.69.4]: https://github.com/taiki-e/install-action/compare/v2.69.3...v2.69.4
|
[2.69.4]: https://github.com/taiki-e/install-action/compare/v2.69.3...v2.69.4
|
||||||
[2.69.3]: https://github.com/taiki-e/install-action/compare/v2.69.2...v2.69.3
|
[2.69.3]: https://github.com/taiki-e/install-action/compare/v2.69.2...v2.69.3
|
||||||
[2.69.2]: https://github.com/taiki-e/install-action/compare/v2.69.1...v2.69.2
|
[2.69.2]: https://github.com/taiki-e/install-action/compare/v2.69.1...v2.69.2
|
||||||
|
|||||||
4
main.sh
4
main.sh
@@ -56,7 +56,7 @@ download_and_checksum() {
|
|||||||
checksum=''
|
checksum=''
|
||||||
fi
|
fi
|
||||||
info "downloading ${url}"
|
info "downloading ${url}"
|
||||||
retry curl --proto '=https' --tlsv1.2 -fsSL --retry 10 "${url}" -o tmp
|
retry curl --proto '=https' --tlsv1.2 -fsSL "${url}" -o tmp
|
||||||
if [[ -n "${checksum}" ]]; then
|
if [[ -n "${checksum}" ]]; then
|
||||||
info "verifying sha256 checksum for $(basename -- "${url}")"
|
info "verifying sha256 checksum for $(basename -- "${url}")"
|
||||||
if type -P sha256sum >/dev/null; then
|
if type -P sha256sum >/dev/null; then
|
||||||
@@ -233,7 +233,7 @@ read_manifest() {
|
|||||||
# TODO: don't hardcode tool name and use 'immediate_yank_reflection' field in base manifest.
|
# TODO: don't hardcode tool name and use 'immediate_yank_reflection' field in base manifest.
|
||||||
case "${tool}" in
|
case "${tool}" in
|
||||||
cargo-nextest)
|
cargo-nextest)
|
||||||
crate_info=$(curl -v --user-agent "${ACTION_USER_AGENT}" --proto '=https' --tlsv1.2 -fsSL --retry 10 "https://crates.io/api/v1/crates/${rust_crate}" || true)
|
crate_info=$(retry curl --user-agent "${ACTION_USER_AGENT}" --proto '=https' --tlsv1.2 -fsSL "https://crates.io/api/v1/crates/${rust_crate}" || true)
|
||||||
if [[ -n "${crate_info}" ]]; then
|
if [[ -n "${crate_info}" ]]; then
|
||||||
while true; do
|
while true; do
|
||||||
yanked=$(jq -r ".versions[] | select(.num == \"${exact_version}\") | .yanked" <<<"${crate_info}")
|
yanked=$(jq -r ".versions[] | select(.num == \"${exact_version}\") | .yanked" <<<"${crate_info}")
|
||||||
|
|||||||
28
manifests/cargo-binstall.json
generated
28
manifests/cargo-binstall.json
generated
@@ -22,32 +22,32 @@
|
|||||||
},
|
},
|
||||||
"license_markdown": "[GPL-3.0](https://github.com/cargo-bins/cargo-binstall/blob/HEAD/crates/bin/LICENSE)",
|
"license_markdown": "[GPL-3.0](https://github.com/cargo-bins/cargo-binstall/blob/HEAD/crates/bin/LICENSE)",
|
||||||
"latest": {
|
"latest": {
|
||||||
"version": "1.17.7"
|
"version": "1.17.8"
|
||||||
},
|
},
|
||||||
"1.17.7": {
|
"1.17.8": {
|
||||||
"x86_64_linux_musl": {
|
"x86_64_linux_musl": {
|
||||||
"etag": "0x8DE7C5AC0E4497E",
|
"etag": "0x8DE8715DB8A1417",
|
||||||
"hash": "29b5ecfb6e03c2511a617c77d312b06df0c54717644fbfda3d465ec8240532f0"
|
"hash": "1da1ef72448db667cc4ae6d48e37451087602c8c07dc61782a4a5e538303e015"
|
||||||
},
|
},
|
||||||
"x86_64_macos": {
|
"x86_64_macos": {
|
||||||
"etag": "0x8DE7C5AC5E5BC1B",
|
"etag": "0x8DE8715E03D9720",
|
||||||
"hash": "aa7174fb938e668dea4b4c3d22fe6cefed97642cc3a7a419ba96d63d63fd729b"
|
"hash": "db353e01b582c97382178db9b4dfe22d81109782e480a38f3db953e62f569952"
|
||||||
},
|
},
|
||||||
"x86_64_windows": {
|
"x86_64_windows": {
|
||||||
"etag": "0x8DE7C5AC441ACDB",
|
"etag": "0x8DE8715DEAA171B",
|
||||||
"hash": "c5cb2444ee04480502a8ac73d96abd9f97af8300ec04ea1c1f2a9e959c02e4d6"
|
"hash": "fef07560d4e391812091bb30c6ed1bd5289f74403a0c947b47b8a8c7a597b51b"
|
||||||
},
|
},
|
||||||
"aarch64_linux_musl": {
|
"aarch64_linux_musl": {
|
||||||
"etag": "0x8DE7C5ACC95E091",
|
"etag": "0x8DE8715E6784BD0",
|
||||||
"hash": "b0658b0a7f0959bc1dbb4ab665931c31c7dd1109ff01cb8772af17dfdc52a9af"
|
"hash": "81d6245bd1a7a89e914d29af81d82280540e94927e61492a0fc359820cd97abb"
|
||||||
},
|
},
|
||||||
"aarch64_macos": {
|
"aarch64_macos": {
|
||||||
"etag": "0x8DE7C5AD2545078",
|
"etag": "0x8DE8715EBEC4A3F",
|
||||||
"hash": "1ad3c0c56fa3970634cce5009ed0ce61b943515f9115f8e480fd0e41d8d89085"
|
"hash": "af87346fdb186f0a2333bc0a30cfddd6faa98b31145ef1bb19c284aedea65972"
|
||||||
},
|
},
|
||||||
"aarch64_windows": {
|
"aarch64_windows": {
|
||||||
"etag": "0x8DE7C5AD068DA1E",
|
"etag": "0x8DE8715EA179DDA",
|
||||||
"hash": "e876543c9aad23968d1123c0d959309937894bbfd267bb0878109fb253217878"
|
"hash": "2270a5a7a8b3e85bd5fe32ac3fbd48cfd32d6f468a8c35499af8b65b806d271d"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
39
manifests/cargo-nextest.json
generated
39
manifests/cargo-nextest.json
generated
@@ -28,10 +28,45 @@
|
|||||||
},
|
},
|
||||||
"license_markdown": "[Apache-2.0](https://github.com/nextest-rs/nextest/blob/main/LICENSE-APACHE) OR [MIT](https://github.com/nextest-rs/nextest/blob/main/LICENSE-MIT)",
|
"license_markdown": "[Apache-2.0](https://github.com/nextest-rs/nextest/blob/main/LICENSE-APACHE) OR [MIT](https://github.com/nextest-rs/nextest/blob/main/LICENSE-MIT)",
|
||||||
"latest": {
|
"latest": {
|
||||||
"version": "0.9.131"
|
"version": "0.9.132"
|
||||||
},
|
},
|
||||||
"0.9": {
|
"0.9": {
|
||||||
"version": "0.9.131"
|
"version": "0.9.132"
|
||||||
|
},
|
||||||
|
"0.9.132": {
|
||||||
|
"previous_stable_version": "0.9.131",
|
||||||
|
"x86_64_linux_gnu": {
|
||||||
|
"etag": "0x8DE86DAD99145E2",
|
||||||
|
"hash": "e22f14ecaff5519dbfe521e8717d64e9989648bddc23eb1f71bb0053518a52e7"
|
||||||
|
},
|
||||||
|
"x86_64_linux_musl": {
|
||||||
|
"etag": "0x8DE86DB277E6673",
|
||||||
|
"hash": "5e93f3b4244e2f8bffe5818b2a7cbd6a59f32d262dcb6017905e345cc74227af"
|
||||||
|
},
|
||||||
|
"x86_64_macos": {
|
||||||
|
"etag": "0x8DE86DB84D52D01",
|
||||||
|
"hash": "6ce5c844ae3cdac3f6f42fd86bf71a8bf99aecd76bab9f6743c808223d31fad1"
|
||||||
|
},
|
||||||
|
"x86_64_windows": {
|
||||||
|
"etag": "0x8DE86DBA597EDA0",
|
||||||
|
"hash": "6f934574f621613d7d759547401a04619b3e1ebe1f4e8f624880197d566fa6ad"
|
||||||
|
},
|
||||||
|
"aarch64_linux_gnu": {
|
||||||
|
"etag": "0x8DE86DBC5227BB5",
|
||||||
|
"hash": "592db3fa3d3ee62f109dc149554811eb8ecdc68e1514be5af79986b1560e2e0d"
|
||||||
|
},
|
||||||
|
"aarch64_linux_musl": {
|
||||||
|
"etag": "0x8DE86DAF803192A",
|
||||||
|
"hash": "2497ddfd2a0c6805f7c5514ff680c6ca9c1ffc5b9ab30af43e85830b768c129a"
|
||||||
|
},
|
||||||
|
"aarch64_windows": {
|
||||||
|
"etag": "0x8DE86DBA23732E6",
|
||||||
|
"hash": "3c519d128909fba6829a318476bcbd9777d97ec066b4d973a3f1e04da049ef0b"
|
||||||
|
},
|
||||||
|
"riscv64_linux_gnu": {
|
||||||
|
"etag": "0x8DE86DAD1A09377",
|
||||||
|
"hash": "82d1f0c4b7733e0a852e2e8b3f1a3f65b89e7ffd165121127ac356f0c9f7b5d2"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"0.9.131": {
|
"0.9.131": {
|
||||||
"previous_stable_version": "0.9.130",
|
"previous_stable_version": "0.9.130",
|
||||||
|
|||||||
20
manifests/cargo-valgrind.json
generated
20
manifests/cargo-valgrind.json
generated
@@ -13,13 +13,27 @@
|
|||||||
},
|
},
|
||||||
"license_markdown": "[MIT](https://github.com/jfrimmel/cargo-valgrind/blob/master/LICENSE-MIT) OR [Apache-2.0](https://github.com/jfrimmel/cargo-valgrind/blob/master/LICENSE-APACHE)",
|
"license_markdown": "[MIT](https://github.com/jfrimmel/cargo-valgrind/blob/master/LICENSE-MIT) OR [Apache-2.0](https://github.com/jfrimmel/cargo-valgrind/blob/master/LICENSE-APACHE)",
|
||||||
"latest": {
|
"latest": {
|
||||||
"version": "2.4.0"
|
"version": "2.4.1"
|
||||||
},
|
},
|
||||||
"2": {
|
"2": {
|
||||||
"version": "2.4.0"
|
"version": "2.4.1"
|
||||||
},
|
},
|
||||||
"2.4": {
|
"2.4": {
|
||||||
"version": "2.4.0"
|
"version": "2.4.1"
|
||||||
|
},
|
||||||
|
"2.4.1": {
|
||||||
|
"x86_64_linux_musl": {
|
||||||
|
"etag": "0x8DE88031FA217E4",
|
||||||
|
"hash": "85f0aba2bdde0d30bafa814a02229a56fd63b27623c25dfba57f49c40eeda762"
|
||||||
|
},
|
||||||
|
"x86_64_macos": {
|
||||||
|
"etag": "0x8DE88031F98D375",
|
||||||
|
"hash": "80b1477c1eb35410b40b842aa655b37233416f9cad86f6a11c6107b8b97ddc22"
|
||||||
|
},
|
||||||
|
"x86_64_windows": {
|
||||||
|
"etag": "0x8DE88031F98D375",
|
||||||
|
"hash": "c9f36f03de6ae0cb773b3796f4dd738ebb85e00a59c1cb72bec49a267d83c5cf"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"2.4.0": {
|
"2.4.0": {
|
||||||
"x86_64_linux_musl": {
|
"x86_64_linux_musl": {
|
||||||
|
|||||||
36
manifests/knope.json
generated
36
manifests/knope.json
generated
@@ -3,10 +3,42 @@
|
|||||||
"template": null,
|
"template": null,
|
||||||
"license_markdown": "[MIT](https://github.com/knope-dev/knope/blob/main/LICENSE)",
|
"license_markdown": "[MIT](https://github.com/knope-dev/knope/blob/main/LICENSE)",
|
||||||
"latest": {
|
"latest": {
|
||||||
"version": "0.22.3"
|
"version": "0.22.4"
|
||||||
},
|
},
|
||||||
"0.22": {
|
"0.22": {
|
||||||
"version": "0.22.3"
|
"version": "0.22.4"
|
||||||
|
},
|
||||||
|
"0.22.4": {
|
||||||
|
"x86_64_linux_musl": {
|
||||||
|
"url": "https://github.com/knope-dev/knope/releases/download/knope/v0.22.4/knope-x86_64-unknown-linux-musl.tgz",
|
||||||
|
"etag": "0x8DE8761D8F513DE",
|
||||||
|
"hash": "45a74925ae9f4c9c2c33b51992ae50241ec4fa836bf8d2977c0b8e8172dd69cf",
|
||||||
|
"bin": "knope-x86_64-unknown-linux-musl/knope"
|
||||||
|
},
|
||||||
|
"x86_64_macos": {
|
||||||
|
"url": "https://github.com/knope-dev/knope/releases/download/knope/v0.22.4/knope-x86_64-apple-darwin.tgz",
|
||||||
|
"etag": "0x8DE8761D8E4D27D",
|
||||||
|
"hash": "010dc197bf159bbd9d60e897252248ba2b0e204beae7250ce54a9deae1ec4876",
|
||||||
|
"bin": "knope-x86_64-apple-darwin/knope"
|
||||||
|
},
|
||||||
|
"x86_64_windows": {
|
||||||
|
"url": "https://github.com/knope-dev/knope/releases/download/knope/v0.22.4/knope-x86_64-pc-windows-msvc.tgz",
|
||||||
|
"etag": "0x8DE8761D8EAE61C",
|
||||||
|
"hash": "09f735b2da42cd594189042d1379c0a3a350a8c0ccb741015a84c6ff334543b1",
|
||||||
|
"bin": "knope-x86_64-pc-windows-msvc/knope.exe"
|
||||||
|
},
|
||||||
|
"aarch64_linux_musl": {
|
||||||
|
"url": "https://github.com/knope-dev/knope/releases/download/knope/v0.22.4/knope-aarch64-unknown-linux-musl.tgz",
|
||||||
|
"etag": "0x8DE8761D8EE649C",
|
||||||
|
"hash": "95e882afdb4154c5baaba91f7bbd1fb1d41cec6898363a2b30e7abad4057b83b",
|
||||||
|
"bin": "knope-aarch64-unknown-linux-musl/knope"
|
||||||
|
},
|
||||||
|
"aarch64_macos": {
|
||||||
|
"url": "https://github.com/knope-dev/knope/releases/download/knope/v0.22.4/knope-aarch64-apple-darwin.tgz",
|
||||||
|
"etag": "0x8DE8761D8EC1D47",
|
||||||
|
"hash": "02131f284315c8ece8a4ef69a0aff5f658309d4df73b95cfdfbe0fbd9e9ce259",
|
||||||
|
"bin": "knope-aarch64-apple-darwin/knope"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"0.22.3": {
|
"0.22.3": {
|
||||||
"x86_64_linux_musl": {
|
"x86_64_linux_musl": {
|
||||||
|
|||||||
58
manifests/mise.json
generated
58
manifests/mise.json
generated
@@ -28,13 +28,65 @@
|
|||||||
},
|
},
|
||||||
"license_markdown": "[MIT](https://github.com/jdx/mise/blob/main/LICENSE)",
|
"license_markdown": "[MIT](https://github.com/jdx/mise/blob/main/LICENSE)",
|
||||||
"latest": {
|
"latest": {
|
||||||
"version": "2026.3.9"
|
"version": "2026.3.12"
|
||||||
},
|
},
|
||||||
"2026": {
|
"2026": {
|
||||||
"version": "2026.3.9"
|
"version": "2026.3.12"
|
||||||
},
|
},
|
||||||
"2026.3": {
|
"2026.3": {
|
||||||
"version": "2026.3.9"
|
"version": "2026.3.12"
|
||||||
|
},
|
||||||
|
"2026.3.12": {
|
||||||
|
"x86_64_linux_musl": {
|
||||||
|
"etag": "0x8DE886122F1FBF4",
|
||||||
|
"hash": "b6bdc23b08bccfcc77b61d35b286e20de1e0192447e8fda64b2bf60c5328b452"
|
||||||
|
},
|
||||||
|
"x86_64_macos": {
|
||||||
|
"etag": "0x8DE88612512C4AA",
|
||||||
|
"hash": "4f65f7f72c14641ad78670ec2c403d3eb9a4681e2fa064385e80a22a109bfe2c"
|
||||||
|
},
|
||||||
|
"x86_64_windows": {
|
||||||
|
"etag": "0x8DE886125F154A2",
|
||||||
|
"hash": "528d5f9bfabb8eae06964c0e112f9711a4af4315bfed96f6f50b6c4b67ec6f37"
|
||||||
|
},
|
||||||
|
"aarch64_linux_musl": {
|
||||||
|
"etag": "0x8DE88611FFB72E8",
|
||||||
|
"hash": "c27dd6a06053f6884c3f46763b64ef9c5e95fac7a9af89edea087b13cc68c521"
|
||||||
|
},
|
||||||
|
"aarch64_macos": {
|
||||||
|
"etag": "0x8DE88612449EE2B",
|
||||||
|
"hash": "c9622be7ea2badc7bf3501cd9b5600e0bf993bf33c162844a4a6d79a2209e1f8"
|
||||||
|
},
|
||||||
|
"aarch64_windows": {
|
||||||
|
"etag": "0x8DE8861257AFC36",
|
||||||
|
"hash": "a65bea150a477f21faa62e24d45f811d2ede69da20aac43ad17ef3134bc516f4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"2026.3.10": {
|
||||||
|
"x86_64_linux_musl": {
|
||||||
|
"etag": "0x8DE8749F9B8C65D",
|
||||||
|
"hash": "b0c2fd25fe95cd1ed3f178b95690608472aa8a27ce2f6e63eaebda52a238e570"
|
||||||
|
},
|
||||||
|
"x86_64_macos": {
|
||||||
|
"etag": "0x8DE8749FBD637A3",
|
||||||
|
"hash": "5ed1a2a6a79aab33e67d21156ec42b22d3cde1ceef09eb08c0ccd9b429795e6a"
|
||||||
|
},
|
||||||
|
"x86_64_windows": {
|
||||||
|
"etag": "0x8DE8749FC98ACBC",
|
||||||
|
"hash": "bf5e86077f652caca0413155e33886c3459d3f2963f9f186be76c8c05c2accb6"
|
||||||
|
},
|
||||||
|
"aarch64_linux_musl": {
|
||||||
|
"etag": "0x8DE8749F6470833",
|
||||||
|
"hash": "9730abf52c93c7945f907f4fe6f731b79d74671705656fa36fa45008933e88c7"
|
||||||
|
},
|
||||||
|
"aarch64_macos": {
|
||||||
|
"etag": "0x8DE8749FB48C7AB",
|
||||||
|
"hash": "85b5e577a5ed34431718091122ea7ec9cf7d4e1d8e5e4dc298cdb02d8dbd97b3"
|
||||||
|
},
|
||||||
|
"aarch64_windows": {
|
||||||
|
"etag": "0x8DE8749FC8C37A5",
|
||||||
|
"hash": "82a702481c9e877b28f82eb60a0d3be2d393fc9b7915283992b1cd0263724d2b"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"2026.3.9": {
|
"2026.3.9": {
|
||||||
"x86_64_linux_musl": {
|
"x86_64_linux_musl": {
|
||||||
|
|||||||
38
manifests/prek.json
generated
38
manifests/prek.json
generated
@@ -40,10 +40,44 @@
|
|||||||
},
|
},
|
||||||
"license_markdown": "[MIT](https://github.com/j178/prek/blob/master/LICENSE)",
|
"license_markdown": "[MIT](https://github.com/j178/prek/blob/master/LICENSE)",
|
||||||
"latest": {
|
"latest": {
|
||||||
"version": "0.3.6"
|
"version": "0.3.8"
|
||||||
},
|
},
|
||||||
"0.3": {
|
"0.3": {
|
||||||
"version": "0.3.6"
|
"version": "0.3.8"
|
||||||
|
},
|
||||||
|
"0.3.8": {
|
||||||
|
"x86_64_linux_musl": {
|
||||||
|
"etag": "0x8DE88B58DEC3E03",
|
||||||
|
"hash": "732cfb03960e6dfd5df2cb67906797aa8831750ef3a6f6340ec2b90ee8b7a59f"
|
||||||
|
},
|
||||||
|
"x86_64_macos": {
|
||||||
|
"etag": "0x8DE88B58D79B1EF",
|
||||||
|
"hash": "010198daf4e99a76d03a911973320542ffd7a04091cf7e86c60ac861187577f6"
|
||||||
|
},
|
||||||
|
"x86_64_windows": {
|
||||||
|
"etag": "0x8DE88B58DA4B02B",
|
||||||
|
"hash": "1da2735c31548dacd2751f90c15b5f643aa72f3053f366636f95153ee2c7186e"
|
||||||
|
},
|
||||||
|
"aarch64_linux_musl": {
|
||||||
|
"etag": "0x8DE88B58C3D8D01",
|
||||||
|
"hash": "b88d96aef4ea84999d12958c390611d3a26194ee57225fe2ff15a9855e3a71bf"
|
||||||
|
},
|
||||||
|
"aarch64_macos": {
|
||||||
|
"etag": "0x8DE88B58BFA193A",
|
||||||
|
"hash": "702fde4399fafb054ce85d0a64367689e3668b6475d732c4a46aae50cec0a4be"
|
||||||
|
},
|
||||||
|
"aarch64_windows": {
|
||||||
|
"etag": "0x8DE88B58BF4A12E",
|
||||||
|
"hash": "5ceb73fe9e18a987a498ced9b98a183d4110e3fdb534070d2d9911f860319e9f"
|
||||||
|
},
|
||||||
|
"riscv64_linux_gnu": {
|
||||||
|
"etag": "0x8DE88B58D4F0179",
|
||||||
|
"hash": "4c3677090f90f325b1f472e8b2db6f56647db794333ab0ee2656a91139ce9a27"
|
||||||
|
},
|
||||||
|
"s390x_linux_gnu": {
|
||||||
|
"etag": "0x8DE88B58D875E2B",
|
||||||
|
"hash": "cec915a22e4385110e2de8498d14c199ce6936d03d9d8340d166c57071ac1de8"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"0.3.6": {
|
"0.3.6": {
|
||||||
"x86_64_linux_musl": {
|
"x86_64_linux_musl": {
|
||||||
|
|||||||
30
manifests/tombi.json
generated
30
manifests/tombi.json
generated
@@ -22,10 +22,36 @@
|
|||||||
},
|
},
|
||||||
"license_markdown": "[MIT](https://github.com/tombi-toml/tombi/blob/main/LICENSE)",
|
"license_markdown": "[MIT](https://github.com/tombi-toml/tombi/blob/main/LICENSE)",
|
||||||
"latest": {
|
"latest": {
|
||||||
"version": "0.9.8"
|
"version": "0.9.9"
|
||||||
},
|
},
|
||||||
"0.9": {
|
"0.9": {
|
||||||
"version": "0.9.8"
|
"version": "0.9.9"
|
||||||
|
},
|
||||||
|
"0.9.9": {
|
||||||
|
"x86_64_linux_musl": {
|
||||||
|
"etag": "0x8DE86ED14380D61",
|
||||||
|
"hash": "4317ffc3e08fc6e3ba92953af85b6ad361493fd79916949aec5b5b7af471922f"
|
||||||
|
},
|
||||||
|
"x86_64_macos": {
|
||||||
|
"etag": "0x8DE86ED1495C95E",
|
||||||
|
"hash": "7f43d90e17f0a6406b5c53bb2773ea1f51e9aba00d47e76d6a55f70ba6e519e0"
|
||||||
|
},
|
||||||
|
"x86_64_windows": {
|
||||||
|
"etag": "0x8DE86ED1433F34E",
|
||||||
|
"hash": "efb2e3bd949435d244368179476658b5bed9bf35b662face2c00920faf97f247"
|
||||||
|
},
|
||||||
|
"aarch64_linux_musl": {
|
||||||
|
"etag": "0x8DE86ED1432BC2D",
|
||||||
|
"hash": "75d32d6d17a35c5307f7b67c4f80eca8d43b4d5bdacf86505a4bb87dcb3100d0"
|
||||||
|
},
|
||||||
|
"aarch64_macos": {
|
||||||
|
"etag": "0x8DE86ED149A3137",
|
||||||
|
"hash": "4e49e41a2f3bd7a26e11c0ce936ac0b75d60c9068798b951ea925cea04ce4a5b"
|
||||||
|
},
|
||||||
|
"aarch64_windows": {
|
||||||
|
"etag": "0x8DE86ED14385B2B",
|
||||||
|
"hash": "138047f5a495629a1fe60734706ab1d89fc8ed68eeab3dbd0b1865eab108f7b6"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"0.9.8": {
|
"0.9.8": {
|
||||||
"x86_64_linux_musl": {
|
"x86_64_linux_musl": {
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
"rust_crate": "${package}",
|
"rust_crate": "${package}",
|
||||||
"bin": "mise/bin/${package}${exe}",
|
"bin": "mise/bin/${package}${exe}",
|
||||||
"version_range": ">= 2025.9.7",
|
"version_range": ">= 2025.9.7",
|
||||||
|
"signing": {
|
||||||
|
"kind": "custom"
|
||||||
|
},
|
||||||
"platform": {
|
"platform": {
|
||||||
"x86_64_linux_musl": {
|
"x86_64_linux_musl": {
|
||||||
"asset_name": "${package}-v${version}-${rust_target_os}-x64-musl.tar.gz"
|
"asset_name": "${package}-v${version}-${rust_target_os}-x64-musl.tar.gz"
|
||||||
|
|||||||
@@ -3,6 +3,10 @@
|
|||||||
"tag_prefix": "v",
|
"tag_prefix": "v",
|
||||||
"bin": "${package}${exe}",
|
"bin": "${package}${exe}",
|
||||||
"version_range": ">= 0.83.0",
|
"version_range": ">= 0.83.0",
|
||||||
|
"signing": {
|
||||||
|
"version_range": ">= 0.104.0",
|
||||||
|
"kind": "custom"
|
||||||
|
},
|
||||||
"platform": {
|
"platform": {
|
||||||
"x86_64_linux_musl": {
|
"x86_64_linux_musl": {
|
||||||
"asset_name": "${package}_${version}_linux_amd64.tar.gz"
|
"asset_name": "${package}_${version}_linux_amd64.tar.gz"
|
||||||
|
|||||||
@@ -61,6 +61,18 @@ impl BaseManifest {
|
|||||||
if self.platform.is_empty() {
|
if self.platform.is_empty() {
|
||||||
panic!("At least one platform must be specified");
|
panic!("At least one platform must be specified");
|
||||||
}
|
}
|
||||||
|
if let Some(website) = &self.website {
|
||||||
|
if website.is_empty() || *website == self.repository {
|
||||||
|
panic!(
|
||||||
|
"Please do not put the repository in website, or set website to an empty value"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(license_markdown) = &self.license_markdown {
|
||||||
|
if license_markdown.is_empty() {
|
||||||
|
panic!("license_markdown can not be an empty value");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,6 +95,8 @@ pub enum SigningKind {
|
|||||||
/// public key: package.metadata.binstall.signing.pubkey at Cargo.toml
|
/// public key: package.metadata.binstall.signing.pubkey at Cargo.toml
|
||||||
/// <https://github.com/cargo-bins/cargo-binstall/blob/HEAD/SIGNING.md>
|
/// <https://github.com/cargo-bins/cargo-binstall/blob/HEAD/SIGNING.md>
|
||||||
MinisignBinstall,
|
MinisignBinstall,
|
||||||
|
/// tool-specific
|
||||||
|
Custom,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use std::{
|
|||||||
env,
|
env,
|
||||||
ffi::OsStr,
|
ffi::OsStr,
|
||||||
io::Read as _,
|
io::Read as _,
|
||||||
path::Path,
|
path::{Path, PathBuf},
|
||||||
sync::{LazyLock, RwLock},
|
sync::{LazyLock, RwLock},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
@@ -20,9 +20,10 @@ use install_action_internal_codegen::{
|
|||||||
BaseManifest, HostPlatform, Manifest, ManifestDownloadInfo, ManifestRef, ManifestTemplate,
|
BaseManifest, HostPlatform, Manifest, ManifestDownloadInfo, ManifestRef, ManifestTemplate,
|
||||||
ManifestTemplateDownloadInfo, Manifests, SigningKind, Version, workspace_root,
|
ManifestTemplateDownloadInfo, Manifests, SigningKind, Version, workspace_root,
|
||||||
};
|
};
|
||||||
|
use serde::de::DeserializeOwned;
|
||||||
use spdx::expression::{ExprNode, ExpressionReq, Operator};
|
use spdx::expression::{ExprNode, ExpressionReq, Operator};
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() {
|
||||||
let args: Vec<_> = env::args().skip(1).collect();
|
let args: Vec<_> = env::args().skip(1).collect();
|
||||||
if args.is_empty() || args.iter().any(|arg| arg.starts_with('-')) {
|
if args.is_empty() || args.iter().any(|arg| arg.starts_with('-')) {
|
||||||
println!(
|
println!(
|
||||||
@@ -30,7 +31,7 @@ fn main() -> Result<()> {
|
|||||||
);
|
);
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
let package = &args[0];
|
let package = &*args[0];
|
||||||
let version_req = args.get(1);
|
let version_req = args.get(1);
|
||||||
let version_req_given = version_req.is_some();
|
let version_req_given = version_req.is_some();
|
||||||
let skip_existing_manifest_versions = std::env::var("SKIP_EXISTING_MANIFEST_VERSIONS").is_ok();
|
let skip_existing_manifest_versions = std::env::var("SKIP_EXISTING_MANIFEST_VERSIONS").is_ok();
|
||||||
@@ -38,23 +39,25 @@ fn main() -> Result<()> {
|
|||||||
let workspace_root = workspace_root();
|
let workspace_root = workspace_root();
|
||||||
let manifest_path = &workspace_root.join("manifests").join(format!("{package}.json"));
|
let manifest_path = &workspace_root.join("manifests").join(format!("{package}.json"));
|
||||||
let download_cache_dir = &workspace_root.join("tools/codegen/tmp/cache").join(package);
|
let download_cache_dir = &workspace_root.join("tools/codegen/tmp/cache").join(package);
|
||||||
fs::create_dir_all(manifest_path.parent().unwrap())?;
|
fs::create_dir_all(manifest_path.parent().unwrap()).unwrap();
|
||||||
fs::create_dir_all(download_cache_dir)?;
|
fs::create_dir_all(download_cache_dir).unwrap();
|
||||||
|
|
||||||
eprintln!("download cache: {}", download_cache_dir.display());
|
eprintln!("download cache: {}", download_cache_dir.display());
|
||||||
|
|
||||||
let mut base_info: BaseManifest = serde_json::from_slice(&fs::read(
|
let mut base_info: BaseManifest = serde_json::from_slice(
|
||||||
workspace_root.join("tools/codegen/base").join(format!("{package}.json")),
|
&fs::read(workspace_root.join("tools/codegen/base").join(format!("{package}.json")))
|
||||||
)?)?;
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
base_info.validate();
|
base_info.validate();
|
||||||
let repo = base_info
|
let repo = base_info
|
||||||
.repository
|
.repository
|
||||||
.strip_prefix("https://github.com/")
|
.strip_prefix("https://github.com/")
|
||||||
.context("repository must start with https://github.com/")?;
|
.context("repository must start with https://github.com/")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
eprintln!("downloading metadata from {GITHUB_API_START}repos/{repo}");
|
eprintln!("downloading metadata from {GITHUB_API_START}repos/{repo}");
|
||||||
let repo_info: github::RepoMetadata =
|
let repo_info: github::RepoMetadata = download_json(&format!("{GITHUB_API_START}repos/{repo}"));
|
||||||
download(&format!("{GITHUB_API_START}repos/{repo}"))?.into_json()?;
|
|
||||||
|
|
||||||
eprintln!("downloading releases from {GITHUB_API_START}repos/{repo}/releases");
|
eprintln!("downloading releases from {GITHUB_API_START}repos/{repo}/releases");
|
||||||
let mut releases: github::Releases = vec![];
|
let mut releases: github::Releases = vec![];
|
||||||
@@ -62,10 +65,9 @@ fn main() -> Result<()> {
|
|||||||
// is greater than 100, multiple fetches are needed.
|
// is greater than 100, multiple fetches are needed.
|
||||||
for page in 1.. {
|
for page in 1.. {
|
||||||
let per_page = 100;
|
let per_page = 100;
|
||||||
let mut r: github::Releases = download(&format!(
|
let mut r: github::Releases = download_json(&format!(
|
||||||
"{GITHUB_API_START}repos/{repo}/releases?per_page={per_page}&page={page}"
|
"{GITHUB_API_START}repos/{repo}/releases?per_page={per_page}&page={page}"
|
||||||
))?
|
));
|
||||||
.into_json()?;
|
|
||||||
// If version_req is latest, it is usually sufficient to look at the latest 100 releases.
|
// If version_req is latest, it is usually sufficient to look at the latest 100 releases.
|
||||||
if r.len() < per_page || version_req.is_some_and(|req| req == "latest") {
|
if r.len() < per_page || version_req.is_some_and(|req| req == "latest") {
|
||||||
releases.append(&mut r);
|
releases.append(&mut r);
|
||||||
@@ -103,23 +105,25 @@ fn main() -> Result<()> {
|
|||||||
.rust_crate
|
.rust_crate
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|s| replace_vars(s, package, None, None, base_info.rust_crate.as_deref()))
|
.map(|s| replace_vars(s, package, None, None, base_info.rust_crate.as_deref()))
|
||||||
.transpose()?;
|
.transpose()
|
||||||
|
.unwrap();
|
||||||
if let Some(crate_name) = &base_info.rust_crate {
|
if let Some(crate_name) = &base_info.rust_crate {
|
||||||
eprintln!("downloading crate info from https://crates.io/api/v1/crates/{crate_name}");
|
eprintln!("downloading crate info from https://crates.io/api/v1/crates/{crate_name}");
|
||||||
let info = download(&format!("https://crates.io/api/v1/crates/{crate_name}"))?
|
let info: crates_io::Crate =
|
||||||
.into_json::<crates_io::Crate>()?;
|
download_json(&format!("https://crates.io/api/v1/crates/{crate_name}"));
|
||||||
let latest_version = &info.versions[0].num;
|
let latest_version = &info.versions[0].num;
|
||||||
crates_io_version_detail = Some(
|
crates_io_version_detail = Some(
|
||||||
download(&format!("https://crates.io/api/v1/crates/{crate_name}/{latest_version}"))?
|
download_json::<crates_io::VersionMetadata>(&format!(
|
||||||
.into_json::<crates_io::VersionMetadata>()?
|
"https://crates.io/api/v1/crates/{crate_name}/{latest_version}"
|
||||||
.version,
|
))
|
||||||
|
.version,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(crate_repository) = info.crate_.repository.clone() {
|
if let Some(crate_repository) = info.crate_.repository.clone() {
|
||||||
if !crate_repository.to_lowercase().starts_with(&base_info.repository.to_lowercase()) {
|
if !crate_repository.to_lowercase().starts_with(&base_info.repository.to_lowercase()) {
|
||||||
panic!("repository {crate_repository} from crates.io differs from base manifest");
|
panic!("repository {crate_repository} from crates.io differs from base manifest");
|
||||||
}
|
}
|
||||||
} else if crate_name != "zola" {
|
} else {
|
||||||
panic!("crate metadata does not include a repository");
|
panic!("crate metadata does not include a repository");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +143,7 @@ fn main() -> Result<()> {
|
|||||||
|
|
||||||
if manifest_path.is_file() {
|
if manifest_path.is_file() {
|
||||||
println!("loading pre-existing manifest {}", manifest_path.display());
|
println!("loading pre-existing manifest {}", manifest_path.display());
|
||||||
match serde_json::from_slice(&fs::read(manifest_path)?) {
|
match serde_json::from_slice(&fs::read(manifest_path).unwrap()) {
|
||||||
Ok(m) => {
|
Ok(m) => {
|
||||||
manifests = m;
|
manifests = m;
|
||||||
for (k, manifest) in &mut manifests.map {
|
for (k, manifest) in &mut manifests.map {
|
||||||
@@ -165,18 +169,8 @@ fn main() -> Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check website
|
|
||||||
if let Some(website) = base_info.website {
|
|
||||||
if website.is_empty() || website == base_info.repository {
|
|
||||||
panic!("Please do not put the repository in website, or set website to an empty value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Populate license_markdown from the base manifest if present.
|
// Populate license_markdown from the base manifest if present.
|
||||||
if let Some(license_markdown) = base_info.license_markdown {
|
if let Some(license_markdown) = base_info.license_markdown {
|
||||||
if license_markdown.is_empty() {
|
|
||||||
panic!("license_markdown can not be an empty value");
|
|
||||||
}
|
|
||||||
manifests.license_markdown = license_markdown;
|
manifests.license_markdown = license_markdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +178,7 @@ fn main() -> Result<()> {
|
|||||||
if !manifests.license_markdown.is_empty() {
|
if !manifests.license_markdown.is_empty() {
|
||||||
let urls = get_license_markdown_urls(&manifests.license_markdown);
|
let urls = get_license_markdown_urls(&manifests.license_markdown);
|
||||||
if urls.is_empty() {
|
if urls.is_empty() {
|
||||||
bail!("Could not find URLs in license_markdown: {}.", manifests.license_markdown);
|
panic!("Could not find URLs in license_markdown: {}.", manifests.license_markdown);
|
||||||
}
|
}
|
||||||
for url in urls {
|
for url in urls {
|
||||||
if let Err(err) = github_head(&url) {
|
if let Err(err) = github_head(&url) {
|
||||||
@@ -207,7 +201,7 @@ fn main() -> Result<()> {
|
|||||||
spdx_id
|
spdx_id
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
bail!(
|
panic!(
|
||||||
"No license SPDX found in crates.io or GitHub metadata.\n\
|
"No license SPDX found in crates.io or GitHub metadata.\n\
|
||||||
Please set license_markdown in the base manifest"
|
Please set license_markdown in the base manifest"
|
||||||
);
|
);
|
||||||
@@ -218,7 +212,7 @@ fn main() -> Result<()> {
|
|||||||
{
|
{
|
||||||
manifests.license_markdown = license_markdown;
|
manifests.license_markdown = license_markdown;
|
||||||
} else {
|
} else {
|
||||||
bail!(
|
panic!(
|
||||||
"Unable to verify license file(s) in the repo for license {license}.\n\
|
"Unable to verify license file(s) in the repo for license {license}.\n\
|
||||||
Please set license_markdown in the base manifest"
|
Please set license_markdown in the base manifest"
|
||||||
);
|
);
|
||||||
@@ -227,13 +221,13 @@ fn main() -> Result<()> {
|
|||||||
|
|
||||||
let version_req: semver::VersionReq = match version_req {
|
let version_req: semver::VersionReq = match version_req {
|
||||||
_ if latest_only => {
|
_ if latest_only => {
|
||||||
let req = format!("={}", releases.first_key_value().unwrap().0.0).parse()?;
|
let req = format!("={}", releases.first_key_value().unwrap().0.0).parse().unwrap();
|
||||||
eprintln!("update manifest for versions '{req}'");
|
eprintln!("update manifest for versions '{req}'");
|
||||||
req
|
req
|
||||||
}
|
}
|
||||||
None => match base_info.version_range {
|
None => match base_info.version_range {
|
||||||
Some(version_range) => version_range.parse()?,
|
Some(version_range) => version_range.parse().unwrap(),
|
||||||
None => ">= 0.0.1".parse()?, // HACK: ignore pre-releases
|
None => ">= 0.0.1".parse().unwrap(), // HACK: ignore pre-releases
|
||||||
},
|
},
|
||||||
Some(version_req) => {
|
Some(version_req) => {
|
||||||
for version in manifests.map.keys() {
|
for version in manifests.map.keys() {
|
||||||
@@ -249,18 +243,26 @@ fn main() -> Result<()> {
|
|||||||
let req = if version_req == "latest" {
|
let req = if version_req == "latest" {
|
||||||
// TODO: this should check all missing versions
|
// TODO: this should check all missing versions
|
||||||
if manifests.map.is_empty() {
|
if manifests.map.is_empty() {
|
||||||
format!("={}", releases.first_key_value().unwrap().0.0).parse()?
|
format!("={}", releases.first_key_value().unwrap().0.0).parse().unwrap()
|
||||||
} else {
|
} else {
|
||||||
format!(">={}", semver_versions.last().unwrap()).parse()?
|
format!(">={}", semver_versions.last().unwrap()).parse().unwrap()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
version_req.parse()?
|
version_req.parse().unwrap()
|
||||||
};
|
};
|
||||||
eprintln!("update manifest for versions '{req}'");
|
eprintln!("update manifest for versions '{req}'");
|
||||||
req
|
req
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let signing_version_req: Option<semver::VersionReq> =
|
||||||
|
base_info.signing.as_ref().map(|signing| {
|
||||||
|
match &signing.version_range {
|
||||||
|
Some(version_range) => version_range.parse().unwrap(),
|
||||||
|
None => ">= 0.0.1".parse().unwrap(), // HACK: ignore pre-releases
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let mut buf = vec![];
|
let mut buf = vec![];
|
||||||
let mut buf2 = vec![];
|
let mut buf2 = vec![];
|
||||||
for (Reverse(semver_version), (version, release)) in &releases {
|
for (Reverse(semver_version), (version, release)) in &releases {
|
||||||
@@ -282,11 +284,154 @@ fn main() -> Result<()> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let signing_version_req: Option<semver::VersionReq> = match &base_info.signing {
|
let mut verified_checksum: Option<Vec<_>> = None;
|
||||||
|
match &base_info.signing {
|
||||||
Some(signing) => {
|
Some(signing) => {
|
||||||
match &signing.version_range {
|
if let SigningKind::Custom = signing.kind {
|
||||||
Some(version_range) => Some(version_range.parse()?),
|
match package {
|
||||||
None => Some(">= 0.0.1".parse()?), // HACK: ignore pre-releases
|
_ if !signing_version_req.as_ref().unwrap().matches(semver_version) => {}
|
||||||
|
"mise" => {
|
||||||
|
// Refs: https://github.com/jdx/mise/blob/v2026.3.9/src/minisign.rs
|
||||||
|
let crates_io_info = crates_io_info.as_ref().unwrap();
|
||||||
|
let [checksum, sig] =
|
||||||
|
["SHASUMS256.txt", "SHASUMS256.txt.minisig"].map(|f| {
|
||||||
|
let Some(asset) =
|
||||||
|
release.assets.iter().find(|asset| asset.name == f)
|
||||||
|
else {
|
||||||
|
// There is broken release which has no release assets: https://github.com/jdx/mise/releases/tag/v2026.2.14
|
||||||
|
return PathBuf::new();
|
||||||
|
};
|
||||||
|
let download_cache =
|
||||||
|
download_cache_dir.join(format!("{version}-{f}"));
|
||||||
|
let url = &asset.browser_download_url;
|
||||||
|
eprint!("downloading {url} for signature verification ... ");
|
||||||
|
if download_cache.is_file() {
|
||||||
|
eprintln!("already downloaded");
|
||||||
|
} else {
|
||||||
|
download_to_buf(url, &mut buf);
|
||||||
|
eprintln!("download complete");
|
||||||
|
fs::write(&download_cache, &buf).unwrap();
|
||||||
|
buf.clear();
|
||||||
|
}
|
||||||
|
download_cache
|
||||||
|
});
|
||||||
|
if checksum.as_os_str().is_empty() || sig.as_os_str().is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let v = crates_io_info
|
||||||
|
.versions
|
||||||
|
.iter()
|
||||||
|
.find(|v| v.num == *semver_version)
|
||||||
|
.unwrap();
|
||||||
|
let url = format!("https://crates.io{}", v.dl_path);
|
||||||
|
let pubkey_download_cache =
|
||||||
|
&download_cache_dir.join(format!("{version}-minisign.pub"));
|
||||||
|
eprint!("downloading {url} for signature verification ... ");
|
||||||
|
if pubkey_download_cache.is_file() {
|
||||||
|
eprintln!("already downloaded");
|
||||||
|
} else {
|
||||||
|
download_to_buf(&url, &mut buf);
|
||||||
|
let hash = ring::digest::digest(&ring::digest::SHA256, &buf);
|
||||||
|
if format!("{hash:?}").strip_prefix("SHA256:").unwrap()
|
||||||
|
!= v.checksum
|
||||||
|
{
|
||||||
|
panic!("checksum mismatch for {url}");
|
||||||
|
}
|
||||||
|
let decoder = flate2::read::GzDecoder::new(&*buf);
|
||||||
|
let mut archive = tar::Archive::new(decoder);
|
||||||
|
for entry in archive.entries().unwrap() {
|
||||||
|
let mut entry = entry.unwrap();
|
||||||
|
let path = entry.path().unwrap();
|
||||||
|
if path.file_name() == Some(OsStr::new("minisign.pub")) {
|
||||||
|
entry.unpack(pubkey_download_cache).unwrap();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.clear();
|
||||||
|
eprintln!("download complete");
|
||||||
|
}
|
||||||
|
let pubkey =
|
||||||
|
minisign_verify::PublicKey::from_file(pubkey_download_cache)
|
||||||
|
.unwrap();
|
||||||
|
eprint!("verifying checksum file for {package}@{version} ... ");
|
||||||
|
let allow_legacy = false;
|
||||||
|
pubkey
|
||||||
|
.verify(
|
||||||
|
&fs::read(&checksum).unwrap(),
|
||||||
|
&minisign_verify::Signature::from_file(sig).unwrap(),
|
||||||
|
allow_legacy,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
verified_checksum = Some(
|
||||||
|
fs::read_to_string(checksum)
|
||||||
|
.unwrap()
|
||||||
|
.lines()
|
||||||
|
.filter_map(|l| l.split_once(" "))
|
||||||
|
.map(|(h, f)| {
|
||||||
|
(f.trim_ascii().to_owned(), h.trim_ascii().to_owned())
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
);
|
||||||
|
eprintln!("done");
|
||||||
|
}
|
||||||
|
"syft" => {
|
||||||
|
// Refs: https://oss.anchore.com/docs/installation/verification/
|
||||||
|
let [checksum, certificate, signature] =
|
||||||
|
["checksums.txt", "checksums.txt.pem", "checksums.txt.sig"].map(
|
||||||
|
|f| {
|
||||||
|
let asset = release
|
||||||
|
.assets
|
||||||
|
.iter()
|
||||||
|
.find(|asset| asset.name.ends_with(f))
|
||||||
|
.unwrap();
|
||||||
|
let download_cache =
|
||||||
|
download_cache_dir.join(format!("{version}-{f}"));
|
||||||
|
let url = &asset.browser_download_url;
|
||||||
|
eprint!(
|
||||||
|
"downloading {url} for signature verification ... "
|
||||||
|
);
|
||||||
|
if download_cache.is_file() {
|
||||||
|
eprintln!("already downloaded");
|
||||||
|
} else {
|
||||||
|
download_to_buf(url, &mut buf);
|
||||||
|
eprintln!("download complete");
|
||||||
|
fs::write(&download_cache, &buf).unwrap();
|
||||||
|
buf.clear();
|
||||||
|
}
|
||||||
|
download_cache
|
||||||
|
},
|
||||||
|
);
|
||||||
|
eprint!("verifying checksum file for {package}@{version} ... ");
|
||||||
|
cmd!(
|
||||||
|
"cosign",
|
||||||
|
"verify-blob",
|
||||||
|
&checksum,
|
||||||
|
"--certificate",
|
||||||
|
certificate,
|
||||||
|
"--signature",
|
||||||
|
signature,
|
||||||
|
"--certificate-identity-regexp",
|
||||||
|
format!("https://github\\.com/{repo}/\\.github/workflows/.+"),
|
||||||
|
"--certificate-oidc-issuer",
|
||||||
|
"https://token.actions.githubusercontent.com"
|
||||||
|
)
|
||||||
|
.run()
|
||||||
|
.unwrap();
|
||||||
|
verified_checksum = Some(
|
||||||
|
fs::read_to_string(checksum)
|
||||||
|
.unwrap()
|
||||||
|
.lines()
|
||||||
|
.filter_map(|l| l.split_once(" "))
|
||||||
|
.map(|(h, f)| {
|
||||||
|
(f.trim_ascii().to_owned(), h.trim_ascii().to_owned())
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
);
|
||||||
|
eprintln!("done");
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
@@ -294,24 +439,29 @@ fn main() -> Result<()> {
|
|||||||
asset.name.contains(".asc")
|
asset.name.contains(".asc")
|
||||||
|| asset.name.contains(".gpg")
|
|| asset.name.contains(".gpg")
|
||||||
|| asset.name.contains(".sig")
|
|| asset.name.contains(".sig")
|
||||||
|
|| asset.name.contains(".minisig")
|
||||||
|
|| asset.name.contains(".pem")
|
||||||
|
|| asset.name.contains(".crt")
|
||||||
|
|| asset.name.contains(".key")
|
||||||
|
|| asset.name.contains(".pub")
|
||||||
}) {
|
}) {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"{package} may supports other signing verification method using {}",
|
"{package} may supports other signature verification method using {}",
|
||||||
asset.name
|
asset.name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
None
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
let mut download_info = BTreeMap::new();
|
let mut download_info = BTreeMap::new();
|
||||||
let mut pubkey = None;
|
let mut minisign_binstall_pubkey = None;
|
||||||
for (&platform, base_download_info) in &base_info.platform {
|
for (&platform, base_download_info) in &base_info.platform {
|
||||||
let asset_names = base_download_info
|
let asset_names = base_download_info
|
||||||
.asset_name
|
.asset_name
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.or(base_info.asset_name.as_ref())
|
.or(base_info.asset_name.as_ref())
|
||||||
.with_context(|| format!("asset_name is needed for {package} on {platform:?}"))?
|
.with_context(|| format!("asset_name is needed for {package} on {platform:?}"))
|
||||||
|
.unwrap()
|
||||||
.as_slice()
|
.as_slice()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|asset_name| {
|
.map(|asset_name| {
|
||||||
@@ -323,7 +473,8 @@ fn main() -> Result<()> {
|
|||||||
base_info.rust_crate.as_deref(),
|
base_info.rust_crate.as_deref(),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>>>()?;
|
.collect::<Result<Vec<_>>>()
|
||||||
|
.unwrap();
|
||||||
let (url, digest, asset_name) = match asset_names.iter().find_map(|asset_name| {
|
let (url, digest, asset_name) = match asset_names.iter().find_map(|asset_name| {
|
||||||
release
|
release
|
||||||
.assets
|
.assets
|
||||||
@@ -345,7 +496,7 @@ fn main() -> Result<()> {
|
|||||||
"{version}-{platform:?}-{}",
|
"{version}-{platform:?}-{}",
|
||||||
Path::new(&url).file_name().unwrap().to_str().unwrap()
|
Path::new(&url).file_name().unwrap().to_str().unwrap()
|
||||||
));
|
));
|
||||||
let response = download(&url)?;
|
let response = download(&url).unwrap();
|
||||||
let etag =
|
let etag =
|
||||||
response.header("etag").expect("binary should have an etag").replace('\"', "");
|
response.header("etag").expect("binary should have an etag").replace('\"', "");
|
||||||
|
|
||||||
@@ -365,11 +516,11 @@ fn main() -> Result<()> {
|
|||||||
|
|
||||||
if download_cache.is_file() {
|
if download_cache.is_file() {
|
||||||
eprintln!("already downloaded");
|
eprintln!("already downloaded");
|
||||||
fs::File::open(download_cache)?.read_to_end(&mut buf)?; // Not buffered because it is read at once.
|
fs::File::open(download_cache).unwrap().read_to_end(&mut buf).unwrap(); // Not buffered because it is read at once.
|
||||||
} else {
|
} else {
|
||||||
response.into_reader().read_to_end(&mut buf)?;
|
response.into_reader().read_to_end(&mut buf).unwrap();
|
||||||
eprintln!("download complete");
|
eprintln!("download complete");
|
||||||
fs::write(download_cache, &buf)?;
|
fs::write(download_cache, &buf).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
eprintln!("getting sha256 hash for {url}");
|
eprintln!("getting sha256 hash for {url}");
|
||||||
@@ -377,7 +528,7 @@ fn main() -> Result<()> {
|
|||||||
let hash = format!("{hash:?}").strip_prefix("SHA256:").unwrap().to_owned();
|
let hash = format!("{hash:?}").strip_prefix("SHA256:").unwrap().to_owned();
|
||||||
if let Some(digest) = digest {
|
if let Some(digest) = digest {
|
||||||
if hash != digest.strip_prefix("sha256:").unwrap() {
|
if hash != digest.strip_prefix("sha256:").unwrap() {
|
||||||
bail!(
|
panic!(
|
||||||
"digest mismatch between GitHub release page and actually downloaded file"
|
"digest mismatch between GitHub release page and actually downloaded file"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -401,9 +552,15 @@ fn main() -> Result<()> {
|
|||||||
signer_workflow,
|
signer_workflow,
|
||||||
&download_cache
|
&download_cache
|
||||||
)
|
)
|
||||||
.run()?;
|
.run()
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
SigningKind::MinisignBinstall => {
|
SigningKind::MinisignBinstall => {
|
||||||
|
let Some(crates_io_info) = &crates_io_info else {
|
||||||
|
panic!(
|
||||||
|
"signing kind minisign-binstall is supported only for rust crate"
|
||||||
|
);
|
||||||
|
};
|
||||||
let url = url.clone() + ".sig";
|
let url = url.clone() + ".sig";
|
||||||
let sig_download_cache = &download_cache.with_extension(format!(
|
let sig_download_cache = &download_cache.with_extension(format!(
|
||||||
"{}.sig",
|
"{}.sig",
|
||||||
@@ -412,19 +569,14 @@ fn main() -> Result<()> {
|
|||||||
eprint!("downloading {url} for signature validation ... ");
|
eprint!("downloading {url} for signature validation ... ");
|
||||||
let sig = if sig_download_cache.is_file() {
|
let sig = if sig_download_cache.is_file() {
|
||||||
eprintln!("already downloaded");
|
eprintln!("already downloaded");
|
||||||
minisign_verify::Signature::from_file(sig_download_cache)?
|
minisign_verify::Signature::from_file(sig_download_cache).unwrap()
|
||||||
} else {
|
} else {
|
||||||
let buf = download(&url)?.into_string()?;
|
let buf = download(&url).unwrap().into_string().unwrap();
|
||||||
eprintln!("download complete");
|
eprintln!("download complete");
|
||||||
fs::write(sig_download_cache, &buf)?;
|
fs::write(sig_download_cache, &buf).unwrap();
|
||||||
minisign_verify::Signature::decode(&buf)?
|
minisign_verify::Signature::decode(&buf).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(crates_io_info) = &crates_io_info else {
|
|
||||||
bail!(
|
|
||||||
"signing kind minisign-binstall is supported only for rust crate"
|
|
||||||
);
|
|
||||||
};
|
|
||||||
let v = crates_io_info
|
let v = crates_io_info
|
||||||
.versions
|
.versions
|
||||||
.iter()
|
.iter()
|
||||||
@@ -437,28 +589,29 @@ fn main() -> Result<()> {
|
|||||||
if crate_download_cache.is_file() {
|
if crate_download_cache.is_file() {
|
||||||
eprintln!("already downloaded");
|
eprintln!("already downloaded");
|
||||||
} else {
|
} else {
|
||||||
download(&url)?.into_reader().read_to_end(&mut buf2)?;
|
download_to_buf(&url, &mut buf2);
|
||||||
let hash = ring::digest::digest(&ring::digest::SHA256, &buf2);
|
let hash = ring::digest::digest(&ring::digest::SHA256, &buf2);
|
||||||
if format!("{hash:?}").strip_prefix("SHA256:").unwrap() != v.checksum {
|
if format!("{hash:?}").strip_prefix("SHA256:").unwrap() != v.checksum {
|
||||||
bail!("checksum mismatch for {url}");
|
panic!("checksum mismatch for {url}");
|
||||||
}
|
}
|
||||||
let decoder = flate2::read::GzDecoder::new(&*buf2);
|
let decoder = flate2::read::GzDecoder::new(&*buf2);
|
||||||
let mut archive = tar::Archive::new(decoder);
|
let mut archive = tar::Archive::new(decoder);
|
||||||
for entry in archive.entries()? {
|
for entry in archive.entries().unwrap() {
|
||||||
let mut entry = entry?;
|
let mut entry = entry.unwrap();
|
||||||
let path = entry.path()?;
|
let path = entry.path().unwrap();
|
||||||
if path.file_name() == Some(OsStr::new("Cargo.toml")) {
|
if path.file_name() == Some(OsStr::new("Cargo.toml")) {
|
||||||
entry.unpack(crate_download_cache)?;
|
entry.unpack(crate_download_cache).unwrap();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buf2.clear();
|
buf2.clear();
|
||||||
eprintln!("download complete");
|
eprintln!("download complete");
|
||||||
}
|
}
|
||||||
if pubkey.is_none() {
|
if minisign_binstall_pubkey.is_none() {
|
||||||
let cargo_manifest = toml::de::from_str::<cargo_manifest::Manifest>(
|
let cargo_manifest = toml::de::from_str::<cargo_manifest::Manifest>(
|
||||||
&fs::read_to_string(crate_download_cache)?,
|
&fs::read_to_string(crate_download_cache).unwrap(),
|
||||||
)?;
|
)
|
||||||
|
.unwrap();
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"algorithm: {}",
|
"algorithm: {}",
|
||||||
cargo_manifest.package.metadata.binstall.signing.algorithm
|
cargo_manifest.package.metadata.binstall.signing.algorithm
|
||||||
@@ -471,16 +624,42 @@ fn main() -> Result<()> {
|
|||||||
cargo_manifest.package.metadata.binstall.signing.algorithm,
|
cargo_manifest.package.metadata.binstall.signing.algorithm,
|
||||||
"minisign"
|
"minisign"
|
||||||
);
|
);
|
||||||
pubkey = Some(minisign_verify::PublicKey::from_base64(
|
minisign_binstall_pubkey = Some(
|
||||||
&cargo_manifest.package.metadata.binstall.signing.pubkey,
|
minisign_verify::PublicKey::from_base64(
|
||||||
)?);
|
&cargo_manifest.package.metadata.binstall.signing.pubkey,
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
let pubkey = pubkey.as_ref().unwrap();
|
let pubkey = minisign_binstall_pubkey.as_ref().unwrap();
|
||||||
eprint!("verifying signature for {bin_url} ... ");
|
eprint!("verifying signature for {bin_url} ... ");
|
||||||
let allow_legacy = false;
|
let allow_legacy = false;
|
||||||
pubkey.verify(&buf, &sig, allow_legacy)?;
|
pubkey.verify(&buf, &sig, allow_legacy).unwrap();
|
||||||
eprintln!("done");
|
eprintln!("done");
|
||||||
}
|
}
|
||||||
|
SigningKind::Custom => {
|
||||||
|
if let Some(verified_checksum) = &verified_checksum {
|
||||||
|
let asset_name_cwd = format!("./{asset_name}");
|
||||||
|
let mut checked = false;
|
||||||
|
for (f, h) in verified_checksum {
|
||||||
|
if *f == asset_name || *f == asset_name_cwd {
|
||||||
|
checked = true;
|
||||||
|
assert_eq!(
|
||||||
|
hash, *h,
|
||||||
|
"verified checksum doesn't match with sha256 hash of {asset_name} in {package}@{version}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert!(
|
||||||
|
checked,
|
||||||
|
"{asset_name} not found in verified checksum for {package}@{version}"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
unimplemented!(
|
||||||
|
"unimplemented tool-specific signing handling for {package}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -563,7 +742,7 @@ fn main() -> Result<()> {
|
|||||||
|
|
||||||
// update an existing manifests.json to avoid discarding work done in the event of a fetch error.
|
// update an existing manifests.json to avoid discarding work done in the event of a fetch error.
|
||||||
if existing_manifest.is_some() && !version_req_given {
|
if existing_manifest.is_some() && !version_req_given {
|
||||||
write_manifests(manifest_path, &manifests.clone())?;
|
write_manifests(manifest_path, &manifests.clone()).unwrap();
|
||||||
eprintln!("wrote {} with incomplete data", manifest_path.display());
|
eprintln!("wrote {} with incomplete data", manifest_path.display());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -636,7 +815,7 @@ fn main() -> Result<()> {
|
|||||||
.values()
|
.values()
|
||||||
.any(|m| matches!(m, ManifestRef::Real(m) if m.download_info.contains_key(&p)))
|
.any(|m| matches!(m, ManifestRef::Real(m) if m.download_info.contains_key(&p)))
|
||||||
{
|
{
|
||||||
bail!(
|
panic!(
|
||||||
"platform list in base manifest for {package} contains {p:?}, \
|
"platform list in base manifest for {package} contains {p:?}, \
|
||||||
but result manifest doesn't contain it; \
|
but result manifest doesn't contain it; \
|
||||||
consider removing {p:?} from platform list in base manifest"
|
consider removing {p:?} from platform list in base manifest"
|
||||||
@@ -680,7 +859,7 @@ fn main() -> Result<()> {
|
|||||||
// until 2027-08, people aren't paying much attention to it at this time.
|
// until 2027-08, people aren't paying much attention to it at this time.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bail!(
|
panic!(
|
||||||
"platform list in base manifest for {package} contains {p:?}, \
|
"platform list in base manifest for {package} contains {p:?}, \
|
||||||
but latest release ({latest_version}) doesn't contain it; \
|
but latest release ({latest_version}) doesn't contain it; \
|
||||||
consider marking {latest_version} as broken by adding 'broken' field to base manifest"
|
consider marking {latest_version} as broken by adding 'broken' field to base manifest"
|
||||||
@@ -720,10 +899,8 @@ fn main() -> Result<()> {
|
|||||||
|
|
||||||
manifests.rust_crate = base_info.rust_crate;
|
manifests.rust_crate = base_info.rust_crate;
|
||||||
|
|
||||||
write_manifests(manifest_path, &manifests)?;
|
write_manifests(manifest_path, &manifests).unwrap();
|
||||||
eprintln!("wrote {}", manifest_path.display());
|
eprintln!("wrote {}", manifest_path.display());
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_manifests(manifest_path: &Path, manifests: &Manifests) -> Result<()> {
|
fn write_manifests(manifest_path: &Path, manifests: &Manifests) -> Result<()> {
|
||||||
@@ -858,6 +1035,16 @@ fn download(url: &str) -> Result<ureq::Response> {
|
|||||||
Err(last_error.unwrap().into())
|
Err(last_error.unwrap().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn download_to_buf(url: &str, buf: &mut Vec<u8>) {
|
||||||
|
download(url).unwrap().into_reader().read_to_end(buf).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn download_json<T: DeserializeOwned>(url: &str) -> T {
|
||||||
|
download(url).unwrap().into_json().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
fn github_head(url: &str) -> Result<()> {
|
fn github_head(url: &str) -> Result<()> {
|
||||||
eprintln!("fetching head of {url} ..");
|
eprintln!("fetching head of {url} ..");
|
||||||
let mut token = GITHUB_TOKENS.get(url);
|
let mut token = GITHUB_TOKENS.get(url);
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ use std::{
|
|||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::Result;
|
|
||||||
use fs_err as fs;
|
use fs_err as fs;
|
||||||
use install_action_internal_codegen::{BaseManifest, Manifests, workspace_root};
|
use install_action_internal_codegen::{BaseManifest, Manifests, workspace_root};
|
||||||
|
|
||||||
@@ -32,7 +31,7 @@ const FOOTER: &str = "
|
|||||||
[cargo-binstall]: https://github.com/cargo-bins/cargo-binstall
|
[cargo-binstall]: https://github.com/cargo-bins/cargo-binstall
|
||||||
";
|
";
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() {
|
||||||
let args: Vec<_> = env::args().skip(1).collect();
|
let args: Vec<_> = env::args().skip(1).collect();
|
||||||
if !args.is_empty() || args.iter().any(|arg| arg.starts_with('-')) {
|
if !args.is_empty() || args.iter().any(|arg| arg.starts_with('-')) {
|
||||||
println!(
|
println!(
|
||||||
@@ -72,9 +71,10 @@ fn main() -> Result<()> {
|
|||||||
name.set_extension("");
|
name.set_extension("");
|
||||||
let name = name.to_string_lossy().to_string();
|
let name = name.to_string_lossy().to_string();
|
||||||
let base_info: BaseManifest =
|
let base_info: BaseManifest =
|
||||||
serde_json::from_slice(&fs::read(base_info_dir.join(file_name.clone()))?)?;
|
serde_json::from_slice(&fs::read(base_info_dir.join(file_name.clone())).unwrap())
|
||||||
|
.unwrap();
|
||||||
let manifests: Manifests =
|
let manifests: Manifests =
|
||||||
serde_json::from_slice(&fs::read(manifest_dir.join(file_name))?)?;
|
serde_json::from_slice(&fs::read(manifest_dir.join(file_name)).unwrap()).unwrap();
|
||||||
|
|
||||||
let website = match base_info.website {
|
let website = match base_info.website {
|
||||||
Some(website) => website,
|
Some(website) => website,
|
||||||
@@ -135,9 +135,7 @@ fn main() -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
file.write_all(FOOTER.as_bytes()).expect("Unable to write footer");
|
file.write_all(FOOTER.as_bytes()).expect("Unable to write footer");
|
||||||
file.flush()?;
|
file.flush().unwrap();
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ cd -- "$(dirname -- "$0")"/..
|
|||||||
# ./tools/manifest.sh [PACKAGE [VERSION_REQ]]
|
# ./tools/manifest.sh [PACKAGE [VERSION_REQ]]
|
||||||
# ./tools/manifest.sh full
|
# ./tools/manifest.sh full
|
||||||
|
|
||||||
|
if [[ -n "${GITHUB_ACTIONS:-}" ]] && ! type -P cosign; then
|
||||||
|
go install github.com/sigstore/cosign/v3/cmd/cosign@latest
|
||||||
|
sudo mv -- ~/go/bin/cosign /usr/local/bin
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ $# -eq 1 ]] && [[ "$1" == "full" ]]; then
|
if [[ $# -eq 1 ]] && [[ "$1" == "full" ]]; then
|
||||||
for manifest in tools/codegen/base/*.json; do
|
for manifest in tools/codegen/base/*.json; do
|
||||||
package="${manifest##*/}"
|
package="${manifest##*/}"
|
||||||
|
|||||||
Reference in New Issue
Block a user