GH action: Run rustfmt+cargo autofix when the PR is merged #17
Workflow file for this run
This file contains hidden or 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
| name: CICD | |
| # spell-checker:ignore (acronyms) CICD MSVC musl | |
| # spell-checker:ignore (env/flags) Awarnings Ccodegen Coverflow Cpanic RUSTDOCFLAGS RUSTFLAGS Zpanic | |
| # spell-checker:ignore (jargon) SHAs deps softprops toolchain | |
| # spell-checker:ignore (names) CodeCOV MacOS MinGW Peltoche rivy | |
| # spell-checker:ignore (shell/tools) choco clippy dmake dpkg esac fakeroot gmake grcov halium lcov libssl mkdir popd printf pushd rustc rustfmt rustup shopt xargs | |
| # spell-checker:ignore (misc) aarch alnum armhf bindir busytest coreutils gnueabihf issuecomment maint nullglob onexitbegin onexitend runtest tempfile testsuite uutils | |
| env: | |
| PROJECT_NAME: coreutils | |
| PROJECT_DESC: "Core universal (cross-platform) utilities" | |
| PROJECT_AUTH: "uutils" | |
| RUST_MIN_SRV: "1.43.1" ## v1.43.0 | |
| RUST_COV_SRV: "2020-08-01" ## (~v1.47.0) supported rust version for code coverage; (date required/used by 'coverage') ## !maint: refactor when code coverage support is included in the stable channel | |
| on: [push, pull_request] | |
| jobs: | |
| code_spellcheck: | |
| name: Style/spelling | |
| runs-on: ${{ matrix.job.os }} | |
| strategy: | |
| matrix: | |
| job: | |
| - { os: ubuntu-latest } | |
| steps: | |
| - uses: actions/checkout@v2 | |
| - name: Install/setup prerequisites | |
| shell: bash | |
| run: | | |
| sudo apt-get -y update ; sudo apt-get -y install npm ; sudo npm install cspell -g; | |
| - name: Run `cspell` | |
| shell: bash | |
| run: | | |
| cspell --config .vscode/cSpell.json --no-summary --no-progress "**/*" | sed "s/\(.*\):\(.*\):\(.*\) - \(.*\)/::warning file=\1,line=\2,col=\3::cspell: \4/" || true | |
| code_warnings: | |
| name: Style/warnings | |
| runs-on: ${{ matrix.job.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| job: | |
| - { os: ubuntu-latest , features: feat_os_unix } | |
| - { os: macos-latest , features: feat_os_macos } | |
| - { os: windows-latest , features: feat_os_windows } | |
| steps: | |
| - uses: actions/checkout@v2 | |
| - name: Initialize workflow variables | |
| id: vars | |
| shell: bash | |
| run: | | |
| ## VARs setup | |
| outputs() { for var in "$@" ; do echo steps.vars.outputs.${var}="${!var}"; echo ::set-output name=${var}::${!var}; done; } | |
| # target-specific options | |
| # * CARGO_FEATURES_OPTION | |
| CARGO_FEATURES_OPTION='' ; | |
| if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi | |
| outputs CARGO_FEATURES_OPTION | |
| - name: Install `rust` toolchain | |
| uses: actions-rs/toolchain@v1 | |
| with: | |
| toolchain: nightly | |
| default: true | |
| profile: minimal # minimal component installation (ie, no documentation) | |
| components: clippy | |
| - name: "`clippy` testing" | |
| if: success() || failure() # run regardless of prior step success/failure | |
| shell: bash | |
| run: | | |
| # `clippy` testing | |
| # * convert any warnings to GHA UI annotations; ref: <https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message> | |
| S=$(cargo +nightly clippy --all-targets ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} -- -D warnings 2>&1) && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s" "$S" | sed -E -n -e '/^error:/{' -e "N; s/^error:[[:space:]]+(.*)\\n[[:space:]]+-->[[:space:]]+(.*):([0-9]+):([0-9]+).*$/::warning file=\2,line=\3,col=\4::WARNING: \`cargo clippy\`: \1/p;" -e '}' ; } | |
| busybox_test: | |
| name: Busybox test suite | |
| runs-on: ${{ matrix.job.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| job: | |
| - { os: ubuntu-latest } | |
| steps: | |
| - uses: actions/checkout@v2 | |
| - name: Install `rust` toolchain | |
| uses: actions-rs/toolchain@v1 | |
| with: | |
| toolchain: stable | |
| default: true | |
| profile: minimal # minimal component installation (ie, no documentation) | |
| - name: "prepare busytest" | |
| shell: bash | |
| run: | | |
| make prepare-busytest | |
| - name: "run busybox testsuite" | |
| shell: bash | |
| run: | | |
| bindir=$(pwd)/target/debug | |
| cd tmp/busybox-*/testsuite | |
| ## S=$(bindir=$bindir ./runtest) && printf "%s\n" "$S" || { printf "%s\n" "$S" | grep "FAIL:" | sed -e "s/FAIL: /::warning ::Test failure:/g" ; } | |
| output=$(bindir=$bindir ./runtest 2>&1 || true) | |
| printf "%s\n" "${output}" | |
| n_fails=$(echo "$output" | grep "^FAIL:\s" | wc --lines) | |
| if [ $n_fails -gt 0 ] ; then echo "::warning ::${n_fails}+ test failures" ; fi | |
| makefile_build: | |
| name: Test the build target of the Makefile | |
| runs-on: ${{ matrix.job.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| job: | |
| - { os: ubuntu-latest } | |
| steps: | |
| - uses: actions/checkout@v2 | |
| - name: Install `rust` toolchain | |
| uses: actions-rs/toolchain@v1 | |
| with: | |
| toolchain: stable | |
| default: true | |
| profile: minimal # minimal component installation (ie, no documentation) | |
| - name: "Run make build" | |
| shell: bash | |
| run: | | |
| sudo apt-get -y update ; sudo apt-get -y install python3-sphinx; | |
| make build | |
| build: | |
| name: Build | |
| runs-on: ${{ matrix.job.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| job: | |
| # { os, target, cargo-options, features, use-cross, toolchain } | |
| - { os: ubuntu-latest , target: arm-unknown-linux-gnueabihf , features: feat_os_unix_gnueabihf , use-cross: use-cross } | |
| - { os: ubuntu-latest , target: aarch64-unknown-linux-gnu , features: feat_os_unix_gnueabihf , use-cross: use-cross } | |
| - { os: ubuntu-16.04 , target: x86_64-unknown-linux-gnu , features: feat_os_unix , use-cross: use-cross } | |
| # - { os: ubuntu-18.04 , target: i586-unknown-linux-gnu , features: feat_os_unix , use-cross: use-cross } ## note: older windows platform; not required, dev-FYI only | |
| # - { os: ubuntu-18.04 , target: i586-unknown-linux-gnu , features: feat_os_unix , use-cross: use-cross } ## note: older windows platform; not required, dev-FYI only | |
| - { os: ubuntu-18.04 , target: i686-unknown-linux-gnu , features: feat_os_unix , use-cross: use-cross } | |
| - { os: ubuntu-18.04 , target: i686-unknown-linux-musl , features: feat_os_unix_musl , use-cross: use-cross } | |
| - { os: ubuntu-18.04 , target: x86_64-unknown-linux-gnu , features: feat_os_unix , use-cross: use-cross } | |
| - { os: ubuntu-18.04 , target: x86_64-unknown-linux-musl , features: feat_os_unix_musl , use-cross: use-cross } | |
| - { os: macos-latest , target: x86_64-apple-darwin , features: feat_os_macos } | |
| - { os: windows-latest , target: i686-pc-windows-gnu , features: feat_os_windows } | |
| - { os: windows-latest , target: i686-pc-windows-msvc , features: feat_os_windows } | |
| - { os: windows-latest , target: x86_64-pc-windows-gnu , features: feat_os_windows } ## note: requires rust >= 1.43.0 to link correctly | |
| - { os: windows-latest , target: x86_64-pc-windows-msvc , features: feat_os_windows } | |
| steps: | |
| - uses: actions/checkout@v2 | |
| - name: Install/setup prerequisites | |
| shell: bash | |
| run: | | |
| ## install/setup prerequisites | |
| case '${{ matrix.job.target }}' in | |
| arm-unknown-linux-gnueabihf) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;; | |
| aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;; | |
| esac | |
| case '${{ matrix.job.os }}' in | |
| macos-latest) brew install coreutils ;; # needed for testing | |
| esac | |
| - name: Initialize workflow variables | |
| id: vars | |
| shell: bash | |
| run: | | |
| ## VARs setup | |
| outputs() { for var in "$@" ; do echo steps.vars.outputs.${var}="${!var}"; echo ::set-output name=${var}::${!var}; done; } | |
| # toolchain | |
| TOOLCHAIN="stable" ## default to "stable" toolchain | |
| # * specify alternate/non-default TOOLCHAIN for *-pc-windows-gnu targets; gnu targets on Windows are broken for the standard *-pc-windows-msvc toolchain (refs: GH:rust-lang/rust#47048, GH:rust-lang/rust#53454, GH:rust-lang/cargo#6754) | |
| case ${{ matrix.job.target }} in *-pc-windows-gnu) TOOLCHAIN="stable-${{ matrix.job.target }}" ;; esac; | |
| # * use requested TOOLCHAIN if specified | |
| if [ -n "${{ matrix.job.toolchain }}" ]; then TOOLCHAIN="${{ matrix.job.toolchain }}" ; fi | |
| outputs TOOLCHAIN | |
| # staging directory | |
| STAGING='_staging' | |
| outputs STAGING | |
| # determine EXE suffix | |
| EXE_suffix="" ; case '${{ matrix.job.target }}' in *-pc-windows-*) EXE_suffix=".exe" ;; esac; | |
| outputs EXE_suffix | |
| # parse commit reference info | |
| echo GITHUB_REF=${GITHUB_REF} | |
| echo GITHUB_SHA=${GITHUB_SHA} | |
| REF_NAME=${GITHUB_REF#refs/*/} | |
| unset REF_BRANCH ; case "${GITHUB_REF}" in refs/heads/*) REF_BRANCH=${GITHUB_REF#refs/heads/} ;; esac; | |
| unset REF_TAG ; case "${GITHUB_REF}" in refs/tags/*) REF_TAG=${GITHUB_REF#refs/tags/} ;; esac; | |
| REF_SHAS=${GITHUB_SHA:0:8} | |
| outputs REF_NAME REF_BRANCH REF_TAG REF_SHAS | |
| # parse target | |
| unset TARGET_ARCH | |
| case '${{ matrix.job.target }}' in | |
| aarch64-*) TARGET_ARCH=arm64 ;; | |
| arm-*-*hf) TARGET_ARCH=armhf ;; | |
| i586-*) TARGET_ARCH=i586 ;; | |
| i686-*) TARGET_ARCH=i686 ;; | |
| x86_64-*) TARGET_ARCH=x86_64 ;; | |
| esac; | |
| unset TARGET_OS ; case '${{ matrix.job.target }}' in *-linux-*) TARGET_OS=linux ;; *-apple-*) TARGET_OS=macos ;; *-windows-*) TARGET_OS=windows ;; esac; | |
| outputs TARGET_ARCH TARGET_OS | |
| # package name | |
| PKG_suffix=".tar.gz" ; case '${{ matrix.job.target }}' in *-pc-windows-*) PKG_suffix=".zip" ;; esac; | |
| PKG_BASENAME=${PROJECT_NAME}-${REF_TAG:-$REF_SHAS}-${{ matrix.job.target }} | |
| PKG_NAME=${PKG_BASENAME}${PKG_suffix} | |
| outputs PKG_suffix PKG_BASENAME PKG_NAME | |
| # deployable tag? (ie, leading "vM" or "M"; M == version number) | |
| unset DEPLOY ; if [[ $REF_TAG =~ ^[vV]?[0-9].* ]]; then DEPLOY='true' ; fi | |
| outputs DEPLOY | |
| # DPKG architecture? | |
| unset DPKG_ARCH | |
| case ${{ matrix.job.target }} in | |
| x86_64-*-linux-*) DPKG_ARCH=amd64 ;; | |
| *-linux-*) DPKG_ARCH=${TARGET_ARCH} ;; | |
| esac | |
| outputs DPKG_ARCH | |
| # DPKG version? | |
| unset DPKG_VERSION ; if [[ $REF_TAG =~ ^[vV]?[0-9].* ]]; then DPKG_VERSION=${REF_TAG/#[vV]/} ; fi | |
| outputs DPKG_VERSION | |
| # DPKG base name/conflicts? | |
| DPKG_BASENAME=${PROJECT_NAME} | |
| DPKG_CONFLICTS=${PROJECT_NAME}-musl | |
| case ${{ matrix.job.target }} in *-musl) DPKG_BASENAME=${PROJECT_NAME}-musl ; DPKG_CONFLICTS=${PROJECT_NAME} ;; esac; | |
| outputs DPKG_BASENAME DPKG_CONFLICTS | |
| # DPKG name | |
| unset DPKG_NAME; | |
| if [[ -n $DPKG_ARCH && -n $DPKG_VERSION ]]; then DPKG_NAME="${DPKG_BASENAME}_${DPKG_VERSION}_${DPKG_ARCH}.deb" ; fi | |
| outputs DPKG_NAME | |
| # target-specific options | |
| # * CARGO_FEATURES_OPTION | |
| CARGO_FEATURES_OPTION='' ; | |
| if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi | |
| outputs CARGO_FEATURES_OPTION | |
| # * CARGO_USE_CROSS (truthy) | |
| CARGO_USE_CROSS='true' ; case '${{ matrix.job.use-cross }}' in ''|0|f|false|n|no) unset CARGO_USE_CROSS ;; esac; | |
| outputs CARGO_USE_CROSS | |
| # ** pass needed environment into `cross` container (iff `cross` not already configured via "Cross.toml") | |
| if [ -n "${CARGO_USE_CROSS}" ] && [ ! -e "Cross.toml" ] ; then | |
| printf "[build.env]\npassthrough = [\"CI\"]\n" > Cross.toml | |
| fi | |
| # * test only library and/or binaries for arm-type targets | |
| unset CARGO_TEST_OPTIONS ; case '${{ matrix.job.target }}' in aarch64-* | arm-*) CARGO_TEST_OPTIONS="--bins" ;; esac; | |
| outputs CARGO_TEST_OPTIONS | |
| # * executable for `strip`? | |
| STRIP="strip" | |
| case ${{ matrix.job.target }} in | |
| aarch64-*-linux-gnu) STRIP="aarch64-linux-gnu-strip" ;; | |
| arm-*-linux-gnueabihf) STRIP="arm-linux-gnueabihf-strip" ;; | |
| *-pc-windows-msvc) STRIP="" ;; | |
| esac; | |
| outputs STRIP | |
| - name: Create all needed build/work directories | |
| shell: bash | |
| run: | | |
| ## create build/work space | |
| mkdir -p '${{ steps.vars.outputs.STAGING }}' | |
| mkdir -p '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}' | |
| mkdir -p '${{ steps.vars.outputs.STAGING }}/dpkg' | |
| - name: rust toolchain ~ install | |
| uses: actions-rs/toolchain@v1 | |
| env: | |
| # Override auto-detection of RAM for Rustc install. | |
| # https://github.com/rust-lang/rustup/issues/2229#issuecomment-585855925 | |
| RUSTUP_UNPACK_RAM: "21474836480" | |
| with: | |
| toolchain: ${{ steps.vars.outputs.TOOLCHAIN }} | |
| target: ${{ matrix.job.target }} | |
| default: true | |
| profile: minimal # minimal component installation (ie, no documentation) | |
| - name: Initialize toolchain-dependent workflow variables | |
| id: dep_vars | |
| shell: bash | |
| run: | | |
| ## Dependent VARs setup | |
| outputs() { for var in "$@" ; do echo steps.vars.outputs.${var}="${!var}"; echo ::set-output name=${var}::${!var}; done; } | |
| # * determine sub-crate utility list | |
| UTILITY_LIST="$(./util/show-utils.sh ${CARGO_FEATURES_OPTION})" | |
| echo UTILITY_LIST=${UTILITY_LIST} | |
| CARGO_UTILITY_LIST_OPTIONS="$(for u in ${UTILITY_LIST}; do echo "-puu_${u}"; done;)" | |
| outputs CARGO_UTILITY_LIST_OPTIONS | |
| - name: Install `cargo-tree` # for dependency information | |
| uses: actions-rs/install@v0.1 | |
| with: | |
| crate: cargo-tree | |
| version: latest | |
| use-tool-cache: true | |
| env: | |
| RUSTUP_TOOLCHAIN: stable | |
| - name: Info | |
| shell: bash | |
| run: | | |
| # Info | |
| ## commit info | |
| echo "## commit" | |
| echo GITHUB_REF=${GITHUB_REF} | |
| echo GITHUB_SHA=${GITHUB_SHA} | |
| ## environment | |
| echo "## environment" | |
| echo "CI='${CI}'" | |
| ## tooling info display | |
| echo "## tooling" | |
| which gcc >/dev/null 2>&1 && (gcc --version | head -1) || true | |
| rustup -V | |
| rustup show active-toolchain | |
| cargo -V | |
| rustc -V | |
| cargo-tree tree -V | |
| ## dependencies | |
| echo "## dependency list" | |
| cargo fetch --locked --quiet | |
| cargo-tree tree --target=${{ matrix.job.target }} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} --all --no-dev-dependencies --no-indent | grep -vE "$PWD" | sort --unique | |
| - name: Build | |
| uses: actions-rs/cargo@v1 | |
| with: | |
| use-cross: ${{ steps.vars.outputs.CARGO_USE_CROSS }} | |
| command: build | |
| args: --release --target=${{ matrix.job.target }} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} | |
| - name: Test | |
| uses: actions-rs/cargo@v1 | |
| with: | |
| use-cross: ${{ steps.vars.outputs.CARGO_USE_CROSS }} | |
| command: test | |
| args: --target=${{ matrix.job.target }} ${{ steps.vars.outputs.CARGO_TEST_OPTIONS}} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} | |
| - name: Test individual utilities | |
| uses: actions-rs/cargo@v1 | |
| with: | |
| use-cross: ${{ steps.vars.outputs.CARGO_USE_CROSS }} | |
| command: test | |
| args: --target=${{ matrix.job.target }} ${{ steps.vars.outputs.CARGO_TEST_OPTIONS}} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} ${{ steps.dep_vars.outputs.CARGO_UTILITY_LIST_OPTIONS }} | |
| - name: Archive executable artifacts | |
| uses: actions/upload-artifact@v2 | |
| with: | |
| name: ${{ env.PROJECT_NAME }}-${{ matrix.job.target }} | |
| path: target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }} | |
| - name: Package | |
| shell: bash | |
| run: | | |
| ## package artifact(s) | |
| # binary | |
| cp 'target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}' '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/' | |
| # `strip` binary (if needed) | |
| if [ -n "${{ steps.vars.outputs.STRIP }}" ]; then "${{ steps.vars.outputs.STRIP }}" '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}' ; fi | |
| # README and LICENSE | |
| # * spell-checker:ignore EADME ICENSE | |
| (shopt -s nullglob; for f in [R]"EADME"{,.*}; do cp $f '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/' ; done) | |
| (shopt -s nullglob; for f in [L]"ICENSE"{-*,}{,.*}; do cp $f '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/' ; done) | |
| # core compressed package | |
| pushd '${{ steps.vars.outputs.STAGING }}/' >/dev/null | |
| case '${{ matrix.job.target }}' in | |
| *-pc-windows-*) 7z -y a '${{ steps.vars.outputs.PKG_NAME }}' '${{ steps.vars.outputs.PKG_BASENAME }}'/* | tail -2 ;; | |
| *) tar czf '${{ steps.vars.outputs.PKG_NAME }}' '${{ steps.vars.outputs.PKG_BASENAME }}'/* ;; | |
| esac | |
| popd >/dev/null | |
| # dpkg | |
| if [ -n "${{ steps.vars.outputs.DPKG_NAME }}" ]; then | |
| DPKG_DIR="${{ steps.vars.outputs.STAGING }}/dpkg" | |
| # binary | |
| install -Dm755 'target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}' "${DPKG_DIR}/usr/bin/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}" | |
| if [ -n "${{ steps.vars.outputs.STRIP }}" ]; then "${{ steps.vars.outputs.STRIP }}" "${DPKG_DIR}/usr/bin/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}" ; fi | |
| # README and LICENSE | |
| (shopt -s nullglob; for f in [R]"EADME"{,.*}; do install -Dm644 "$f" "${DPKG_DIR}/usr/share/doc/${{ env.PROJECT_NAME }}/$f" ; done) | |
| (shopt -s nullglob; for f in [L]"ICENSE"{-*,}{,.*}; do install -Dm644 "$f" "${DPKG_DIR}/usr/share/doc/${{ env.PROJECT_NAME }}/$f" ; done) | |
| # control file | |
| mkdir -p "${DPKG_DIR}/DEBIAN" | |
| printf "Package: ${{ steps.vars.outputs.DPKG_BASENAME }}\nVersion: ${{ steps.vars.outputs.DPKG_VERSION }}\nSection: utils\nPriority: optional\nMaintainer: ${{ env.PROJECT_AUTH }}\nArchitecture: ${{ steps.vars.outputs.DPKG_ARCH }}\nProvides: ${{ env.PROJECT_NAME }}\nConflicts: ${{ steps.vars.outputs.DPKG_CONFLICTS }}\nDescription: ${{ env.PROJECT_DESC }}\n" > "${DPKG_DIR}/DEBIAN/control" | |
| # build dpkg | |
| fakeroot dpkg-deb --build "${DPKG_DIR}" "${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.DPKG_NAME }}" | |
| fi | |
| - name: Publish | |
| uses: softprops/action-gh-release@v1 | |
| if: steps.vars.outputs.DEPLOY | |
| with: | |
| files: | | |
| ${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_NAME }} | |
| ${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.DPKG_NAME }} | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| coverage: | |
| name: Code Coverage | |
| runs-on: ${{ matrix.job.os }} | |
| strategy: | |
| fail-fast: true | |
| matrix: | |
| # job: [ { os: ubuntu-latest }, { os: macos-latest }, { os: windows-latest } ] | |
| job: | |
| - { os: ubuntu-latest , features: unix } | |
| - { os: macos-latest , features: macos } | |
| - { os: windows-latest , features: windows } | |
| steps: | |
| - uses: actions/checkout@v2 | |
| - name: Install/setup prerequisites | |
| shell: bash | |
| run: | | |
| ## install/setup prerequisites | |
| case '${{ matrix.job.os }}' in | |
| macos-latest) brew install coreutils ;; # needed for testing | |
| esac | |
| # - name: Reattach HEAD ## may be needed for accurate code coverage info | |
| # run: git checkout ${{ github.head_ref }} | |
| - name: Initialize workflow variables | |
| id: vars | |
| shell: bash | |
| run: | | |
| ## VARs setup | |
| outputs() { for var in "$@" ; do echo steps.vars.outputs.${var}="${!var}"; echo ::set-output name=${var}::${!var}; done; } | |
| # toolchain | |
| TOOLCHAIN="nightly-${{ env.RUST_COV_SRV }}" ## default to "nightly" toolchain (required for certain required unstable compiler flags) ## !maint: refactor when stable channel has needed support | |
| # * specify gnu-type TOOLCHAIN for windows; `grcov` requires gnu-style code coverage data files | |
| case ${{ matrix.job.os }} in windows-*) TOOLCHAIN="$TOOLCHAIN-x86_64-pc-windows-gnu" ;; esac; | |
| # * use requested TOOLCHAIN if specified | |
| if [ -n "${{ matrix.job.toolchain }}" ]; then TOOLCHAIN="${{ matrix.job.toolchain }}" ; fi | |
| outputs TOOLCHAIN | |
| # staging directory | |
| STAGING='_staging' | |
| outputs STAGING | |
| ## # check for CODECOV_TOKEN availability (work-around for inaccessible 'secrets' object for 'if'; see <https://github.community/t5/GitHub-Actions/jobs-lt-job-id-gt-if-does-not-work-with-env-secrets/m-p/38549>) | |
| ## # note: CODECOV_TOKEN / HAS_CODECOV_TOKEN is not needed for public repositories when using AppVeyor, Azure Pipelines, CircleCI, GitHub Actions, Travis (see <https://docs.codecov.io/docs/about-the-codecov-bash-uploader#section-upload-token>) | |
| ## unset HAS_CODECOV_TOKEN | |
| ## if [ -n $CODECOV_TOKEN ]; then HAS_CODECOV_TOKEN='true' ; fi | |
| ## outputs HAS_CODECOV_TOKEN | |
| # target-specific options | |
| # * CARGO_FEATURES_OPTION | |
| CARGO_FEATURES_OPTION='--all-features' ; ## default to '--all-features' for code coverage | |
| if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi | |
| outputs CARGO_FEATURES_OPTION | |
| # * CODECOV_FLAGS | |
| CODECOV_FLAGS=$( echo "${{ matrix.job.os }}" | sed 's/[^[:alnum:]]/_/g' ) | |
| outputs CODECOV_FLAGS | |
| - name: rust toolchain ~ install | |
| uses: actions-rs/toolchain@v1 | |
| with: | |
| toolchain: ${{ steps.vars.outputs.TOOLCHAIN }} | |
| default: true | |
| profile: minimal # minimal component installation (ie, no documentation) | |
| - name: Initialize toolchain-dependent workflow variables | |
| id: dep_vars | |
| shell: bash | |
| run: | | |
| ## Dependent VARs setup | |
| outputs() { for var in "$@" ; do echo steps.vars.outputs.${var}="${!var}"; echo ::set-output name=${var}::${!var}; done; } | |
| # * determine sub-crate utility list | |
| UTILITY_LIST="$(./util/show-utils.sh ${CARGO_FEATURES_OPTION})" | |
| CARGO_UTILITY_LIST_OPTIONS="$(for u in ${UTILITY_LIST}; do echo "-puu_${u}"; done;)" | |
| outputs CARGO_UTILITY_LIST_OPTIONS | |
| - name: Test uucore | |
| uses: actions-rs/cargo@v1 | |
| with: | |
| command: test | |
| args: ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} --no-fail-fast -p uucore | |
| env: | |
| CARGO_INCREMENTAL: '0' | |
| RUSTC_WRAPPER: '' | |
| RUSTFLAGS: '-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort' | |
| RUSTDOCFLAGS: '-Cpanic=abort' | |
| # RUSTUP_TOOLCHAIN: ${{ steps.vars.outputs.TOOLCHAIN }} | |
| - name: Test | |
| uses: actions-rs/cargo@v1 | |
| with: | |
| command: test | |
| args: ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} --no-fail-fast | |
| env: | |
| CARGO_INCREMENTAL: '0' | |
| RUSTC_WRAPPER: '' | |
| RUSTFLAGS: '-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort' | |
| RUSTDOCFLAGS: '-Cpanic=abort' | |
| # RUSTUP_TOOLCHAIN: ${{ steps.vars.outputs.TOOLCHAIN }} | |
| - name: Test individual utilities | |
| uses: actions-rs/cargo@v1 | |
| with: | |
| command: test | |
| args: ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} --no-fail-fast ${{ steps.dep_vars.outputs.CARGO_UTILITY_LIST_OPTIONS }} | |
| env: | |
| CARGO_INCREMENTAL: '0' | |
| RUSTC_WRAPPER: '' | |
| RUSTFLAGS: '-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort' | |
| RUSTDOCFLAGS: '-Cpanic=abort' | |
| # RUSTUP_TOOLCHAIN: ${{ steps.vars.outputs.TOOLCHAIN }} | |
| - name: "`grcov` ~ install" | |
| uses: actions-rs/install@v0.1 | |
| with: | |
| crate: grcov | |
| version: latest | |
| use-tool-cache: false | |
| - name: Generate coverage data (via `grcov`) | |
| id: coverage | |
| shell: bash | |
| run: | | |
| # generate coverage data | |
| COVERAGE_REPORT_DIR="target/debug" | |
| COVERAGE_REPORT_FILE="${COVERAGE_REPORT_DIR}/lcov.info" | |
| # GRCOV_IGNORE_OPTION='--ignore build.rs --ignore "/*" --ignore "[a-zA-Z]:/*"' ## `grcov` ignores these params when passed as an environment variable (why?) | |
| # GRCOV_EXCLUDE_OPTION='--excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()"' ## `grcov` ignores these params when passed as an environment variable (why?) | |
| mkdir -p "${COVERAGE_REPORT_DIR}" | |
| # display coverage files | |
| grcov . --output-type files --ignore build.rs --ignore "/*" --ignore "[a-zA-Z]:/*" --excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()" | sort --unique | |
| # generate coverage report | |
| grcov . --output-type lcov --output-path "${COVERAGE_REPORT_FILE}" --branch --ignore build.rs --ignore "/*" --ignore "[a-zA-Z]:/*" --excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()" | |
| echo ::set-output name=report::${COVERAGE_REPORT_FILE} | |
| - name: Upload coverage results (to Codecov.io) | |
| uses: codecov/codecov-action@v1 | |
| # if: steps.vars.outputs.HAS_CODECOV_TOKEN | |
| with: | |
| # token: ${{ secrets.CODECOV_TOKEN }} | |
| file: ${{ steps.coverage.outputs.report }} | |
| ## flags: IntegrationTests, UnitTests, ${{ steps.vars.outputs.CODECOV_FLAGS }} | |
| flags: ${{ steps.vars.outputs.CODECOV_FLAGS }} | |
| name: codecov-umbrella | |
| fail_ci_if_error: false |