diff --git a/.github/.cspell/project-dictionary.txt b/.github/.cspell/project-dictionary.txt index 8c08dd19..4f28f1d5 100644 --- a/.github/.cspell/project-dictionary.txt +++ b/.github/.cspell/project-dictionary.txt @@ -36,6 +36,7 @@ sccache SHASUMS shortstat sigstore +startswith syft tombi udeps diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e87b9461..f122f803 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -181,9 +181,12 @@ jobs: strategy: fail-fast: false matrix: - fallback: - - none - - cargo-install + include: + - fallback: none + - fallback: cargo-install + - fallback: cargo-binstall + - fallback: cargo-binstall + version: 0.3 runs-on: ubuntu-24.04-arm timeout-minutes: 60 steps: @@ -195,7 +198,7 @@ jobs: id: install continue-on-error: ${{ matrix.fallback == 'none' }} with: - tool: parse-changelog@0.4.6 + tool: parse-changelog@${{ matrix.version || '0.4.6' }} fallback: ${{ matrix.fallback }} - run: exit 1 if: matrix.fallback == 'none' && steps.install.outcome != 'failure' diff --git a/CHANGELOG.md b/CHANGELOG.md index 3eef6dd0..bf7e9e26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ Note: In this file, do not use the hard wrap in the middle of a sentence for com ## [Unreleased] +- Enhance security when cargo-binstall fallback is enabled. + ## [2.75.8] - 2026-04-13 - Update `vacuum@latest` to 0.25.8. diff --git a/main.sh b/main.sh index 6bfec02e..38a13681 100755 --- a/main.sh +++ b/main.sh @@ -928,11 +928,61 @@ if [[ ${#unsupported_tools[@]} -gt 0 ]]; then # By default, cargo-binstall enforce downloads over secure transports only. # As a result, http will be disabled, and it will also set # min tls version to be 1.2 - binstall_args=(--force --no-confirm --locked "${unsupported_tools[@]}") - if [[ -n "${token}" ]]; then - cargo-binstall binstall --github-token "${token}" "${binstall_args[@]}" - else - cargo-binstall binstall "${binstall_args[@]}" + binstall_args=( + --force + --no-confirm + --locked + # Since the build script can access the token when `cargo install` is called + # within `cargo-binstall`, disables building from source in cargo-binstall + # and fallback to `cargo install` which doesn't need the token. + --disable-strategies compile + ) + unsupported_tools2=() + for tool in "${unsupported_tools[@]}"; do + if [[ -n "${token}" ]]; then + if ! GITHUB_TOKEN="${token}" cargo-binstall binstall "${binstall_args[@]}" "${tool}"; then + warn "cargo-binstall fallback does not support prebuilt binaries for ${tool} on this platform (${host_arch}); use 'cargo-install' fallback instead" + unsupported_tools2+=("${tool}") + fi + else + if ! cargo-binstall binstall "${binstall_args[@]}" "${tool}"; then + warn "cargo-binstall fallback does not support prebuilt binaries for ${tool} on this platform (${host_arch}); use 'cargo-install' fallback instead" + unsupported_tools2+=("${tool}") + fi + fi + done + if [[ ${#unsupported_tools2[@]} -gt 0 ]]; then + for tool in "${unsupported_tools2[@]}"; do + cargo_args=(--locked) + 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\.-]+)?(\+[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 + bail "install-action does not support non-semver version: '${version}'" + fi + crate_info=$(retry curl --user-agent "${ACTION_USER_AGENT}" --proto '=https' --tlsv1.2 -fsSL --retry 10 "https://crates.io/api/v1/crates/${tool}") + if [[ ! "${version}" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then + bail "install-action does not support non-semver version: '${version}'" + fi + # shellcheck disable=SC2207 + versions=($(jq -r --arg start "${version}." '.versions[] | select(.num | startswith($start)) | select(.yanked == false) | .num' <<<"${crate_info}")) + full_version='' + for v in ${versions[@]+"${versions[@]}"}; do + if [[ "${v}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(\+[0-9A-Za-z\.-]+)?$ ]]; then + full_version="${v}" + break + fi + done + if [[ -z "${full_version}" ]]; then + bail "no stable version found for ${tool} that match with '${version}.*'; if you want to install a pre-release version, please specify the full version" + fi + version="${full_version}" + fi + cargo_args+=(--version "${version}") + fi + cargo install "${cargo_args[@]}" "${tool}" + done fi if ! type -P cargo >/dev/null; then _bin_dir=$(canonicalize_windows_path "${home}/.cargo/bin")