mirror of
https://github.com/taiki-e/install-action.git
synced 2026-04-27 01:20:28 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eab2c9a639 | ||
|
|
04da82019b | ||
|
|
d22c04db3c | ||
|
|
288875dd3d | ||
|
|
ff61ba777f | ||
|
|
443c943e8c | ||
|
|
44ad71dd7c |
1
.github/.cspell/project-dictionary.txt
vendored
1
.github/.cspell/project-dictionary.txt
vendored
@@ -2,6 +2,7 @@ almalinux
|
||||
archlinux
|
||||
binstall
|
||||
callgrind
|
||||
Ceuo
|
||||
coreutils
|
||||
cyclonedx
|
||||
cygdrive
|
||||
|
||||
24
.github/workflows/ci.yml
vendored
24
.github/workflows/ci.yml
vendored
@@ -10,6 +10,7 @@ on:
|
||||
- main
|
||||
- dev
|
||||
- ci-*
|
||||
- busybox
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
workflow_dispatch:
|
||||
@@ -77,13 +78,13 @@ jobs:
|
||||
- os: windows-2022
|
||||
- os: windows-2022
|
||||
bash: msys64
|
||||
# - os: windows-2022
|
||||
# bash: cygwin
|
||||
- os: windows-2022
|
||||
bash: cygwin
|
||||
- os: windows-2025
|
||||
- os: windows-2025
|
||||
bash: msys64
|
||||
# - os: windows-2025
|
||||
# bash: cygwin
|
||||
- os: windows-2025
|
||||
bash: cygwin
|
||||
- os: windows-11-arm
|
||||
- os: windows-2022
|
||||
tool: major.minor.patch
|
||||
@@ -231,7 +232,17 @@ jobs:
|
||||
- opensuse/leap:latest # glibc 2.38 (as of leap 15.6)
|
||||
- opensuse/tumbleweed:latest # glibc 2.39 (as of 2024-07-19)
|
||||
- archlinux:latest # glibc 2.39 (as of 2024-07-19)
|
||||
- alpine:latest # musl 1.2.5 (as of alpine 3.20)
|
||||
- alpine:3.2 # musl 1.1.11, busybox 1.23.2
|
||||
- alpine:3.14 # musl 1.2.2, busybox 1.33.1
|
||||
- alpine:3.15 # musl 1.2.2, busybox 1.34.1
|
||||
- alpine:3.16 # musl 1.2.3, busybox 1.35.0
|
||||
- alpine:3.17 # musl 1.2.3, busybox 1.35.0
|
||||
- alpine:3.18 # musl 1.2.4, busybox 1.36.1
|
||||
- alpine:3.19 # musl 1.2.4, busybox 1.36.1
|
||||
- alpine:3.20 # musl 1.2.5, busybox 1.36.1
|
||||
- alpine:3.21 # musl 1.2.5, busybox 1.37.0
|
||||
- alpine:3.22 # musl 1.2.5, busybox 1.37.0
|
||||
- alpine:3.23 # musl 1.2.5, busybox 1.37.0
|
||||
# - openwrt/rootfs:x86-64-openwrt-24.10 # musl 1.2.5
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 60
|
||||
@@ -282,6 +293,9 @@ jobs:
|
||||
tool: ${{ steps.tool-list.outputs.tool }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: apk --no-cache add bash
|
||||
shell: sh
|
||||
if: startsWith(matrix.container, 'alpine')
|
||||
- name: Test bash
|
||||
run: just --version && shfmt --version
|
||||
shell: bash
|
||||
|
||||
@@ -10,6 +10,10 @@ Note: In this file, do not use the hard wrap in the middle of a sentence for com
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [2.67.30] - 2026-02-13
|
||||
|
||||
- Update `cargo-nextest@latest` to 0.9.127.
|
||||
|
||||
## [2.67.29] - 2026-02-13
|
||||
|
||||
- Update `mise@latest` to 2026.2.11.
|
||||
@@ -5643,7 +5647,8 @@ Note: This release is considered a breaking change because installing on version
|
||||
|
||||
Initial release
|
||||
|
||||
[Unreleased]: https://github.com/taiki-e/install-action/compare/v2.67.29...HEAD
|
||||
[Unreleased]: https://github.com/taiki-e/install-action/compare/v2.67.30...HEAD
|
||||
[2.67.30]: https://github.com/taiki-e/install-action/compare/v2.67.29...v2.67.30
|
||||
[2.67.29]: https://github.com/taiki-e/install-action/compare/v2.67.28...v2.67.29
|
||||
[2.67.28]: https://github.com/taiki-e/install-action/compare/v2.67.27...v2.67.28
|
||||
[2.67.27]: https://github.com/taiki-e/install-action/compare/v2.67.26...v2.67.27
|
||||
|
||||
@@ -118,12 +118,14 @@ On Linux, if any required tools are missing, this action will attempt to install
|
||||
|
||||
On other platforms, at least the following tools are required:
|
||||
|
||||
- bash 3.2+
|
||||
- bash 3.2+ (or busybox on Linux)
|
||||
- jq 1.3+ (only on non-Windows platforms)
|
||||
- curl 7.34+ (or RHEL7/CentOS7's patched curl 7.29)
|
||||
|
||||
Known environments affected by the above version requirements are CentOS 6 (EoL on 2020-11) using curl 7.19, and Ubuntu 12.04 (EoL on 2017-04) using curl 7.22 (see "Install requirements" in [our CI config](https://github.com/taiki-e/install-action/blob/HEAD/.github/workflows/ci.yml) for example of workaround).
|
||||
|
||||
Note that what this action installs for its setup (such as above tools) is considered an implementation detail if they are installed by this action's side, and there is no guarantee that they will be available in subsequent steps, because this action is not an action for installing those tools.
|
||||
|
||||
## Related Projects
|
||||
|
||||
- [cache-cargo-install-action]: GitHub Action for `cargo install` with cache.
|
||||
|
||||
32
action.yml
32
action.yml
@@ -21,32 +21,32 @@ inputs:
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- run: |
|
||||
- name: Prepare
|
||||
id: prepare
|
||||
run: |
|
||||
set -eu
|
||||
if ! command -v bash >/dev/null; then
|
||||
if grep -Eq '^ID=alpine' /etc/os-release; then
|
||||
printf '::group::Install packages required for install-action (bash)\n'
|
||||
# NB: sync with apk_install in main.sh
|
||||
if command -v sudo >/dev/null; then
|
||||
sudo apk --no-cache add bash
|
||||
elif command -v doas >/dev/null; then
|
||||
doas apk --no-cache add bash
|
||||
else
|
||||
apk --no-cache add bash
|
||||
if command -v busybox >/dev/null; then
|
||||
if test -n "${GITHUB_OUTPUT:-}"; then
|
||||
printf 'shell=busybox sh -e {0}\n' >>"${GITHUB_OUTPUT}"
|
||||
exit
|
||||
fi
|
||||
printf '::endgroup::\n'
|
||||
else
|
||||
printf '::error::install-action requires bash\n'
|
||||
exit 1
|
||||
fi
|
||||
printf '::error::install-action requires bash or busybox\n'
|
||||
exit 1
|
||||
fi
|
||||
shell: sh
|
||||
if: runner.os == 'Linux'
|
||||
- run: bash --noprofile --norc "${GITHUB_ACTION_PATH:?}/main.sh"
|
||||
shell: bash
|
||||
- run: |
|
||||
case "${CURRENT_SHELL}" in
|
||||
busybox*) busybox sh "${GITHUB_ACTION_PATH:?}/main.sh" ;;
|
||||
*) bash --noprofile --norc "${GITHUB_ACTION_PATH:?}/main.sh" ;;
|
||||
esac
|
||||
shell: ${{ steps.prepare.outputs.shell || 'bash' }}
|
||||
env:
|
||||
INPUT_TOOL: ${{ inputs.tool }}
|
||||
INPUT_CHECKSUM: ${{ inputs.checksum }}
|
||||
INPUT_FALLBACK: ${{ inputs.fallback }}
|
||||
DEFAULT_GITHUB_TOKEN: ${{ github.token }}
|
||||
ACTION_USER_AGENT: ${{ github.action_repository }} (${{ github.action_ref }})
|
||||
CURRENT_SHELL: ${{ steps.prepare.outputs.shell }}
|
||||
|
||||
57
main.sh
57
main.sh
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
set -CeEuo pipefail
|
||||
# Do not set -E as busybox 3.15 and older don't support it.
|
||||
set -Ceuo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
rx() {
|
||||
@@ -35,11 +36,11 @@ normalize_comma_or_space_separated() {
|
||||
if [[ "${list}" == *","* ]]; then
|
||||
# If a comma is contained, consider it is a comma-separated list.
|
||||
# Drop leading and trailing whitespaces in each element.
|
||||
sed -E 's/ *, */,/g; s/^.//' <<<",${list},"
|
||||
printf '%s\n' ",${list}," | sed -E 's/ *, */,/g; s/^.//'
|
||||
else
|
||||
# Otherwise, consider it is a whitespace-separated list.
|
||||
# Convert whitespace characters into comma.
|
||||
sed -E 's/ +/,/g; s/^.//' <<<" ${list} "
|
||||
printf '%s\n' " ${list} " | sed -E 's/ +/,/g; s/^.//'
|
||||
fi
|
||||
}
|
||||
_sudo() {
|
||||
@@ -60,11 +61,11 @@ download_and_checksum() {
|
||||
if [[ -n "${checksum}" ]]; then
|
||||
info "verifying sha256 checksum for $(basename -- "${url}")"
|
||||
if type -P sha256sum >/dev/null; then
|
||||
sha256sum -c - >/dev/null <<<"${checksum} *tmp"
|
||||
printf '%s\n' "${checksum} *tmp" | sha256sum -c - >/dev/null
|
||||
elif type -P shasum >/dev/null; then
|
||||
# GitHub-hosted macOS runner does not install GNU Coreutils by default.
|
||||
# https://github.com/actions/runner-images/issues/90
|
||||
shasum -a 256 -c - >/dev/null <<<"${checksum} *tmp"
|
||||
printf '%s\n' "${checksum} *tmp" | shasum -a 256 -c - >/dev/null
|
||||
else
|
||||
bail "checksum requires 'sha256sum' or 'shasum' command; consider installing one of them or setting 'checksum' input option to 'false'"
|
||||
fi
|
||||
@@ -224,7 +225,7 @@ read_manifest() {
|
||||
download_info="null"
|
||||
return 0
|
||||
fi
|
||||
exact_version=$(jq -r '.version' <<<"${manifest}")
|
||||
exact_version=$(printf '%s\n' "${manifest}" | jq -r '.version')
|
||||
if [[ "${exact_version}" == "null" ]]; then
|
||||
exact_version="${version}"
|
||||
else
|
||||
@@ -236,11 +237,11 @@ read_manifest() {
|
||||
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)
|
||||
if [[ -n "${crate_info}" ]]; then
|
||||
while true; do
|
||||
yanked=$(jq -r ".versions[] | select(.num == \"${exact_version}\") | .yanked" <<<"${crate_info}")
|
||||
yanked=$(printf '%s\n' "${crate_info}" | jq -r ".versions[] | select(.num == \"${exact_version}\") | .yanked")
|
||||
if [[ "${yanked}" != "true" ]]; then
|
||||
break
|
||||
fi
|
||||
previous_stable_version=$(jq -r '.previous_stable_version' <<<"${manifest}")
|
||||
previous_stable_version=$(printf '%s\n' "${manifest}" | jq -r '.previous_stable_version')
|
||||
if [[ "${previous_stable_version}" == "null" ]]; then
|
||||
break
|
||||
fi
|
||||
@@ -260,26 +261,26 @@ read_manifest() {
|
||||
# usually preferred over linux-gnu binaries because they can avoid glibc version issues.
|
||||
# (rustc enables statically linking for linux-musl by default, except for mips.)
|
||||
host_platform="${host_arch}_linux_musl"
|
||||
download_info=$(jq -r ".${host_platform}" <<<"${manifest}")
|
||||
download_info=$(printf '%s\n' "${manifest}" | jq -r ".${host_platform}")
|
||||
if [[ "${download_info}" == "null" ]]; then
|
||||
# Even if host_env is musl, we won't issue an error here because it seems that in
|
||||
# some cases linux-gnu binaries will work on linux-musl hosts.
|
||||
# https://wiki.alpinelinux.org/wiki/Running_glibc_programs
|
||||
# TODO: However, a warning may make sense.
|
||||
host_platform="${host_arch}_linux_gnu"
|
||||
download_info=$(jq -r ".${host_platform}" <<<"${manifest}")
|
||||
download_info=$(printf '%s\n' "${manifest}" | jq -r ".${host_platform}")
|
||||
elif [[ "${host_env}" == "gnu" ]]; then
|
||||
# TODO: don't hardcode tool name and use 'prefer_linux_gnu' field in base manifest.
|
||||
case "${tool}" in
|
||||
cargo-nextest)
|
||||
# TODO: don't hardcode required glibc version
|
||||
required_glibc_version=2.27
|
||||
higher_glibc_version=$(LC_ALL=C sort -Vu <<<"${required_glibc_version}"$'\n'"${host_glibc_version}" | tail -1)
|
||||
higher_glibc_version=$(printf '%s\n%s\n' "${required_glibc_version}" "${host_glibc_version}" | LC_ALL=C sort -Vu | tail -1)
|
||||
if [[ "${higher_glibc_version}" == "${host_glibc_version}" ]]; then
|
||||
# musl build of nextest is slow, so use glibc build if host_env is gnu.
|
||||
# https://github.com/taiki-e/install-action/issues/13
|
||||
host_platform="${host_arch}_linux_gnu"
|
||||
download_info=$(jq -r ".${host_platform}" <<<"${manifest}")
|
||||
download_info=$(printf '%s\n' "${manifest}" | jq -r ".${host_platform}")
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
@@ -289,10 +290,10 @@ read_manifest() {
|
||||
# Binaries compiled for x86_64 macOS will usually also work on AArch64 macOS.
|
||||
# Binaries compiled for x86_64 Windows will usually also work on AArch64 Windows 11+.
|
||||
host_platform="${host_arch}_${host_os}"
|
||||
download_info=$(jq -r ".${host_platform}" <<<"${manifest}")
|
||||
download_info=$(printf '%s\n' "${manifest}" | jq -r ".${host_platform}")
|
||||
if [[ "${download_info}" == "null" ]] && [[ "${host_arch}" != "x86_64" ]]; then
|
||||
host_platform="x86_64_${host_os}"
|
||||
download_info=$(jq -r ".${host_platform}" <<<"${manifest}")
|
||||
download_info=$(printf '%s\n' "${manifest}" | jq -r ".${host_platform}")
|
||||
fi
|
||||
;;
|
||||
*) bail "unsupported OS type '${host_os}' for ${tool}" ;;
|
||||
@@ -304,25 +305,25 @@ read_download_info() {
|
||||
if [[ "${download_info}" == "null" ]]; then
|
||||
bail "${tool}@${version} for '${host_os}' is not supported"
|
||||
fi
|
||||
checksum=$(jq -r '.checksum' <<<"${download_info}")
|
||||
url=$(jq -r '.url' <<<"${download_info}")
|
||||
checksum=$(printf '%s\n' "${download_info}" | jq -r '.checksum')
|
||||
url=$(printf '%s\n' "${download_info}" | jq -r '.url')
|
||||
local tmp
|
||||
bin_in_archive=()
|
||||
if [[ "${url}" == "null" ]]; then
|
||||
local template
|
||||
template=$(jq -c ".template.${host_platform}" "${manifest_dir}/${tool}.json")
|
||||
template="${template//\$\{version\}/${exact_version}}"
|
||||
url=$(jq -r '.url' <<<"${template}")
|
||||
tmp=$(jq -r '.bin' <<<"${template}")
|
||||
url=$(printf '%s\n' "${template}" | jq -r '.url')
|
||||
tmp=$(printf '%s\n' "${template}" | jq -r '.bin')
|
||||
if [[ "${tmp}" == *"["* ]]; then
|
||||
# shellcheck disable=SC2207
|
||||
bin_in_archive=($(jq -r '.bin[]' <<<"${template}"))
|
||||
bin_in_archive=($(printf '%s\n' "${template}" | jq -r '.bin[]'))
|
||||
fi
|
||||
else
|
||||
tmp=$(jq -r '.bin' <<<"${download_info}")
|
||||
tmp=$(printf '%s\n' "${download_info}" | jq -r '.bin')
|
||||
if [[ "${tmp}" == *"["* ]]; then
|
||||
# shellcheck disable=SC2207
|
||||
bin_in_archive=($(jq -r '.bin[]' <<<"${download_info}"))
|
||||
bin_in_archive=($(printf '%s\n' "${download_info}" | jq -r '.bin[]'))
|
||||
fi
|
||||
fi
|
||||
if [[ ${#bin_in_archive[@]} -eq 0 ]]; then
|
||||
@@ -431,7 +432,7 @@ init_install_action_bin_dir() {
|
||||
}
|
||||
canonicalize_windows_path() {
|
||||
case "${host_os}" in
|
||||
windows) sed -E 's/^\/cygdrive\//\//; s/^\/c\//C:\\/; s/\//\\/g' <<<"$1" ;;
|
||||
windows) printf '%s\n' "$1" | sed -E 's/^\/cygdrive\//\//; s/^\/c\//C:\\/; s/\//\\/g' ;;
|
||||
*) printf '%s\n' "$1" ;;
|
||||
esac
|
||||
}
|
||||
@@ -483,11 +484,11 @@ case "$(uname -s)" in
|
||||
Linux)
|
||||
host_os=linux
|
||||
ldd_version=$(ldd --version 2>&1 || true)
|
||||
if grep -Fq musl <<<"${ldd_version}"; then
|
||||
if printf '%s\n' "${ldd_version}" | grep -Fq musl; then
|
||||
host_env=musl
|
||||
else
|
||||
host_env=gnu
|
||||
host_glibc_version=$(grep -E "GLIBC|GNU libc" <<<"${ldd_version}" | sed -E "s/.* //g")
|
||||
host_glibc_version=$(printf '%s\n' "${ldd_version}" | grep -E "GLIBC|GNU libc" | sed -E "s/.* //g")
|
||||
fi
|
||||
if [[ -e /etc/os-release ]]; then
|
||||
if grep -Eq '^ID_LIKE=' /etc/os-release; then
|
||||
@@ -654,9 +655,9 @@ case "${host_os}" in
|
||||
jq() { "${install_action_dir}/jq/bin/jq.exe" -b "$@"; }
|
||||
elif type -P jq >/dev/null; then
|
||||
# https://github.com/jqlang/jq/issues/1854
|
||||
_tmp=$(jq -r .a <<<'{}' | wc -c)
|
||||
_tmp=$(printf '{}\n' | jq -r .a | wc -c)
|
||||
if [[ "${_tmp}" != 5 ]]; then
|
||||
_tmp=$({ jq -b -r .a 2>/dev/null <<<'{}' || true; } | wc -c)
|
||||
_tmp=$({ printf '{}\n' | jq -b -r .a 2>/dev/null || true; } | wc -c)
|
||||
if [[ "${_tmp}" == 5 ]]; then
|
||||
jq() { command jq -b "$@"; }
|
||||
else
|
||||
@@ -685,8 +686,8 @@ for tool in "${tools[@]}"; do
|
||||
if [[ "${tool}" == *"@"* ]]; then
|
||||
version="${tool#*@}"
|
||||
tool="${tool%@*}"
|
||||
if [[ ! "${version}" =~ ^([1-9][0-9]*(\.[0-9]+(\.[0-9]+)?)?|0\.[1-9][0-9]*(\.[0-9]+)?|^0\.0\.[0-9]+)(-[0-9A-Za-z\.-]+)?$|^latest$ ]]; then
|
||||
if [[ ! "${version}" =~ ^([1-9][0-9]*(\.[0-9]+(\.[0-9]+)?)?|0\.[1-9][0-9]*(\.[0-9]+)?|^0\.0\.[0-9]+)(-[0-9A-Za-z\.-]+)?(\+[0-9A-Za-z\.-]+)?$|^latest$ ]]; then
|
||||
if ! printf '%s\n' "${version}" | grep -Eq '^([1-9][0-9]*(\.[0-9]+(\.[0-9]+)?)?|0\.[1-9][0-9]*(\.[0-9]+)?|^0\.0\.[0-9]+)(-[0-9A-Za-z\.-]+)?$|^latest$'; then
|
||||
if ! printf '%s\n' "${version}" | grep -Eq '^([1-9][0-9]*(\.[0-9]+(\.[0-9]+)?)?|0\.[1-9][0-9]*(\.[0-9]+)?|^0\.0\.[0-9]+)(-[0-9A-Za-z\.-]+)?(\+[0-9A-Za-z\.-]+)?$|^latest$'; then
|
||||
bail "install-action does not support semver operators: '${version}'"
|
||||
fi
|
||||
bail "install-action v2 does not support semver build-metadata: '${version}'; if you need these supports again, please submit an issue at <https://github.com/taiki-e/install-action>"
|
||||
|
||||
27
manifests/cargo-nextest.json
generated
27
manifests/cargo-nextest.json
generated
@@ -19,10 +19,33 @@
|
||||
},
|
||||
"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": {
|
||||
"version": "0.9.126"
|
||||
"version": "0.9.127"
|
||||
},
|
||||
"0.9": {
|
||||
"version": "0.9.126"
|
||||
"version": "0.9.127"
|
||||
},
|
||||
"0.9.127": {
|
||||
"previous_stable_version": "0.9.126",
|
||||
"x86_64_linux_gnu": {
|
||||
"etag": "0x8DE6B2F56693476",
|
||||
"checksum": "0a9d356170528ba92a65fd0157ec0445a67d1f7c2c5726085656e55ba8a1b976"
|
||||
},
|
||||
"x86_64_linux_musl": {
|
||||
"etag": "0x8DE6B2ED81EC9E7",
|
||||
"checksum": "51648aa64c76c87e6357195c9bbb702bda8b2b6fbeeae0960926556b7aea37bc"
|
||||
},
|
||||
"x86_64_macos": {
|
||||
"etag": "0x8DE6B2F967EE463",
|
||||
"checksum": "c814033126902b9f06fc5d01651c6dafc634b3a7a27d3ad87a893f749027f661"
|
||||
},
|
||||
"x86_64_windows": {
|
||||
"etag": "0x8DE6B30804FF2E7",
|
||||
"checksum": "c00d48d96a5fdbac7664532fa81a07602242f5b9618980350997664d109d222b"
|
||||
},
|
||||
"aarch64_linux_gnu": {
|
||||
"etag": "0x8DE6B2E95DD5A04",
|
||||
"checksum": "ce9f682227a131497227f84328e0b2eb36d2a7f43515f867a47bdb35c69516e4"
|
||||
}
|
||||
},
|
||||
"0.9.126": {
|
||||
"previous_stable_version": "0.9.125",
|
||||
|
||||
@@ -16,7 +16,7 @@ serde_derive = "1"
|
||||
serde_json = "1"
|
||||
spdx = "0.13"
|
||||
tar = "0.4"
|
||||
toml = { version = "0.9", default-features = false, features = ["parse", "serde"] }
|
||||
toml = { version = "1", default-features = false, features = ["parse", "serde"] }
|
||||
# TODO: call curl command instead of using ureq?
|
||||
ureq = { version = "2", features = ["json"] }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user