If we're running cargo, we need to add the runner name to the cache. Otherwise things that link against system packages, like openssl, can break when we use the same cache across different versions of the runner OS. For example, when going from Ubuntu 20.04 to 22.04, we move from OpenSSL 1.1.x to 3.x.
197 lines
8.5 KiB
YAML
197 lines
8.5 KiB
YAML
name: "Build Rust Projects with Cross"
|
|
author: "Dave Rolsky <autarch@urth.org>"
|
|
branding:
|
|
icon: home
|
|
color: gray-dark
|
|
description: |
|
|
Cross compile your Rust projects with cross (https://github.com/cross-rs/cross).
|
|
inputs:
|
|
target:
|
|
description: The target platform
|
|
required: true
|
|
command:
|
|
description: |
|
|
The commands to run. This must be one of "build", "test", "both" (build and test), or "bench".
|
|
default: build
|
|
toolchain:
|
|
description: |
|
|
The target toolchain to use (one of "stable", "beta", or "nightly").
|
|
default: stable
|
|
working-directory:
|
|
description: The working directory for each step
|
|
default: "."
|
|
GITHUB_TOKEN:
|
|
description: |
|
|
A GitHub token, available in the secrets.GITHUB_TOKEN working-directory variable.
|
|
default: ${{ github.token }}
|
|
args:
|
|
description: |
|
|
The arguments to be passed to cross or cargo when building, as a
|
|
space-separated string.
|
|
default: ""
|
|
strip:
|
|
description: Strip the compiled binary
|
|
default: false
|
|
cross-version:
|
|
description: |
|
|
The version of cross to use. If not specified, then the latest version
|
|
will be used.
|
|
cache-cross-binary:
|
|
description: |
|
|
Cache the cross binary if one is installed. This is primarily for use in
|
|
tests of this action.
|
|
default: true
|
|
use-rust-cache:
|
|
description: |
|
|
Use `Swatinem/rust-cache@v2`. Defaults to true.
|
|
default: true
|
|
rust-cache-parameters:
|
|
description: |
|
|
A JSON string containing parameters to pass to `Swatinem/rust-cache@v2`. You can use the
|
|
`toJSON()` function in your action to make passing this easier.
|
|
default: "{}"
|
|
runs:
|
|
using: composite
|
|
steps:
|
|
- name: Show inputs
|
|
shell: bash
|
|
run: |
|
|
echo '${{ toJSON(inputs) }}'
|
|
- name: Add this action's path to PATH
|
|
shell: bash
|
|
run: echo "${{ github.action_path }}" >> $GITHUB_PATH
|
|
- name: Validate inputs
|
|
shell: bash
|
|
run: |
|
|
"${{ github.action_path }}"/validate-inputs.py "${{ github.workspace }}"
|
|
env:
|
|
INPUTS_target: ${{ inputs.target }}
|
|
INPUTS_command: ${{ inputs.command }}
|
|
INPUTS_toolchain: ${{ inputs.toolchain }}
|
|
INPUTS_working_directory: ${{ inputs.working-directory }}
|
|
INPUTS_strip: ${{ inputs.strip }}
|
|
INPUTS_cache_cross_binary: ${{ inputs.cache-cross-binary }}
|
|
INPUTS_use_rust_cache: ${{ inputs.use-rust-cache }}
|
|
INPUTS_rust_cache_parameters: ${{ inputs.rust-cache-parameters }}
|
|
- name: Determine whether we need to cross-compile
|
|
id: determine-cross-compile
|
|
shell: bash
|
|
run: set-cross-compile.sh ${{ inputs.target }}
|
|
- name: Install toolchain
|
|
uses: dtolnay/rust-toolchain@master
|
|
with:
|
|
targets: ${{ inputs.target }}
|
|
toolchain: ${{ inputs.toolchain }}
|
|
- name: Determine cross version
|
|
id: determine-cross-version
|
|
shell: bash
|
|
run: determine-cross-version.sh "${{ inputs.cross-version }}"
|
|
env:
|
|
GITHUB_TOKEN: ${{ inputs.GITHUB_TOKEN }}
|
|
if: steps.determine-cross-compile.outputs.needs-cross == 'true'
|
|
# We need to access this in both this YAML config and shell scripts. It
|
|
# doesn't seem like using ${{ env.RUNNER_TEMP }} works in the YAML config.
|
|
- name: Set directory for installing cross
|
|
id: set-cross-dir
|
|
shell: bash
|
|
run: set-cross-dir.sh
|
|
if: steps.determine-cross-compile.outputs.needs-cross == 'true'
|
|
- name: Cache cross
|
|
id: cache-cross
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: ${{ steps.set-cross-dir.outputs.cross-dir }}/cross
|
|
key: ${{ runner.os }}-${{ steps.determine-cross-version.outputs.cross-version }}
|
|
if: steps.determine-cross-compile.outputs.needs-cross == 'true' && inputs.cache-cross-binary == 'true'
|
|
- name: Install cross if cross-compiling (*nix)
|
|
shell: bash
|
|
run: install-cross-nix.sh ${{ steps.set-cross-dir.outputs.cross-dir }} ${{ steps.determine-cross-version.outputs.cross-version }}
|
|
if: steps.determine-cross-compile.outputs.needs-cross == 'true' && steps.cache-cross.outputs.cache-hit != 'true'
|
|
env:
|
|
GITHUB_TOKEN: ${{ inputs.GITHUB_TOKEN }}
|
|
- name: Install musl-tools on Linux if target includes "musl"
|
|
shell: bash
|
|
run: |
|
|
if dpkg -l musl-tools | grep -q "^ii\s*musl-tools"; then
|
|
exit 0
|
|
fi
|
|
sudo apt-get update --yes && \
|
|
sudo apt-get install --yes musl-tools
|
|
if: steps.determine-cross-compile.outputs.needs-cross != 'true' && contains(inputs.target, 'musl')
|
|
- name: Set build command
|
|
id: set-build-command
|
|
shell: bash
|
|
run: set-build-command.sh ${{ steps.set-cross-dir.outputs.cross-dir }}
|
|
- name: Determine which cargo commands to run
|
|
id: determine-cargo-commands
|
|
shell: bash
|
|
run: determine-cargo-commands.sh ${{ inputs.command }}
|
|
- name: Parse `rust-cache-parameters` and set inputs for `Swatinem/rust-cache@v2`
|
|
id: parse-rust-cache-parameters
|
|
shell: bash
|
|
run: |
|
|
set -e
|
|
set -x
|
|
set -o pipefail
|
|
OS_VERSION=""
|
|
if [ -x /usr/bin/lsb_release ]; then
|
|
# This will be something like "Ubuntu 22.04.5 LTS"
|
|
OS_VERSION="$( lsb_release --short --description )"
|
|
fi
|
|
# This will get the inputs JSON from the `RUST_CACHE_PARAMETERS` env var. This avoids
|
|
# any string interpolation issues, since the inputs will contain quotes.
|
|
parse-rust-cache-parameters.py "${{ inputs.target }}" "${{ steps.set-build-command.outputs.build-command }}" "$OS_VERSION"
|
|
env:
|
|
RUST_CACHE_PARAMETERS: ${{ inputs.rust-cache-parameters }}
|
|
if: inputs.use-rust-cache == 'true'
|
|
- name: Cache cargo & target directories
|
|
uses: Swatinem/rust-cache@v2
|
|
with: ${{ steps.parse-rust-cache-parameters.outputs }}
|
|
if: inputs.use-rust-cache == 'true'
|
|
- name: Run tests (*nix)
|
|
working-directory: ${{ inputs.working-directory }}
|
|
shell: bash
|
|
run: |
|
|
${{ steps.set-build-command.outputs.build-command }} +${{inputs.toolchain}} test --target ${{ inputs.target }} ${{ inputs.args }}
|
|
if: steps.determine-cargo-commands.outputs.test == 'true' && runner.os != 'Windows'
|
|
# We want to run in Powershell on Windows to make sure we compile in a
|
|
# native Windows environment. Some things won't compile properly under
|
|
# msys, notably OpenSSL, which is compiled locally when using the
|
|
# `openssl` crate with the `vendored` feature.
|
|
- name: Run tests (Windows)
|
|
working-directory: ${{ inputs.working-directory }}
|
|
shell: powershell
|
|
run: |
|
|
& ${{ steps.set-build-command.outputs.build-command }} +${{inputs.toolchain}} test --target ${{ inputs.target }} ${{ inputs.args }}
|
|
if: steps.determine-cargo-commands.outputs.test == 'true' && runner.os == 'Windows'
|
|
- name: Run benchmarks (*nix)
|
|
working-directory: ${{ inputs.working-directory }}
|
|
shell: bash
|
|
run: |
|
|
${{ steps.set-build-command.outputs.build-command }} +${{inputs.toolchain}} bench --target ${{ inputs.target }} ${{ inputs.args }}
|
|
if: steps.determine-cargo-commands.outputs.bench == 'true' && runner.os != 'Windows'
|
|
- name: Run benchmarks (Windows)
|
|
working-directory: ${{ inputs.working-directory }}
|
|
shell: powershell
|
|
run: |
|
|
& ${{ steps.set-build-command.outputs.build-command }} +${{inputs.toolchain}} bench --target ${{ inputs.target }} ${{ inputs.args }}
|
|
if: steps.determine-cargo-commands.outputs.bench == 'true' && runner.os == 'Windows'
|
|
- name: Build binary (*nix)
|
|
working-directory: ${{ inputs.working-directory }}
|
|
shell: bash
|
|
run: |
|
|
${{ steps.set-build-command.outputs.build-command }} +${{inputs.toolchain}} build ${{ inputs.args }} --target ${{ inputs.target }}
|
|
if: steps.determine-cargo-commands.outputs.build == 'true' && runner.os != 'Windows'
|
|
- name: Build binary (Windows)
|
|
working-directory: ${{ inputs.working-directory }}
|
|
shell: powershell
|
|
run: |
|
|
& ${{ steps.set-build-command.outputs.build-command }} +${{inputs.toolchain}} build ${{ inputs.args }} --target ${{ inputs.target }}
|
|
if: steps.determine-cargo-commands.outputs.build == 'true' && runner.os == 'Windows'
|
|
- name: Strip binary
|
|
working-directory: ${{ inputs.working-directory }}
|
|
shell: bash
|
|
run: strip-binary.sh ${{ inputs.target }}
|
|
# strip doesn't work with cross-arch binaries on Linux or Windows.
|
|
if: inputs.command != 'test' && inputs.strip == 'true' && steps.determine-cross-compile.outputs.needs-cross == 'false' && inputs.target != 'aarch64-pc-windows-msvc'
|