diff --git a/.github/actions/cargo-install-upload-artifacts/action.yml b/.github/actions/cargo-install-upload-artifacts/action.yml index 2486c71d9..07bd34f53 100644 --- a/.github/actions/cargo-install-upload-artifacts/action.yml +++ b/.github/actions/cargo-install-upload-artifacts/action.yml @@ -40,6 +40,8 @@ runs: --root ${{ steps.metadata.outputs.out-dir }} --bins use-cross: true + env: + RUSTFLAGS: "" # Make sure to unset RUSTFLAGS - name: Archive artifacts id: archive diff --git a/.github/actions/cargo-llvm-cov/action.yml b/.github/actions/cargo-llvm-cov/action.yml new file mode 100644 index 000000000..49eb4dda4 --- /dev/null +++ b/.github/actions/cargo-llvm-cov/action.yml @@ -0,0 +1,67 @@ +name: llvm coverage +description: Sets up everything that is needed for coverage. Makes artifacts available for processing later, prefixed with _coverage- +inputs: + name: + description: 'the name of the artifact' + required: true +outputs: + artifact-name: + description: 'the name of the artifact' + value: ${{ steps.cov.outputs.artifact-name }} +runs: + using: composite + steps: + - name: Install cargo-llvm-cov + uses: taiki-e/install-action@v1 + with: + tool: cargo-llvm-cov + - run: rustup component add llvm-tools-preview + shell: bash + - name: LLVM instrument coverage + id: cov + uses: ./.github/actions/post + if: always() + with: + main: | + pwd=$(pwd) + if which cygpath; then + pwd="$(cygpath -w "$(pwd)")" + fi + echo RUSTFLAGS=" -C instrument-coverage --remap-path-prefix ${pwd}=" >> $GITHUB_ENV + echo LLVM_PROFILE_FILE="${pwd}/target/cross-%m.profraw" >> $GITHUB_ENV + echo CARGO_INCREMENTAL="0" >> $GITHUB_ENV + echo RUST_TEST_THREADS="1" >> $GITHUB_ENV + echo "::set-output name=artifact-name::_coverage-${name}" + post: | + # XXX(emilgardis): Upload early? + pwd=$(pwd) + if which cygpath; then + pwd="$(cygpath -w "$(pwd)")" + fi + # No pwd needed here, we're in the root + export LLVM_PROFILE_FILE="${pwd}/target/cross-%m.profraw" + export CARGO_LLVM_COV_TARGET_DIR="${pwd}/target" + mkdir coverage + echo $(ls target) + cargo llvm-cov --no-run --remap-path-prefix --lcov --output-path "coverage/lcov.${name}.info" -vv || ( echo "::error title=Coverage merge failed::" && exit 0 ) + rm target/*.profraw + npm install @actions/artifact + npm install glob + + cat <<-EOT | node - || ( echo "::error title=Coverage upload failed::" && exit 0 ) + (async function main() { + var artifact = require('@actions/artifact'); + var glob = require('glob') + const artifactClient = artifact.create(); + const artifactName = '_coverage-' + process.env.name; + const files = glob.sync("coverage/*"); + if (!files.length) { + process.exit(0); + } + console.log("${files}") + const options = { retentionDays: 2 }; + const upload = await artifactClient.uploadArtifact(artifactName, files, "coverage", options); + })() + EOT + env: + name: ${{ inputs.name }} diff --git a/.github/actions/cargo-publish/action.yml b/.github/actions/cargo-publish/action.yml index 83d8544e6..bcba68033 100644 --- a/.github/actions/cargo-publish/action.yml +++ b/.github/actions/cargo-publish/action.yml @@ -40,7 +40,7 @@ runs: shell: bash env: GITHUB_TOKEN: ${{ inputs.github-token }} - + - name: Create GitHub release if: > github.event_name == 'push' && ( @@ -54,7 +54,7 @@ runs: prerelease: ${{ startsWith(github.ref, 'refs/tags/v') && contains(github.ref_name, '-') }} draft: ${{ !startsWith(github.ref, 'refs/tags/v') && steps.changelog-reader.outputs.status == 'unreleased' }} files: | - ${{ steps.download-artifacts.outputs.download-path }}/*/* + ${{ steps.download-artifacts.outputs.download-path }}/cross-*/* - name: Publish crate uses: actions-rs/cargo@v1 diff --git a/.github/actions/post/action.yml b/.github/actions/post/action.yml new file mode 100644 index 000000000..d8db192df --- /dev/null +++ b/.github/actions/post/action.yml @@ -0,0 +1,14 @@ +# adapted from https://github.com/actions/runner/issues/1478 +name: With post step +description: 'Generic JS Action to execute a main command and set a command in a post step.' +inputs: + main: + description: 'Main command/script.' + required: true + post: + description: 'Post command/script.' + required: true +runs: + using: 'node16' + main: 'main.js' + post: 'main.js' diff --git a/.github/actions/post/main.js b/.github/actions/post/main.js new file mode 100644 index 000000000..94bcec651 --- /dev/null +++ b/.github/actions/post/main.js @@ -0,0 +1,26 @@ +// adapted from https://github.com/actions/runner/issues/1478 +const { exec } = require("child_process"); + +function run(cmd) { + exec(cmd, { shell: "bash" }, (error, stdout, stderr) => { + if (stdout.length != 0) { + console.log(`${stdout}`); + } + if (stderr.length != 0) { + console.error(`${stderr}`); + } + if (error) { + process.exitCode = error.code; + console.error(`${error}`); + } + }); +} + +if (process.env[`STATE_POST`] != undefined) { + // Are we in the 'post' step? + run(process.env.INPUT_POST); +} else { + // Otherwise, this is the main step + console.log(`::save-state name=POST::true`); + run(process.env.INPUT_MAIN); +} diff --git a/.github/codecov.yml b/.github/codecov.yml new file mode 100644 index 000000000..30677680e --- /dev/null +++ b/.github/codecov.yml @@ -0,0 +1,14 @@ +comment: false +codecov: + branch: main +coverage: + status: + project: + default: + informational: true + patch: + default: + informational: true +flag_management: + default_rules: # the rules that will be followed for any flag added, generally + carryforward: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b9b511828..5c7db32c2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -75,6 +75,9 @@ jobs: - uses: actions/checkout@v3 - uses: ./.github/actions/setup-rust + - uses: ./.github/actions/cargo-llvm-cov + with: + name: test-${{matrix.os}} - name: Run unit tests uses: actions-rs/cargo@v1 @@ -208,6 +211,7 @@ jobs: outputs: has-image: ${{ steps.prepare-meta.outputs.has-image }} images: ${{ steps.build-docker-image.outputs.images && fromJSON(steps.build-docker-image.outputs.images) }} + coverage-artifact: ${{ steps.cov.outputs.artifact-name }} steps: - uses: actions/checkout@v3 @@ -217,12 +221,9 @@ jobs: if: runner.os == 'Linux' uses: docker/setup-buildx-action@v1 - - name: Install cross - if: matrix.deploy - run: cargo install --path . --force - - name: Build xtask run: cargo build -p xtask + - name: Prepare Meta id: prepare-meta timeout-minutes: 60 @@ -231,6 +232,18 @@ jobs: TARGET: ${{ matrix.target }} SUB: ${{ matrix.sub }} shell: bash + + - name: LLVM instrument coverage + id: cov + uses: ./.github/actions/cargo-llvm-cov + if: steps.prepare-meta.outputs.has-image + with: + name: cross-${{matrix.pretty}} + + - name: Install cross + if: matrix.deploy + run: cargo install --path . --force --debug + - name: Docker Meta if: steps.prepare-meta.outputs.has-image id: docker-meta @@ -321,3 +334,39 @@ jobs: "$(jq -r 'all(.result as $result | (["success", "skipped"] | contains([$result])))' <<< "${needs}")" env: needs: ${{ toJson(needs) }} + + code-cov: + name: Coverage + needs: [test, build, conclusion, generate-matrix] + # should check that there are any artifacts, if not skip + if: always() && (needs.build.result == 'success' || needs.build.result == 'skipped') && needs.test.result == 'success' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/setup-rust + - uses: actions/download-artifact@v3 + with: + path: ${{ runner.temp }}/artifacts + - name: Grab PR number + run: echo "::set-output name=pr::"$(echo $commit_message | sed -ne 's/.*\#\(.*\):/\1/p') + id: pr-number + if: ${{ !github.event.pull_request.number }} + env: + commit_message: > + ${{ + (( + startsWith(github.event.head_commit.message, 'Try #') && + github.event.head_commit.author.username == 'bors[bot]' + ) && github.event.head_commit.message) || '' + }} + - name: Upload to codecov.io + run: | + set -x + curl -Os https://uploader.codecov.io/latest/linux/codecov + chmod +x codecov + sha_rev=$(git rev-parse HEAD) + find ${artifacts} -name "lcov.*.info" -exec ./codecov -F $(echo {} | sed -n 's/lcov\.\(.*\)\.info/\1/p') \ + ${pr:+-P ${pr}} -f {} --sha ${sha_rev} -n $(echo {} | sed -n 's/lcov\.\(.*\)\.info/\1/p') \; + env: + pr: ${{ steps.pr-number.outputs.pr || '' }} + artifacts: ${{ runner.temp }}/artifacts diff --git a/ci/test.sh b/ci/test.sh index d47a52ab9..b920429b9 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -41,7 +41,10 @@ main() { local td= retry cargo fetch - cargo install --force --path . + cargo install --force --path . --debug + + # Unset RUSTFLAGS + export RUSTFLAGS="" export QEMU_STRACE=1 @@ -165,7 +168,7 @@ main() { --depth 1 \ --recursive \ https://github.com/cross-rs/test-workspace "${td}" - + pushd "${td}" TARGET="${TARGET}" workspace_test --manifest-path="./workspace/Cargo.toml" pushd "workspace"