Compare commits

...

13 Commits

Author SHA1 Message Date
Taiki Endo
1014a1e7a6 Release 2.34.1 2024-06-03 22:18:17 +09:00
Taiki Endo
df03a8f339 tools: Update tidy.sh 2024-06-03 21:58:51 +09:00
Taiki Endo
1bd25cfd26 Update git-cliff@latest to 2.3.0 2024-06-03 21:50:37 +09:00
Taiki Endo
4e38715ddc Release 2.34.0 2024-06-02 01:14:31 +09:00
Taiki Endo
2d4372270d Support cargo-binstall fallback without cargo 2024-06-02 01:13:32 +09:00
Taiki Endo
e5240ce0c5 Release 2.33.36 2024-06-02 00:14:03 +09:00
Taiki Endo
cd2b50cd20 Update cargo-llvm-cov@latest to 0.6.10 2024-06-02 00:12:05 +09:00
Taiki Endo
08b0c77d33 Update cspell dictionary 2024-05-31 00:23:30 +09:00
Taiki Endo
51b8ba088c Release 2.33.35 2024-05-29 03:20:16 +09:00
Taiki Endo
c46ebac92e Ignore more lints at workspace level 2024-05-29 03:15:59 +09:00
Taiki Endo
6058afcbf2 Update syft@latest to 1.5.0 2024-05-29 03:11:44 +09:00
Taiki Endo
60784cb1f4 Release 2.33.34 2024-05-27 08:51:32 +09:00
Taiki Endo
ccdec58fd9 Update dprint@latest to 0.46.1 2024-05-27 06:11:24 +09:00
13 changed files with 220 additions and 149 deletions

View File

@@ -44,7 +44,7 @@
"languageSettings": [ "languageSettings": [
{ {
"languageId": ["*"], "languageId": ["*"],
"dictionaries": ["rust"] "dictionaries": ["bash", "rust"]
} }
], ],
"ignorePaths": [] "ignorePaths": []

View File

@@ -22,7 +22,6 @@ pwsh
quickinstall quickinstall
rdme rdme
sccache sccache
shfmt
syft syft
udeps udeps
wasmtime wasmtime

View File

@@ -66,10 +66,10 @@ jobs:
tool: ${{ steps.tool-list.outputs.tool }} tool: ${{ steps.tool-list.outputs.tool }}
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsshell # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsshell
- name: Test bash - name: Test bash
run: just --version; shfmt --version; protoc --version run: just --version && shfmt --version && protoc --version
shell: bash shell: bash
- name: Test sh - name: Test sh
run: just --version; shfmt --version; protoc --version run: just --version && shfmt --version && protoc --version
shell: sh shell: sh
if: startsWith(matrix.os, 'ubuntu') || startsWith(matrix.os, 'macos') if: startsWith(matrix.os, 'ubuntu') || startsWith(matrix.os, 'macos')
- name: Test pwsh - name: Test pwsh
@@ -118,29 +118,8 @@ jobs:
timeout-minutes: 60 timeout-minutes: 60
container: ${{ matrix.container }} container: ${{ matrix.container }}
steps: steps:
- name: Install requirements (ubuntu/debian)
run: |
set -eEuxo pipefail
apt-get -o Acquire::Retries=10 -qq update
apt-get -o Acquire::Retries=10 -o Dpkg::Use-Pty=0 install -y --no-install-recommends cargo
if: startsWith(matrix.container, 'ubuntu') || startsWith(matrix.container, 'debian')
- name: Install requirements (fedora/almalinux/centos)
run: |
set -eEuxo pipefail
curl --proto '=https' --tlsv1.2 -fsSL --retry 10 https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain stable --no-modify-path
echo "$HOME/.cargo/bin" >>"${GITHUB_PATH}"
if: startsWith(matrix.container, 'fedora') || startsWith(matrix.container, 'almalinux') || startsWith(matrix.container, 'centos')
- name: Install requirements (opensuse)
run: |
set -eEuxo pipefail
zypper install -y rustup
rustup toolchain add stable --profile minimal
if: startsWith(matrix.container, 'opensuse')
- name: Install requirements (archlinux)
run: pacman -Sy --noconfirm rust
if: startsWith(matrix.container, 'archlinux')
- name: Install requirements (alpine) - name: Install requirements (alpine)
run: apk --no-cache add bash cargo run: apk --no-cache add bash
shell: sh shell: sh
if: startsWith(matrix.container, 'alpine') if: startsWith(matrix.container, 'alpine')
- uses: taiki-e/checkout-action@v1 - uses: taiki-e/checkout-action@v1
@@ -153,19 +132,6 @@ jobs:
with: with:
tool: ${{ steps.tool-list.outputs.tool }} tool: ${{ steps.tool-list.outputs.tool }}
test-no-cargo:
runs-on: ubuntu-latest
timeout-minutes: 60
container: ubuntu
steps:
- uses: taiki-e/checkout-action@v1
- name: Generate tool list
id: tool-list
run: tools/ci/tool-list.sh >>"${GITHUB_OUTPUT}"
- uses: ./
with:
tool: ${{ steps.tool-list.outputs.tool }}
manifest: manifest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 60 timeout-minutes: 60

View File

@@ -10,6 +10,26 @@ Note: In this file, do not use the hard wrap in the middle of a sentence for com
## [Unreleased] ## [Unreleased]
## [2.34.1] - 2024-06-03
- Update `git-cliff@latest` to 2.3.0.
## [2.34.0] - 2024-06-01
- Support cargo-binstall fallback without cargo.
## [2.33.36] - 2024-06-01
- Update `cargo-llvm-cov@latest` to 0.6.10.
## [2.33.35] - 2024-05-28
- Update `syft@latest` to 1.5.0.
## [2.33.34] - 2024-05-26
- Update `dprint@latest` to 0.46.1.
## [2.33.33] - 2024-05-25 ## [2.33.33] - 2024-05-25
- Update `dprint@latest` to 0.46.0. - Update `dprint@latest` to 0.46.0.
@@ -2215,7 +2235,12 @@ 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.33.33...HEAD [Unreleased]: https://github.com/taiki-e/install-action/compare/v2.34.1...HEAD
[2.34.1]: https://github.com/taiki-e/install-action/compare/v2.34.0...v2.34.1
[2.34.0]: https://github.com/taiki-e/install-action/compare/v2.33.36...v2.34.0
[2.33.36]: https://github.com/taiki-e/install-action/compare/v2.33.35...v2.33.36
[2.33.35]: https://github.com/taiki-e/install-action/compare/v2.33.34...v2.33.35
[2.33.34]: https://github.com/taiki-e/install-action/compare/v2.33.33...v2.33.34
[2.33.33]: https://github.com/taiki-e/install-action/compare/v2.33.32...v2.33.33 [2.33.33]: https://github.com/taiki-e/install-action/compare/v2.33.32...v2.33.33
[2.33.32]: https://github.com/taiki-e/install-action/compare/v2.33.31...v2.33.32 [2.33.32]: https://github.com/taiki-e/install-action/compare/v2.33.31...v2.33.32
[2.33.31]: https://github.com/taiki-e/install-action/compare/v2.33.30...v2.33.31 [2.33.31]: https://github.com/taiki-e/install-action/compare/v2.33.30...v2.33.31

View File

@@ -10,6 +10,8 @@ improper_ctypes_definitions = "warn"
non_ascii_idents = "warn" non_ascii_idents = "warn"
rust_2018_idioms = "warn" rust_2018_idioms = "warn"
single_use_lifetimes = "warn" single_use_lifetimes = "warn"
unexpected_cfgs = { level = "warn", check-cfg = [
] }
unreachable_pub = "warn" unreachable_pub = "warn"
unsafe_op_in_unsafe_fn = "warn" unsafe_op_in_unsafe_fn = "warn"
[workspace.lints.clippy] [workspace.lints.clippy]
@@ -27,12 +29,13 @@ borrow_as_ptr = { level = "allow", priority = 1 } # https://github.com/rust-lang
declare_interior_mutable_const = { level = "allow", priority = 1 } # https://github.com/rust-lang/rust-clippy/issues/7665 declare_interior_mutable_const = { level = "allow", priority = 1 } # https://github.com/rust-lang/rust-clippy/issues/7665
doc_markdown = { level = "allow", priority = 1 } doc_markdown = { level = "allow", priority = 1 }
float_cmp = { level = "allow", priority = 1 } # https://github.com/rust-lang/rust-clippy/issues/7725 float_cmp = { level = "allow", priority = 1 } # https://github.com/rust-lang/rust-clippy/issues/7725
lint_groups_priority = { level = "allow", priority = 1 } # clippy bug: https://github.com/rust-lang/rust-clippy/issues/12270 incompatible_msrv = { level = "allow", priority = 1 } # buggy: doesn't consider cfg, https://github.com/rust-lang/rust-clippy/issues/12280, https://github.com/rust-lang/rust-clippy/issues/12257#issuecomment-2093667187
lint_groups_priority = { level = "allow", priority = 1 } # https://github.com/rust-lang/rust-clippy/issues/12270
manual_assert = { level = "allow", priority = 1 } manual_assert = { level = "allow", priority = 1 }
manual_range_contains = { level = "allow", priority = 1 } # https://github.com/rust-lang/rust-clippy/issues/6455#issuecomment-1225966395 manual_range_contains = { level = "allow", priority = 1 } # https://github.com/rust-lang/rust-clippy/issues/6455#issuecomment-1225966395
missing_errors_doc = { level = "allow", priority = 1 } missing_errors_doc = { level = "allow", priority = 1 }
module_name_repetitions = { level = "allow", priority = 1 } module_name_repetitions = { level = "allow", priority = 1 }
nonminimal_bool = { level = "allow", priority = 1 } # buggy https://github.com/rust-lang/rust-clippy/issues?q=is%3Aissue+is%3Aopen+nonminimal_bool nonminimal_bool = { level = "allow", priority = 1 } # buggy: https://github.com/rust-lang/rust-clippy/issues?q=is%3Aissue+is%3Aopen+nonminimal_bool
similar_names = { level = "allow", priority = 1 } similar_names = { level = "allow", priority = 1 }
single_match = { level = "allow", priority = 1 } single_match = { level = "allow", priority = 1 }
single_match_else = { level = "allow", priority = 1 } single_match_else = { level = "allow", priority = 1 }

View File

@@ -152,7 +152,6 @@ This action has been tested for GitHub-hosted runners (Ubuntu, macOS, Windows) a
To use this action in self-hosted runners or in containers, at least the following tools are required: To use this action in self-hosted runners or in containers, at least the following tools are required:
- bash - bash
- cargo (if you use cargo-binstall fallback)
## Related Projects ## Related Projects

View File

@@ -748,5 +748,11 @@ if [[ ${#unsupported_tools[@]} -gt 0 ]]; then
# By default, cargo-binstall enforce downloads over secure transports only. # By default, cargo-binstall enforce downloads over secure transports only.
# As a result, http will be disabled, and it will also set # As a result, http will be disabled, and it will also set
# min tls version to be 1.2 # min tls version to be 1.2
cargo binstall --force --no-confirm --locked "${unsupported_tools[@]}" cargo-binstall binstall --force --no-confirm --locked "${unsupported_tools[@]}"
if ! type -P cargo >/dev/null; then
_bin_dir=$(canonicalize_windows_path "${HOME}/.cargo/bin")
# TODO: avoid this when already added
info "adding '${_bin_dir}' to PATH"
echo "${_bin_dir}" >>"${GITHUB_PATH}"
fi
fi fi

View File

@@ -18,10 +18,27 @@
} }
}, },
"latest": { "latest": {
"version": "0.6.9" "version": "0.6.10"
}, },
"0.6": { "0.6": {
"version": "0.6.9" "version": "0.6.10"
},
"0.6.10": {
"x86_64_linux_musl": {
"checksum": "2350d7d6586c8b1ac828ad5578225fafb6a43fa9c35fe835c28a5ed63499df60"
},
"x86_64_macos": {
"checksum": "6355b4536798ba0cea459729cc531f7bbf252d51c86b02683c0b4a4033d8cb96"
},
"x86_64_windows": {
"checksum": "3090e71ba2c0e16e593d338f4ed696f3829544f53dea63bdd966398f4379259c"
},
"aarch64_linux_musl": {
"checksum": "7921682e7bd925b69bbecaf9bf42f99a6404ef60049b1a9f87fe97dc697265f4"
},
"aarch64_macos": {
"checksum": "46fe1d529755ca1a39dc7995374eef4482a20f0f632dd113430641c06fc4b466"
}
}, },
"0.6.9": { "0.6.9": {
"x86_64_linux_musl": { "x86_64_linux_musl": {

21
manifests/dprint.json generated
View File

@@ -24,10 +24,27 @@
} }
}, },
"latest": { "latest": {
"version": "0.46.0" "version": "0.46.1"
}, },
"0.46": { "0.46": {
"version": "0.46.0" "version": "0.46.1"
},
"0.46.1": {
"x86_64_linux_musl": {
"checksum": "4a7d6fa6b920ab150f580965556086cdd7992e07078e627ab9a9d1c3bd30ba85"
},
"x86_64_macos": {
"checksum": "cdea84bce1d84c26e8eced2265d246b79a849ec2e7d1377d98dd7bdb21c7ce83"
},
"x86_64_windows": {
"checksum": "74e5ab38c744d5903862c2b5174d0fef9759b5506da775e1fb93b6a68c63101d"
},
"aarch64_linux_musl": {
"checksum": "e2b6d87167d21f1f01571790e79526ef9caff3b8b75f5cac348c4f06f60a8c16"
},
"aarch64_macos": {
"checksum": "f3ff4faef83d14c3b4ae262e79a40d4e0fc3fa1903d0b6e9b82f0b25b00e9499"
}
}, },
"0.46.0": { "0.46.0": {
"x86_64_linux_musl": { "x86_64_linux_musl": {

View File

@@ -27,10 +27,33 @@
} }
}, },
"latest": { "latest": {
"version": "2.2.2" "version": "2.3.0"
}, },
"2": { "2": {
"version": "2.2.2" "version": "2.3.0"
},
"2.3": {
"version": "2.3.0"
},
"2.3.0": {
"x86_64_linux_musl": {
"checksum": "0371c0c2fd948a711d05198f719a2ec8ccb2a43ae5e4760394916d5cf6b45c6c"
},
"x86_64_macos": {
"checksum": "73ce46c671a593fe1acef725e7816c793968e3c315fd72107280e830eaa55820"
},
"x86_64_windows": {
"checksum": "90bc9c60b5db44a62fae51fb09e9565e2d460e107df3404ac5384a2f0bdd96d1"
},
"aarch64_linux_musl": {
"checksum": "aed0a6fba4d5b309be98ef71db75928c84c57495d46843791e95870582f0d1a6"
},
"aarch64_macos": {
"checksum": "1fd8e277212db52c791a20b6ecdb993ce47884a1aca3ee3d31066fd29acea6bb"
},
"aarch64_windows": {
"checksum": "059a29642ffe16ad720cb383290564df35bddd329fa34f6d1d1a4f633d6dad48"
}
}, },
"2.2": { "2.2": {
"version": "2.2.2" "version": "2.2.2"

24
manifests/syft.json generated
View File

@@ -23,10 +23,30 @@
} }
}, },
"latest": { "latest": {
"version": "1.4.1" "version": "1.5.0"
}, },
"1": { "1": {
"version": "1.4.1" "version": "1.5.0"
},
"1.5": {
"version": "1.5.0"
},
"1.5.0": {
"x86_64_linux_musl": {
"checksum": "3d10023d46dfaf0fe75288df207b478b43597f7d2fff553f58430817166bd478"
},
"x86_64_macos": {
"checksum": "605322e3e7043a4f2f3d6e37f75a71389d38f6f290bff2e54bb2aaebbbf4829b"
},
"x86_64_windows": {
"checksum": "5079c6a88e130f8677d0701cb2689f9eae2088022ecf5fa2b9f341b96d9983d2"
},
"aarch64_linux_musl": {
"checksum": "ee2b1289a1e4b0de9409c3a78867949ca42788a5f50072b8a6e6e04e6a269f9c"
},
"aarch64_macos": {
"checksum": "fe02d072e7ec9a8eb4ac866ba973396a8beae79829ee870acaadd4d862e5e65a"
}
}, },
"1.4": { "1.4": {
"version": "1.4.1" "version": "1.4.1"

View File

@@ -128,17 +128,14 @@ case "${host_os}" in
fi fi
;; ;;
esac esac
# cargo-binstall requires cargo # cargo-watch/watchexec-cli is supported by cargo-binstall (through quickinstall)
if type -P cargo &>/dev/null; then case "${version}" in
# cargo-watch/watchexec-cli is supported by cargo-binstall (through quickinstall) latest) tools+=(cargo-watch watchexec-cli nextest) ;;
case "${version}" in major.minor.patch) tools+=(cargo-watch@8.1.1 watchexec-cli@1.20.5 nextest@0.9.57) ;;
latest) tools+=(cargo-watch watchexec-cli nextest) ;; major.minor) tools+=(cargo-watch@8.1 watchexec-cli@1.20 nextest@0.9) ;;
major.minor.patch) tools+=(cargo-watch@8.1.1 watchexec-cli@1.20.5 nextest@0.9.57) ;; major) tools+=(cargo-watch@8 watchexec-cli@1) ;;
major.minor) tools+=(cargo-watch@8.1 watchexec-cli@1.20 nextest@0.9) ;; *) exit 1 ;;
major) tools+=(cargo-watch@8 watchexec-cli@1) ;; esac
*) exit 1 ;;
esac
fi
# sort and dedup # sort and dedup
IFS=$'\n' IFS=$'\n'

View File

@@ -16,7 +16,7 @@ trap 's=$?; echo >&2 "$0: error on line "${LINENO}": ${BASH_COMMAND}"; exit ${s}
# - shellcheck # - shellcheck
# - npm # - npm
# - jq # - jq
# - python # - python 3
# - rustup (if Rust code exists) # - rustup (if Rust code exists)
# - clang-format (if C/C++ code exists) # - clang-format (if C/C++ code exists)
# #
@@ -40,6 +40,19 @@ check_config() {
error "could not found $1 in the repository root" error "could not found $1 in the repository root"
fi fi
} }
check_install() {
for tool in "$@"; do
if ! type -P "${tool}" &>/dev/null; then
if [[ "${tool}" == "python3" ]]; then
if type -P python &>/dev/null; then
continue
fi
fi
error "'${tool}' is required to run this check"
return 1
fi
done
}
info() { info() {
echo >&2 "info: $*" echo >&2 "info: $*"
} }
@@ -56,6 +69,27 @@ venv() {
shift shift
"${venv_bin}/${bin}${exe}" "$@" "${venv_bin}/${bin}${exe}" "$@"
} }
venv_install_yq() {
local py_suffix=''
if type -P python3 &>/dev/null; then
py_suffix='3'
fi
exe=''
venv_bin='.venv/bin'
case "$(uname -s)" in
MINGW* | MSYS* | CYGWIN* | Windows_NT)
exe='.exe'
venv_bin='.venv/Scripts'
;;
esac
if [[ ! -d .venv ]]; then
"python${py_suffix}" -m venv .venv
fi
if [[ ! -e "${venv_bin}/yq${exe}" ]]; then
info "installing yq to ./.venv using pip"
venv "pip${py_suffix}" install yq
fi
}
if [[ $# -gt 0 ]]; then if [[ $# -gt 0 ]]; then
cat <<EOF cat <<EOF
@@ -68,24 +102,23 @@ fi
# Rust (if exists) # Rust (if exists)
if [[ -n "$(git ls-files '*.rs')" ]]; then if [[ -n "$(git ls-files '*.rs')" ]]; then
info "checking Rust code style" info "checking Rust code style"
check_install cargo jq python3
check_config .rustfmt.toml check_config .rustfmt.toml
if type -P rustup &>/dev/null; then if check_install rustup; then
# `cargo fmt` cannot recognize files not included in the current workspace and modules # `cargo fmt` cannot recognize files not included in the current workspace and modules
# defined inside macros, so run rustfmt directly. # defined inside macros, so run rustfmt directly.
# We need to use nightly rustfmt because we use the unstable formatting options of rustfmt. # We need to use nightly rustfmt because we use the unstable formatting options of rustfmt.
rustc_version=$(rustc -vV | grep '^release:' | cut -d' ' -f2) rustc_version=$(rustc -vV | grep '^release:' | cut -d' ' -f2)
if [[ "${rustc_version}" == *"nightly"* ]] || [[ "${rustc_version}" == *"dev"* ]]; then if [[ "${rustc_version}" == *"nightly"* ]] || [[ "${rustc_version}" == *"dev"* ]]; then
rustup component add rustfmt &>/dev/null rustup component add rustfmt &>/dev/null
echo "+ rustfmt \$(git ls-files '*.rs')" info "running \`rustfmt \$(git ls-files '*.rs')\`"
rustfmt $(git ls-files '*.rs') rustfmt $(git ls-files '*.rs')
else else
rustup component add rustfmt --toolchain nightly &>/dev/null rustup component add rustfmt --toolchain nightly &>/dev/null
echo "+ rustfmt +nightly \$(git ls-files '*.rs')" info "running \`rustfmt +nightly \$(git ls-files '*.rs')\`"
rustfmt +nightly $(git ls-files '*.rs') rustfmt +nightly $(git ls-files '*.rs')
fi fi
check_diff $(git ls-files '*.rs') check_diff $(git ls-files '*.rs')
else
error "'rustup' is not installed; skipped Rust code style check"
fi fi
cast_without_turbofish=$(grep -n -E '\.cast\(\)' $(git ls-files '*.rs') || true) cast_without_turbofish=$(grep -n -E '\.cast\(\)' $(git ls-files '*.rs') || true)
if [[ -n "${cast_without_turbofish}" ]]; then if [[ -n "${cast_without_turbofish}" ]]; then
@@ -122,11 +155,12 @@ if [[ -n "$(git ls-files '*.rs')" ]]; then
binaries='' binaries=''
metadata=$(cargo metadata --format-version=1 --no-deps) metadata=$(cargo metadata --format-version=1 --no-deps)
has_public_crate='' has_public_crate=''
venv_install_yq
for id in $(jq <<<"${metadata}" '.workspace_members[]'); do for id in $(jq <<<"${metadata}" '.workspace_members[]'); do
pkg=$(jq <<<"${metadata}" ".packages[] | select(.id == ${id})") pkg=$(jq <<<"${metadata}" ".packages[] | select(.id == ${id})")
publish=$(jq <<<"${pkg}" -r '.publish') publish=$(jq <<<"${pkg}" -r '.publish')
manifest_path=$(jq <<<"${pkg}" -r '.manifest_path') manifest_path=$(jq <<<"${pkg}" -r '.manifest_path')
if ! grep -q '^\[lints\]' "${manifest_path}" && ! grep -q '^\[lints\.rust\]' "${manifest_path}"; then if [[ "$(venv tomlq -c '.lints' "${manifest_path}")" == "null" ]]; then
error "no [lints] table in ${manifest_path} please add '[lints]' with 'workspace = true'" error "no [lints] table in ${manifest_path} please add '[lints]' with 'workspace = true'"
fi fi
# Publishing is unrestricted if null, and forbidden if an empty array. # Publishing is unrestricted if null, and forbidden if an empty array.
@@ -144,13 +178,14 @@ if [[ -n "$(git ls-files '*.rs')" ]]; then
publish=$(jq <<<"${root_pkg}" -r '.publish') publish=$(jq <<<"${root_pkg}" -r '.publish')
# Publishing is unrestricted if null, and forbidden if an empty array. # Publishing is unrestricted if null, and forbidden if an empty array.
if [[ "${publish}" != "[]" ]]; then if [[ "${publish}" != "[]" ]]; then
if ! grep -Eq '^exclude = \[.*"/\.\*".*\]' Cargo.toml; then exclude=$(tomlq -r '.package.exclude[]' Cargo.toml)
if ! grep <<<"${exclude}" -Eq '^/\.\*$'; then
error "top-level Cargo.toml of non-virtual workspace should have 'exclude' field with \"/.*\"" error "top-level Cargo.toml of non-virtual workspace should have 'exclude' field with \"/.*\""
fi fi
if [[ -e tools ]] && ! grep -Eq '^exclude = \[.*"/tools".*\]' Cargo.toml; then if [[ -e tools ]] && ! grep <<<"${exclude}" -Eq '^/tools$'; then
error "top-level Cargo.toml of non-virtual workspace should have 'exclude' field with \"/tools\" if it exists" error "top-level Cargo.toml of non-virtual workspace should have 'exclude' field with \"/tools\" if it exists"
fi fi
if [[ -e target-specs ]] && ! grep -Eq '^exclude = \[.*"/target-specs".*\]' Cargo.toml; then if [[ -e target-specs ]] && ! grep <<<"${exclude}" -Eq '^/target-specs$'; then
error "top-level Cargo.toml of non-virtual workspace should have 'exclude' field with \"/target-specs\" if it exists" error "top-level Cargo.toml of non-virtual workspace should have 'exclude' field with \"/target-specs\" if it exists"
fi fi
fi fi
@@ -196,12 +231,10 @@ fi
if [[ -n "$(git ls-files '*.c' '*.h' '*.cpp' '*.hpp')" ]]; then if [[ -n "$(git ls-files '*.c' '*.h' '*.cpp' '*.hpp')" ]]; then
info "checking C/C++ code style" info "checking C/C++ code style"
check_config .clang-format check_config .clang-format
if type -P clang-format &>/dev/null; then if check_install clang-format; then
echo "+ clang-format -i \$(git ls-files '*.c' '*.h' '*.cpp' '*.hpp')" info "running \`clang-format -i \$(git ls-files '*.c' '*.h' '*.cpp' '*.hpp')\`"
clang-format -i $(git ls-files '*.c' '*.h' '*.cpp' '*.hpp') clang-format -i $(git ls-files '*.c' '*.h' '*.cpp' '*.hpp')
check_diff $(git ls-files '*.c' '*.h' '*.cpp' '*.hpp') check_diff $(git ls-files '*.c' '*.h' '*.cpp' '*.hpp')
else
error "'clang-format' is not installed; skipped C/C++ code style check"
fi fi
elif [[ -e .clang-format ]]; then elif [[ -e .clang-format ]]; then
error ".clang-format is unused" error ".clang-format is unused"
@@ -211,64 +244,39 @@ fi
if [[ -n "$(git ls-files '*.yml' '*.yaml' '*.js' '*.json')" ]]; then if [[ -n "$(git ls-files '*.yml' '*.yaml' '*.js' '*.json')" ]]; then
info "checking YAML/JavaScript/JSON code style" info "checking YAML/JavaScript/JSON code style"
check_config .editorconfig check_config .editorconfig
if type -P npm &>/dev/null; then if check_install npm; then
echo "+ npx -y prettier -l -w \$(git ls-files '*.yml' '*.yaml' '*.js' '*.json')" info "running \`npx -y prettier -l -w \$(git ls-files '*.yml' '*.yaml' '*.js' '*.json')\`"
npx -y prettier -l -w $(git ls-files '*.yml' '*.yaml' '*.js' '*.json') npx -y prettier -l -w $(git ls-files '*.yml' '*.yaml' '*.js' '*.json')
check_diff $(git ls-files '*.yml' '*.yaml' '*.js' '*.json') check_diff $(git ls-files '*.yml' '*.yaml' '*.js' '*.json')
else
error "'npm' is not installed; skipped YAML/JavaScript/JSON code style check"
fi fi
# Check GitHub workflows. # Check GitHub workflows.
if [[ -d .github/workflows ]]; then if [[ -d .github/workflows ]]; then
info "checking GitHub workflows" info "checking GitHub workflows"
if type -P jq &>/dev/null; then if check_install jq python3; then
if type -P python3 &>/dev/null || type -P python &>/dev/null; then venv_install_yq
py_suffix='' for workflow in .github/workflows/*.yml; do
if type -P python3 &>/dev/null; then # The top-level permissions must be weak as they are referenced by all jobs.
py_suffix='3' permissions=$(venv yq -c '.permissions' "${workflow}")
fi case "${permissions}" in
exe='' '{"contents":"read"}' | '{"contents":"none"}') ;;
venv_bin='.venv/bin' null) error "${workflow}: top level permissions not found; it must be 'contents: read' or weaker permissions" ;;
case "$(uname -s)" in *) error "${workflow}: only 'contents: read' and weaker permissions are allowed at top level; if you want to use stronger permissions, please set job-level permissions" ;;
MINGW* | MSYS* | CYGWIN* | Windows_NT)
exe='.exe'
venv_bin='.venv/Scripts'
;;
esac esac
if [[ ! -d .venv ]]; then # Make sure the 'needs' section is not out of date.
"python${py_suffix}" -m venv .venv if grep -q '# tidy:needs' "${workflow}" && ! grep -Eq '# *needs: \[' "${workflow}"; then
fi # shellcheck disable=SC2207
if [[ ! -e "${venv_bin}/yq${exe}" ]]; then jobs_actual=($(venv yq '.jobs' "${workflow}" | jq -r 'keys_unsorted[]'))
venv "pip${py_suffix}" install yq unset 'jobs_actual[${#jobs_actual[@]}-1]'
fi # shellcheck disable=SC2207
for workflow in .github/workflows/*.yml; do jobs_expected=($(venv yq -r '.jobs."ci-success".needs[]' "${workflow}"))
# The top-level permissions must be weak as they are referenced by all jobs. if [[ "${jobs_actual[*]}" != "${jobs_expected[*]+"${jobs_expected[*]}"}" ]]; then
permissions=$(venv yq -c '.permissions' "${workflow}") printf -v jobs '%s, ' "${jobs_actual[@]}"
case "${permissions}" in sed -i "s/needs: \[.*\] # tidy:needs/needs: [${jobs%, }] # tidy:needs/" "${workflow}"
'{"contents":"read"}' | '{"contents":"none"}') ;; check_diff "${workflow}"
null) error "${workflow}: top level permissions not found; it must be 'contents: read' or weaker permissions" ;; error "${workflow}: please update 'needs' section in 'ci-success' job"
*) error "${workflow}: only 'contents: read' and weaker permissions are allowed at top level; if you want to use stronger permissions, please set job-level permissions" ;;
esac
# Make sure the 'needs' section is not out of date.
if grep -q '# tidy:needs' "${workflow}" && ! grep -Eq '# *needs: \[' "${workflow}"; then
# shellcheck disable=SC2207
jobs_actual=($(venv yq '.jobs' "${workflow}" | jq -r 'keys_unsorted[]'))
unset 'jobs_actual[${#jobs_actual[@]}-1]'
# shellcheck disable=SC2207
jobs_expected=($(venv yq -r '.jobs."ci-success".needs[]' "${workflow}"))
if [[ "${jobs_actual[*]}" != "${jobs_expected[*]+"${jobs_expected[*]}"}" ]]; then
printf -v jobs '%s, ' "${jobs_actual[@]}"
sed -i "s/needs: \[.*\] # tidy:needs/needs: [${jobs%, }] # tidy:needs/" "${workflow}"
check_diff "${workflow}"
error "${workflow}: please update 'needs' section in 'ci-success' job"
fi
fi fi
done fi
else done
error "'python3' is not installed; skipped GitHub workflow check"
fi
else
error "'jq' is not installed; skipped GitHub workflow check"
fi fi
fi fi
fi fi
@@ -281,12 +289,10 @@ fi
if [[ -n "$(git ls-files '*.toml' | (grep -v .taplo.toml || true))" ]]; then if [[ -n "$(git ls-files '*.toml' | (grep -v .taplo.toml || true))" ]]; then
info "checking TOML style" info "checking TOML style"
check_config .taplo.toml check_config .taplo.toml
if type -P npm &>/dev/null; then if check_install npm; then
echo "+ npx -y @taplo/cli fmt \$(git ls-files '*.toml')" info "running \`npx -y @taplo/cli fmt \$(git ls-files '*.toml')\`"
RUST_LOG=warn npx -y @taplo/cli fmt $(git ls-files '*.toml') RUST_LOG=warn npx -y @taplo/cli fmt $(git ls-files '*.toml')
check_diff $(git ls-files '*.toml') check_diff $(git ls-files '*.toml')
else
error "'npm' is not installed; skipped TOML style check"
fi fi
elif [[ -e .taplo.toml ]]; then elif [[ -e .taplo.toml ]]; then
error ".taplo.toml is unused" error ".taplo.toml is unused"
@@ -296,11 +302,9 @@ fi
if [[ -n "$(git ls-files '*.md')" ]]; then if [[ -n "$(git ls-files '*.md')" ]]; then
info "checking Markdown style" info "checking Markdown style"
check_config .markdownlint-cli2.yaml check_config .markdownlint-cli2.yaml
if type -P npm &>/dev/null; then if check_install npm; then
echo "+ npx -y markdownlint-cli2 \$(git ls-files '*.md')" info "running \`npx -y markdownlint-cli2 \$(git ls-files '*.md')\`"
npx -y markdownlint-cli2 $(git ls-files '*.md') npx -y markdownlint-cli2 $(git ls-files '*.md')
else
error "'npm' is not installed; skipped Markdown style check"
fi fi
elif [[ -e .markdownlint-cli2.yaml ]]; then elif [[ -e .markdownlint-cli2.yaml ]]; then
error ".markdownlint-cli2.yaml is unused" error ".markdownlint-cli2.yaml is unused"
@@ -312,29 +316,25 @@ fi
# Shell scripts # Shell scripts
info "checking Shell scripts" info "checking Shell scripts"
if type -P shfmt &>/dev/null; then if check_install shfmt; then
check_config .editorconfig check_config .editorconfig
echo "+ shfmt -l -w \$(git ls-files '*.sh')" info "running \`shfmt -l -w \$(git ls-files '*.sh')\`"
shfmt -l -w $(git ls-files '*.sh') shfmt -l -w $(git ls-files '*.sh')
check_diff $(git ls-files '*.sh') check_diff $(git ls-files '*.sh')
else
error "'shfmt' is not installed; skipped Shell scripts style check"
fi fi
if type -P shellcheck &>/dev/null; then if check_install shellcheck; then
check_config .shellcheckrc check_config .shellcheckrc
echo "+ shellcheck \$(git ls-files '*.sh')" info "running \`shellcheck \$(git ls-files '*.sh')\`"
if ! shellcheck $(git ls-files '*.sh'); then if ! shellcheck $(git ls-files '*.sh'); then
should_fail=1 should_fail=1
fi fi
if [[ -n "$(git ls-files '*Dockerfile')" ]]; then if [[ -n "$(git ls-files '*Dockerfile')" ]]; then
# SC2154 doesn't seem to work on dockerfile. # SC2154 doesn't seem to work on dockerfile.
echo "+ shellcheck -e SC2148,SC2154,SC2250 \$(git ls-files '*Dockerfile')" info "running \`shellcheck -e SC2148,SC2154,SC2250 \$(git ls-files '*Dockerfile')\`"
if ! shellcheck -e SC2148,SC2154,SC2250 $(git ls-files '*Dockerfile'); then if ! shellcheck -e SC2148,SC2154,SC2250 $(git ls-files '*Dockerfile'); then
should_fail=1 should_fail=1
fi fi
fi fi
else
error "'shellcheck' is not installed; skipped Shell scripts style check"
fi fi
# License check # License check
@@ -383,13 +383,14 @@ fi
if [[ -f .cspell.json ]]; then if [[ -f .cspell.json ]]; then
info "spell checking" info "spell checking"
project_dictionary=.github/.cspell/project-dictionary.txt project_dictionary=.github/.cspell/project-dictionary.txt
if type -P npm &>/dev/null; then if check_install npm jq python3; then
has_rust='' has_rust=''
if [[ -n "$(git ls-files '*Cargo.toml')" ]]; then if [[ -n "$(git ls-files '*Cargo.toml')" ]]; then
venv_install_yq
has_rust='1' has_rust='1'
dependencies='' dependencies=''
for manifest_path in $(git ls-files '*Cargo.toml'); do for manifest_path in $(git ls-files '*Cargo.toml'); do
if [[ "${manifest_path}" != "Cargo.toml" ]] && ! grep -Eq '\[workspace\]' "${manifest_path}"; then if [[ "${manifest_path}" != "Cargo.toml" ]] && [[ "$(venv tomlq -c '.workspace' "${manifest_path}")" == "null" ]]; then
continue continue
fi fi
metadata=$(cargo metadata --format-version=1 --no-deps --manifest-path "${manifest_path}") metadata=$(cargo metadata --format-version=1 --no-deps --manifest-path "${manifest_path}")
@@ -422,7 +423,7 @@ EOF
error "you may want to mark .github/.cspell/rust-dependencies.txt linguist-generated" error "you may want to mark .github/.cspell/rust-dependencies.txt linguist-generated"
fi fi
echo "+ npx -y cspell --no-progress --no-summary \$(git ls-files)" info "running \`npx -y cspell --no-progress --no-summary \$(git ls-files)\`"
if ! npx -y cspell --no-progress --no-summary $(git ls-files); then if ! npx -y cspell --no-progress --no-summary $(git ls-files); then
error "spellcheck failed: please fix uses of above words or add to ${project_dictionary} if correct" error "spellcheck failed: please fix uses of above words or add to ${project_dictionary} if correct"
fi fi
@@ -454,8 +455,6 @@ EOF
echo -n "${unused}" echo -n "${unused}"
echo "=======================================" echo "======================================="
fi fi
else
error "'npm' is not installed; skipped spell check"
fi fi
fi fi