mirror of
https://github.com/uutils/coreutils
synced 2024-12-20 10:03:33 +00:00
3bfb1afe5c
Before this change we never ran tests on uucore itself meaning that is was not possible to test functions of the shared core, only their usage in the different binaries This change adds running uucore to our ci, which will increase coverage for the few doctests that exist and is extracted from #1988 where first tests for uucore will be introduced
602 lines
30 KiB
YAML
602 lines
30 KiB
YAML
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 coreutils gnueabihf issuecomment maint nullglob onexitbegin onexitend tempfile uutils
|
|
|
|
env:
|
|
PROJECT_NAME: coreutils
|
|
PROJECT_DESC: "Core universal (cross-platform) utilities"
|
|
PROJECT_AUTH: "uutils"
|
|
RUST_MIN_SRV: "1.40.0" ## v1.40.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_format:
|
|
name: Style/format
|
|
runs-on: ${{ matrix.job.os }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
job:
|
|
- { os: ubuntu-latest , features: feat_os_unix }
|
|
steps:
|
|
- uses: actions/checkout@v1
|
|
- name: Initialize workflow variables
|
|
id: vars
|
|
shell: bash
|
|
run: |
|
|
## VARs setup
|
|
# target-specific options
|
|
# * CARGO_FEATURES_OPTION
|
|
CARGO_FEATURES_OPTION='' ;
|
|
if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi
|
|
echo set-output name=CARGO_FEATURES_OPTION::${CARGO_FEATURES_OPTION}
|
|
echo ::set-output name=CARGO_FEATURES_OPTION::${CARGO_FEATURES_OPTION}
|
|
- name: Install `rust` toolchain
|
|
uses: actions-rs/toolchain@v1
|
|
with:
|
|
toolchain: stable
|
|
default: true
|
|
profile: minimal # minimal component installation (ie, no documentation)
|
|
components: rustfmt
|
|
- name: "`fmt` testing"
|
|
shell: bash
|
|
run: |
|
|
# `fmt` 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 fmt -- --check) && printf "%s\n" "$S" || { printf "%s\n" "$S" | sed -E -n -e "s/^Diff[[:space:]]+in[[:space:]]+${PWD//\//\\/}\/(.*)[[:space:]]+at[[:space:]]+[^0-9]+([0-9]+).*$/::warning file=\1,line=\2::WARNING: \`cargo fmt\`: style violation/p" ; }
|
|
- name: "`fmt` testing of tests"
|
|
shell: bash
|
|
run: |
|
|
# `fmt` testing of tests
|
|
# * 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=$(find tests -name "*.rs" -print0 | xargs -0 cargo fmt -- --check) && printf "%s\n" "$S" || { printf "%s\n" "$S" | sed -E -n "s/^Diff[[:space:]]+in[[:space:]]+${PWD//\//\\/}\/(.*)[[:space:]]+at[[:space:]]+[^0-9]+([0-9]+).*$/::warning file=\1,line=\2::WARNING: \`cargo fmt\`: style violation/p" ; }
|
|
|
|
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@v1
|
|
- name: Initialize workflow variables
|
|
id: vars
|
|
shell: bash
|
|
run: |
|
|
## VARs setup
|
|
# target-specific options
|
|
# * CARGO_FEATURES_OPTION
|
|
CARGO_FEATURES_OPTION='' ;
|
|
if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi
|
|
echo set-output name=CARGO_FEATURES_OPTION::${CARGO_FEATURES_OPTION}
|
|
echo ::set-output name=CARGO_FEATURES_OPTION::${CARGO_FEATURES_OPTION}
|
|
- name: Install `rust` toolchain
|
|
uses: actions-rs/toolchain@v1
|
|
with:
|
|
toolchain: stable
|
|
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 clippy ${{ 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 '}' ; }
|
|
|
|
min_version:
|
|
name: MinRustV # Minimum supported rust version
|
|
runs-on: ${{ matrix.job.os }}
|
|
strategy:
|
|
matrix:
|
|
job:
|
|
- { os: ubuntu-latest , features: feat_os_unix }
|
|
steps:
|
|
- uses: actions/checkout@v1
|
|
- name: Install `rust` toolchain (v${{ env.RUST_MIN_SRV }})
|
|
uses: actions-rs/toolchain@v1
|
|
with:
|
|
toolchain: ${{ env.RUST_MIN_SRV }}
|
|
default: true
|
|
profile: minimal # minimal component installation (ie, no documentation)
|
|
- 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: Confirm compatible 'Cargo.lock'
|
|
shell: bash
|
|
run: |
|
|
# Confirm compatible 'Cargo.lock'
|
|
# * 'Cargo.lock' is required to be in a format that `cargo` of MinSRV can interpret (eg, v1-format for MinSRV < v1.38)
|
|
cargo fetch --locked --quiet || { echo "::error file=Cargo.lock::Incompatible 'Cargo.lock' format; try \`cargo +${{ env.RUST_MIN_SRV }} update\`" ; exit 1 ; }
|
|
- name: Info
|
|
shell: bash
|
|
run: |
|
|
# Info
|
|
## 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
|
|
## * using the 'stable' toolchain is necessary to avoid "unexpected '--filter-platform'" errors
|
|
RUSTUP_TOOLCHAIN=stable cargo-tree tree --frozen --all --no-dev-dependencies --no-indent --features ${{ matrix.job.features }} | grep -vE "$PWD" | sort --unique
|
|
|
|
- name: Test
|
|
uses: actions-rs/cargo@v1
|
|
with:
|
|
command: test
|
|
args: --features "feat_os_unix" -p uucore -p coreutils
|
|
env:
|
|
RUSTFLAGS: '-Awarnings'
|
|
|
|
busybox_test:
|
|
name: Busybox test suite
|
|
runs-on: ${{ matrix.job.os }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
job:
|
|
- { os: ubuntu-latest }
|
|
steps:
|
|
- uses: actions/checkout@v1
|
|
- 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" ; }
|
|
|
|
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@v1
|
|
- 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@v1
|
|
- 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
|
|
- name: Initialize workflow variables
|
|
id: vars
|
|
shell: bash
|
|
run: |
|
|
## VARs setup
|
|
# 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
|
|
echo set-output name=TOOLCHAIN::${TOOLCHAIN:-<empty>/false}
|
|
echo ::set-output name=TOOLCHAIN::${TOOLCHAIN}
|
|
# staging directory
|
|
STAGING='_staging'
|
|
echo set-output name=STAGING::${STAGING}
|
|
echo ::set-output name=STAGING::${STAGING}
|
|
# determine EXE suffix
|
|
EXE_suffix="" ; case '${{ matrix.job.target }}' in *-pc-windows-*) EXE_suffix=".exe" ;; esac;
|
|
echo set-output name=EXE_suffix::${EXE_suffix}
|
|
echo ::set-output name=EXE_suffix::${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}
|
|
echo set-output name=REF_NAME::${REF_NAME}
|
|
echo set-output name=REF_BRANCH::${REF_BRANCH}
|
|
echo set-output name=REF_TAG::${REF_TAG}
|
|
echo set-output name=REF_SHAS::${REF_SHAS}
|
|
echo ::set-output name=REF_NAME::${REF_NAME}
|
|
echo ::set-output name=REF_BRANCH::${REF_BRANCH}
|
|
echo ::set-output name=REF_TAG::${REF_TAG}
|
|
echo ::set-output name=REF_SHAS::${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;
|
|
echo set-output name=TARGET_ARCH::${TARGET_ARCH}
|
|
echo ::set-output name=TARGET_ARCH::${TARGET_ARCH}
|
|
unset TARGET_OS ; case '${{ matrix.job.target }}' in *-linux-*) TARGET_OS=linux ;; *-apple-*) TARGET_OS=macos ;; *-windows-*) TARGET_OS=windows ;; esac;
|
|
echo set-output name=TARGET_OS::${TARGET_OS}
|
|
echo ::set-output name=TARGET_OS::${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}
|
|
echo set-output name=PKG_suffix::${PKG_suffix}
|
|
echo set-output name=PKG_BASENAME::${PKG_BASENAME}
|
|
echo set-output name=PKG_NAME::${PKG_NAME}
|
|
echo ::set-output name=PKG_suffix::${PKG_suffix}
|
|
echo ::set-output name=PKG_BASENAME::${PKG_BASENAME}
|
|
echo ::set-output name=PKG_NAME::${PKG_NAME}
|
|
# deployable tag? (ie, leading "vM" or "M"; M == version number)
|
|
unset DEPLOY ; if [[ $REF_TAG =~ ^[vV]?[0-9].* ]]; then DEPLOY='true' ; fi
|
|
echo set-output name=DEPLOY::${DEPLOY:-<empty>/false}
|
|
echo ::set-output name=DEPLOY::${DEPLOY}
|
|
# DPKG architecture?
|
|
unset DPKG_ARCH
|
|
case ${{ matrix.job.target }} in
|
|
x86_64-*-linux-*) DPKG_ARCH=amd64 ;;
|
|
*-linux-*) DPKG_ARCH=${TARGET_ARCH} ;;
|
|
esac
|
|
echo set-output name=DPKG_ARCH::${DPKG_ARCH}
|
|
echo ::set-output name=DPKG_ARCH::${DPKG_ARCH}
|
|
# DPKG version?
|
|
unset DPKG_VERSION ; if [[ $REF_TAG =~ ^[vV]?[0-9].* ]]; then DPKG_VERSION=${REF_TAG/#[vV]/} ; fi
|
|
echo set-output name=DPKG_VERSION::${DPKG_VERSION}
|
|
echo ::set-output name=DPKG_VERSION::${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;
|
|
echo set-output name=DPKG_BASENAME::${DPKG_BASENAME}
|
|
echo set-output name=DPKG_CONFLICTS::${DPKG_CONFLICTS}
|
|
echo ::set-output name=DPKG_BASENAME::${DPKG_BASENAME}
|
|
echo ::set-output name=DPKG_CONFLICTS::${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
|
|
echo set-output name=DPKG_NAME::${DPKG_NAME}
|
|
echo ::set-output name=DPKG_NAME::${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
|
|
echo set-output name=CARGO_FEATURES_OPTION::${CARGO_FEATURES_OPTION}
|
|
echo ::set-output name=CARGO_FEATURES_OPTION::${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;
|
|
echo set-output name=CARGO_USE_CROSS::${CARGO_USE_CROSS:-<empty>/false}
|
|
echo ::set-output name=CARGO_USE_CROSS::${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;
|
|
echo set-output name=CARGO_TEST_OPTIONS::${CARGO_TEST_OPTIONS}
|
|
echo ::set-output name=CARGO_TEST_OPTIONS::${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;
|
|
echo set-output name=STRIP::${STRIP:-<empty>/false}
|
|
echo ::set-output name=STRIP::${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
|
|
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
|
|
# * 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;)"
|
|
echo set-output name=UTILITY_LIST::${UTILITY_LIST}
|
|
echo ::set-output name=CARGO_UTILITY_LIST_OPTIONS::${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@v1
|
|
# - 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: |
|
|
# 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
|
|
echo set-output name=TOOLCHAIN::${TOOLCHAIN}
|
|
echo ::set-output name=TOOLCHAIN::${TOOLCHAIN}
|
|
# staging directory
|
|
STAGING='_staging'
|
|
echo set-output name=STAGING::${STAGING}
|
|
echo ::set-output name=STAGING::${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
|
|
## echo set-output name=HAS_CODECOV_TOKEN::${HAS_CODECOV_TOKEN}
|
|
## echo ::set-output name=HAS_CODECOV_TOKEN::${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
|
|
echo set-output name=CARGO_FEATURES_OPTION::${CARGO_FEATURES_OPTION}
|
|
echo ::set-output name=CARGO_FEATURES_OPTION::${CARGO_FEATURES_OPTION}
|
|
# * CODECOV_FLAGS
|
|
CODECOV_FLAGS=$( echo "${{ matrix.job.os }}" | sed 's/[^[:alnum:]]/_/g' )
|
|
echo set-output name=CODECOV_FLAGS::${CODECOV_FLAGS}
|
|
echo ::set-output name=CODECOV_FLAGS::${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
|
|
# * 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;)"
|
|
echo set-output name=UTILITY_LIST::${UTILITY_LIST}
|
|
echo ::set-output name=CARGO_UTILITY_LIST_OPTIONS::${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: true
|
|
- 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
|