R raindrops #826
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
# | |
# .github/workflows/rust.yml | |
# | |
name: Rust Workflow 4.0 | |
on: # yamllint disable-line rule:truthy | |
pull_request: | |
workflow_dispatch: | |
defaults: | |
run: | |
shell: bash | |
jobs: | |
stage1: | |
name: Change Check | |
runs-on: 'ubuntu-latest' | |
outputs: | |
docs_changed: ${{ steps.check_file_changed.outputs.docs_changed }} | |
matrix_exercise: ${{ steps.check_file_changed.outputs.matrix_exercise }} | |
exercise_count: ${{ steps.check_file_changed.outputs.exercise_count }} | |
steps: | |
- name: Check GitHub Vars | |
id: github-vars | |
run: set | grep -e ^CI -e ^GITHUB_ -e ^RUNNER_ | |
- name: Checkout Repo | |
id: checkout-repo | |
uses: actions/checkout@v3 | |
with: | |
fetch-depth: 0 | |
ref: ${{ github.ref }} | |
submodules: recursive | |
- name: Get Change List | |
id: check_file_changed | |
run: |- | |
{ | |
printf "Workflow: %s\n\n" "${GITHUB_WORKFLOW}" | |
printf "Runner: name[%s] arch[%s]\n" "${RUNNER_NAME}" "${RUNNER_ARCH}" | |
printf "Repo: %s\n" "${GITHUB_REPOSITORY}" | |
printf "User: %s\n" "${GITHUB_TRIGGERING_ACTOR}" | |
printf "\n" | |
} | tee -a "${GITHUB_STEP_SUMMARY}" | |
# get user info for default gh container | |
{ | |
printf "\`\`\`text\n" | |
printf "Container user info:\n" | |
who | |
printf "\n" | |
id | |
printf "\`\`\`\n" | |
} | tee -a "${GITHUB_STEP_SUMMARY}" | |
printf "\n" | |
# Diff HEAD with the previous commit then output to stdout. | |
GIT_DIFF="$(git diff --name-only HEAD^ HEAD | tee /tmp/changed_files.txt)" | |
{ | |
printf "=== Which files changed? ===\n" | |
printf "\`\`\`text\n" | |
printf "%s\n" "${GIT_DIFF}" | |
printf "\`\`\`\n" | |
} | tee -a "${GITHUB_STEP_SUMMARY}" | |
HAS_WF_DIFF=false | |
HAS_EX_DIFF=false | |
if printf "%s\n" "${GIT_DIFF}" | grep -E '^(.github/workflows/rust.yml|.github/citools/rust/)$'; then | |
HAS_WF_DIFF=true | |
fi | |
if printf "%s\n" "${GIT_DIFF}" | grep -E '^(rust/.*[.]rs|rust/.*/Cargo[.]toml)$'; then | |
HAS_EX_DIFF=true | |
fi | |
printf "\n" | |
printf "=== Did WF/CI change without exercise changes? ===\n" | |
CI_FORCE_FULL=false | |
if ${HAS_WF_DIFF} && ! ${HAS_EX_DIFF}; then | |
CI_FORCE_FULL=true | |
printf "%s\n" "${CI_FORCE_FULL}" | |
fi | |
printf "\n" | |
# Get changed exercise list. | |
if [[ ${GITHUB_EVENT_NAME} == pull_request ]] && ! ${CI_FORCE_FULL}; then | |
printf "Generating pull request changed exercise list.\n" | |
grep -E '^rust/[-a-z0-9]+./.*$' /tmp/changed_files.txt | cut -f1,2 -d/ | sort -Vu | tee /tmp/exercises.txt || true | |
else | |
printf "Generating complete exercise list.\n" | |
find ./rust/ -type d -print | grep -v -E '^[.]/rust/(|[.].*)$' | sed -r -e 's:[.]/(rust/[-a-z0-9]+)/?.*$:\1:g' | sort -Vu | tee /tmp/exercises.txt | |
HAS_DIFF=true | |
fi | |
printf "\n" | |
# Check if the files are present in the changed file list (added, modified, deleted) then output to stdout. | |
HAS_DIFF="${HAS_DIFF:-false}" | |
printf "=== Which Rust files changed? ===\n" | |
if printf "%s\n" "${GIT_DIFF}" | grep -E '^(rust/.*[.]rs|rust/.*/Cargo[.]toml|.github/workflows/rust.yml|.github/citools/rust/)$'; then | |
HAS_DIFF=true | |
printf "%s\n" "${HAS_DIFF}" | |
fi | |
printf "\n" | |
# Did Rust files change? | |
printf "=== Did Rust files change? ===\n" | |
printf "%s\n" "${HAS_DIFF}" | |
printf "\n" | |
# Generate exercise job matrix from changed files list. | |
printf "=== Generating matrix exercise list. ===\n" | |
declare -i last=0 | |
declare -i count=0 | |
last=$(wc -l /tmp/exercises.txt | cut -f1 -d\ ) | |
((last -= 1)) || true | |
entries="" | |
while read -r line; do | |
if [[ ! ${count} -lt ${last} ]]; then | |
comma="" | |
else | |
comma="," | |
fi | |
printf -v entry "\"%s\"%s\n" "${line}" "${comma}" | |
((count += 1)) | |
entries+="${entry}" | |
done < <(sort -V /tmp/exercises.txt) | |
jq --sort-keys . >/tmp/exercises.json <<EOF | |
[ ${entries} ] | |
EOF | |
exercise_count="$(jq '. | length' /tmp/exercises.json)" | |
printf "%s=%s\n" "exercise_count" "${exercise_count}" | tee -a "${GITHUB_OUTPUT}" | |
matrix_exercise="$(jq --compact-output --sort-keys . /tmp/exercises.json)" | |
printf "%s=%s\n" "matrix_exercise" "${matrix_exercise}" | tee -a "${GITHUB_OUTPUT}" | |
printf "\n" | |
cat "${GITHUB_OUTPUT}" | |
# Don't run stage 2 if PR mode doesn't have testable changes. | |
if [[ ${GITHUB_EVENT_NAME} == pull_request ]] && [[ -z ${entries} ]]; then | |
printf "In PR mode with no testable changes, disabling stage 2.\n" | |
HAS_DIFF=false | |
fi | |
# Set the output named "docs_changed" | |
printf "%s=%s\n" "docs_changed" "${HAS_DIFF}" >> "${GITHUB_OUTPUT}" | |
check-matrix: | |
runs-on: ubuntu-latest | |
needs: stage1 | |
steps: | |
- name: Install json2yaml | |
run: sudo npm install -g json2yaml | |
- name: Check matrix::exercises | |
run: |- | |
exercise_count='${{ needs.stage1.outputs.exercise_count }}' | |
matrix_exercise='${{ needs.stage1.outputs.matrix_exercise }}' | |
{ | |
printf "\`\`\`text\n" | |
printf "exercise_count=%s\n" "${exercise_count}" | |
printf "matrix_exercise=%s\n" "${matrix_exercise}" | |
printf "\`\`\`\n" | |
printf "json:\n" | |
printf "\`\`\`text\n" | |
printf "%s" "${matrix_exercise}" | jq . | |
printf "\`\`\`\n" | |
} | tee -a "${GITHUB_STEP_SUMMARY}" | |
{ | |
printf "yaml:\n" | |
printf "\`\`\`text\n" | |
printf "{ \"matrix\": { \"exercise\": %s } }" "${matrix_exercise}" | json2yaml | |
printf "\`\`\`\n" | |
} | tee -a "${GITHUB_STEP_SUMMARY}" | |
stage2: | |
name: Rust Checks | |
strategy: | |
matrix: | |
rust-version: ["stable"] | |
os: ["ubuntu-latest", "windows-latest", "macos-latest"] | |
exclude: | |
- os: "macos-latest" | |
rust-version: "stable" | |
- os: "windows-latest" | |
rust-version: "stable" | |
exercise: ${{fromJson(needs.stage1.outputs.matrix_exercise)}} | |
runs-on: "${{ matrix.os }}" | |
container: | |
image: vpayno/ci-generic-debian:latest | |
env: | |
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse | |
RUSTC_WRAPPER: sccache | |
ENABLE_TARPAULIN: false | |
needs: [stage1] | |
if: needs.stage1.outputs.docs_changed == 'true' | |
steps: | |
- name: Checkout Repo [${{ matrix.exercise }}] | |
id: checkout-repo | |
uses: actions/checkout@v3 | |
- name: Config Rust Tools [${{ matrix.exercise }}] | |
id: config-rust-tools | |
run: |- | |
./.github/citools/common/run_wrapper_script "./${{ matrix.exercise }}" ../../.github/citools/rust/rust-setup-config | |
- name: Install Rust Tools [${{ matrix.exercise }}] | |
id: install-rust-tools | |
run: |- | |
./.github/citools/common/run_wrapper_script "./${{ matrix.exercise }}" ../../.github/citools/rust/rust-setup-install | |
- name: Show Rust version [${{ matrix.exercise }}] | |
id: rust-version | |
run: |- | |
./.github/citools/common/run_wrapper_script "./${{ matrix.exercise }}" ../../.github/citools/rust/rust-setup-verify | |
- name: Analysing the code with cargo check [${{ matrix.exercise }}] | |
id: cargo-check | |
run: |- | |
./.github/citools/common/run_wrapper_script "./${{ matrix.exercise }}" ../../.github/citools/rust/rust-lint-check --release | |
- name: Analysing the code with cargo clippy [${{ matrix.exercise }}] | |
id: cargo-clippy | |
run: |- | |
./.github/citools/common/run_wrapper_script "./${{ matrix.exercise }}" ../../.github/citools/rust/rust-lint-clippy --release | |
- name: Testing with cargo tarpaulin [${{ matrix.exercise }}] | |
id: cargo-tarpaulin | |
if: ${{ env.ENABLE_TARPAULIN == 'true' }} | |
run: |- | |
# disabling, using my container I get: Failed to run tests: ASLR disable failed: EPERM: Operation not permitted | |
# https://github.com/xd009642/tarpaulin/issues/146 | |
./.github/citools/common/run_wrapper_script "./${{ matrix.exercise }}" ../../.github/citools/rust/rust-test-with-tarpaulin | |
- name: Testing with cargo test coverage [${{ matrix.exercise }}] | |
id: cargo-test-coverage | |
run: |- | |
./.github/citools/common/run_wrapper_script "./${{ matrix.exercise }}" ../../.github/citools/rust/rust-test-with-llvm-coverage | |
- name: Testing with cargo audit [${{ matrix.exercise }}] | |
id: cargo-audit | |
run: |- | |
./.github/citools/common/run_wrapper_script "./${{ matrix.exercise }}" ../../.github/citools/rust/rust-lint-audit |