diff --git a/rust-toolchain/LICENSE b/rust-toolchain/LICENSE new file mode 100644 index 0000000..31aa793 --- /dev/null +++ b/rust-toolchain/LICENSE @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/rust-toolchain/README.md b/rust-toolchain/README.md new file mode 100644 index 0000000..2ea5437 --- /dev/null +++ b/rust-toolchain/README.md @@ -0,0 +1,107 @@ +# Install Rust Toolchain + +This GitHub Action installs a Rust toolchain using rustup. It is designed for +one-line concise usage and good defaults. + +
+ +## Example workflow + +```yaml +name: test suite +on: [push, pull_request] + +jobs: + test: + name: cargo test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - run: cargo test --all-features +``` + +The selection of Rust toolchain is made based on the particular @rev of this +Action being requested. For example "dtolnay/rust-toolchain@nightly" pulls in +the nightly Rust toolchain, while "dtolnay/rust-toolchain@1.42.0" pulls in +1.42.0. + +
+ +## Inputs + +All inputs are optional. + + + + + + + + + + + + + + + + + + +
NameDescription
toolchain + Rustup toolchain specifier e.g. stable, nightly, 1.42.0, nightly-2022-01-01. + Important: the default is to match the @rev as described above. + When passing an explicit toolchain as an input instead of @rev, you'll want to use "dtolnay/rust-toolchain@master" as the revision of the action. +
targetsComma-separated string of additional targets to install e.g. wasm32-unknown-unknown
componentsComma-separated string of additional components to install e.g. clippy, rustfmt
+ +
+ +## Outputs + + + + + + + + + + + + + + +
NameDescription
cachekeyA short hash of the installed rustc version, appropriate for use as a cache key. "20220627a831"
nameRustup's name for the selected version of the toolchain, like "1.62.0". Suitable for use with cargo +${{steps.toolchain.outputs.name}}.
+ +
+ +## Toolchain expressions + +The following forms are available for projects that use a sliding window of +compiler support. + +```yaml + # Installs the most recent stable toolchain as of the specified time + # offset, which may be written in years, months, weeks, or days. + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable 18 months ago +``` + +```yaml + # Installs the stable toolchain which preceded the most recent one by + # the specified number of minor versions. + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable minus 8 releases +``` + +
+ +## License + +The scripts and documentation in this project are released under the [MIT +License]. + +[MIT License]: LICENSE diff --git a/rust-toolchain/action.yml b/rust-toolchain/action.yml new file mode 100644 index 0000000..2b57d9c --- /dev/null +++ b/rust-toolchain/action.yml @@ -0,0 +1,149 @@ +name: rustup toolchain install +author: David Tolnay +description: Install the Rust toolchain +branding: + icon: activity + color: purple + +inputs: + toolchain: + description: Rust toolchain specification -- see https://rust-lang.github.io/rustup/concepts/toolchains.html#toolchain-specification + required: true + targets: + description: Comma-separated list of target triples to install for this toolchain + required: false + target: + description: Alias for `targets` + required: false + components: + description: Comma-separated list of components to be additionally installed + required: false + rustup-version: + description: The version of rustup used during installation + required: false + default: 1.28.2 + +outputs: + cachekey: + description: A short hash of the rustc version, appropriate for use as a cache key. "20220627a831" + value: ${{steps.rustc-version.outputs.cachekey}} + name: + description: Rustup's name for the selected version of the toolchain. "1.62.0" # suitable for use with `cargo +${{steps.toolchain.outputs.name}}` + value: ${{steps.parse.outputs.toolchain}} + +runs: + using: composite + steps: + - id: parse + run: | + : parse toolchain version + if [[ $toolchain =~ ^stable' '[0-9]+' '(year|month|week|day)s?' 'ago$ ]]; then + if [[ ${{runner.os}} == macOS ]]; then + echo "toolchain=1.$((($(date -v-$(sed 's/stable \([0-9]*\) \(.\).*/\1\2/' <<< $toolchain) +%s)/60/60/24-16569)/7/6))" >> $GITHUB_OUTPUT + else + echo "toolchain=1.$((($(date --date "${toolchain#stable }" +%s)/60/60/24-16569)/7/6))" >> $GITHUB_OUTPUT + fi + elif [[ $toolchain =~ ^stable' 'minus' '[0-9]+' 'releases?$ ]]; then + echo "toolchain=1.$((($(date +%s)/60/60/24-16569)/7/6-${toolchain//[^0-9]/}))" >> $GITHUB_OUTPUT + elif [[ $toolchain =~ ^1\.[0-9]+$ ]]; then + echo "toolchain=1.$((i=${toolchain#1.}, c=($(date +%s)/60/60/24-16569)/7/6, i+9*i*(10*i<=c)+90*i*(100*i<=c)))" >> $GITHUB_OUTPUT + else + echo "toolchain=$toolchain" >> $GITHUB_OUTPUT + fi + env: + toolchain: ${{inputs.toolchain}} + shell: bash + + - id: flags + run: | + : construct rustup command line + echo "targets=$(for t in ${targets//,/ }; do echo -n ' --target' $t; done)" >> $GITHUB_OUTPUT + echo "components=$(for c in ${components//,/ }; do echo -n ' --component' $c; done)" >> $GITHUB_OUTPUT + echo "downgrade=${{steps.parse.outputs.toolchain == 'nightly' && inputs.components && ' --allow-downgrade' || ''}}" >> $GITHUB_OUTPUT + env: + targets: ${{inputs.targets || inputs.target || ''}} + components: ${{inputs.components}} + shell: bash + + - run: | + : set $CARGO_HOME + echo CARGO_HOME=${CARGO_HOME:-"${{runner.os == 'Windows' && '$USERPROFILE\.cargo' || '$HOME/.cargo'}}"} >> $GITHUB_ENV + shell: bash + + - run: | + : install rustup if needed + if ! command -v rustup &>/dev/null; then + curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused --location --silent --show-error --fail https://sh.rustup.rs | RUSTUP_VERSION="$RUSTUP_VERSION" sh -s -- --default-toolchain none -y + echo "$CARGO_HOME/bin" >> $GITHUB_PATH + fi + if: runner.os != 'Windows' + env: + RUSTUP_VERSION: ${{ inputs.rustup-version }} + shell: bash + + - run: | + : install rustup if needed on windows + if ! command -v rustup &>/dev/null; then + curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused --location --silent --show-error --fail https://win.rustup.rs/${{runner.arch == 'ARM64' && 'aarch64' || 'x86_64'}} --output '${{runner.temp}}\rustup-init.exe' + RUSTUP_VERSION="$RUSTUP_VERSION" '${{runner.temp}}\rustup-init.exe' --default-toolchain none --no-modify-path -y + echo "$CARGO_HOME\bin" >> $GITHUB_PATH + fi + if: runner.os == 'Windows' + env: + RUSTUP_VERSION: ${{ inputs.rustup-version }} + shell: bash + + - name: rustup toolchain install ${{steps.parse.outputs.toolchain}} + run: rustup toolchain install ${{steps.parse.outputs.toolchain}}${{steps.flags.outputs.targets}}${{steps.flags.outputs.components}} --profile minimal${{steps.flags.outputs.downgrade}} --no-self-update + shell: bash + + - run: rustup default ${{steps.parse.outputs.toolchain}} + shell: bash + continue-on-error: true # https://github.com/dtolnay/rust-toolchain/issues/127 + + - id: rustc-version + run: | + : create cachekey + DATE=$(rustc +${{steps.parse.outputs.toolchain}} --version --verbose | sed -ne 's/^commit-date: \(20[0-9][0-9]\)-\([01][0-9]\)-\([0-3][0-9]\)$/\1\2\3/p') + HASH=$(rustc +${{steps.parse.outputs.toolchain}} --version --verbose | sed -ne 's/^commit-hash: //p') + echo "cachekey=$(echo $DATE$HASH | head -c12)" >> $GITHUB_OUTPUT + shell: bash + + - run: | + : disable incremental compilation + if [ -z "${CARGO_INCREMENTAL+set}" ]; then + echo CARGO_INCREMENTAL=0 >> $GITHUB_ENV + fi + shell: bash + + - run: | + : enable colors in Cargo output + if [ -z "${CARGO_TERM_COLOR+set}" ]; then + echo CARGO_TERM_COLOR=always >> $GITHUB_ENV + fi + shell: bash + + - run: | + : enable Cargo sparse registry + # implemented in 1.66, stabilized in 1.68, made default in 1.70 + if [ -z "${CARGO_REGISTRIES_CRATES_IO_PROTOCOL+set}" -o -f "${{runner.temp}}"/.implicit_cargo_registries_crates_io_protocol ]; then + if rustc +${{steps.parse.outputs.toolchain}} --version --verbose | grep -q '^release: 1\.6[89]\.'; then + touch "${{runner.temp}}"/.implicit_cargo_registries_crates_io_protocol || true + echo CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse >> $GITHUB_ENV + elif rustc +${{steps.parse.outputs.toolchain}} --version --verbose | grep -q '^release: 1\.6[67]\.'; then + touch "${{runner.temp}}"/.implicit_cargo_registries_crates_io_protocol || true + echo CARGO_REGISTRIES_CRATES_IO_PROTOCOL=git >> $GITHUB_ENV + fi + fi + shell: bash + + - run: | + : work around spurious network errors in curl 8.0 + # https://rust-lang.zulipchat.com/#narrow/stream/246057-t-cargo/topic/timeout.20investigation + if rustc +${{steps.parse.outputs.toolchain}} --version --verbose | grep -q '^release: 1\.7[01]\.'; then + echo CARGO_HTTP_MULTIPLEXING=false >> $GITHUB_ENV + fi + shell: bash + + - run: rustc +${{steps.parse.outputs.toolchain}} --version --verbose + shell: bash diff --git a/rust-toolchain/scripts/update-revs.sh b/rust-toolchain/scripts/update-revs.sh new file mode 100755 index 0000000..697d135 --- /dev/null +++ b/rust-toolchain/scripts/update-revs.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." + +if ! git diff-index --quiet HEAD; then + echo "Not running update-revs.sh because git working directory is dirty" >&2 + exit 1 +fi + +patch_releases=( + 1.12.1 1.15.1 1.22.1 1.24.1 1.26.1 1.26.2 1.27.1 1.27.2 1.29.1 1.29.2 1.30.1 + 1.31.1 1.34.1 1.34.2 1.41.1 1.43.1 1.44.1 1.45.1 1.45.2 1.52.1 1.56.1 1.58.1 + 1.62.1 1.66.1 1.67.1 1.68.1 1.68.2 1.71.1 1.72.1 1.74.1 1.77.1 1.77.2 1.80.1 + 1.84.1 1.85.1 +) + +releases() { + printf "%s\n" 1.{0..100}.0 ${patch_releases[@]} | sort -V +} + +base=$(git rev-parse HEAD) +push=() + +declare -A minor +for rev in `releases`; do + minor[${rev%.*}]=$rev +done + +for rev in `releases` stable beta nightly; do + echo "Updating $rev branch" + git checkout --quiet "$base" + git branch --quiet --delete --force $rev &>/dev/null || true + if [[ $rev == 1* ]]; then + sed -i "/^ toolchain:/,+2d; s/\${{inputs\.toolchain}}/$rev/" action.yml + else + sed -i "s/required: true/required: false\n default: $rev/" action.yml + fi + git add action.yml + git commit --quiet --message "toolchain: $rev" + git checkout --quiet -b $rev + push+=("$rev:refs/heads/$rev") + if [ "${minor[${rev%.*}]}" == $rev ]; then + push+=("$rev:refs/heads/${rev%.*}") + fi +done + +for tool in clippy miri; do + echo "Updating $tool branch" + git checkout --quiet --detach nightly + git branch --quiet --delete --force $tool &>/dev/null || true + default=$tool + if [ $tool == miri ]; then default+=,\ rust-src; fi + sed -i "/required: false/{N;s/\n$/\n default: $default\n/}" action.yml + git add action.yml + git commit --quiet --message "components: $tool" + git checkout --quiet -b $tool + push+=("$tool:refs/heads/$tool") +done + +git checkout --quiet "$base" + +echo "git push origin --force-with-lease ${push[@]}"