on: workflow_call: inputs: matrix-args: required: false type: string description: Arguments to pass to `cargo xtask ci-job target-matrix` checkout-ref: required: false type: string description: Used to checkout a specific ref, instead of the default ref with `actions/checkout` action pull_request: merge_group: push: branches: [main, staging, trying] tags: - "v*.*.*" name: CI env: CARGO_NET_RETRY: 3 CARGO_HTTP_CHECK_REVOKE: false jobs: shellcheck: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: ref: ${{ inputs.checkout-ref }} - name: Run ShellCheck uses: azohra/shell-linter@v0.6.0 cargo-deny: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: ref: ${{ inputs.checkout-ref }} - uses: EmbarkStudios/cargo-deny-action@v1 fmt: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: ref: ${{ inputs.checkout-ref }} - uses: ./.github/actions/setup-rust with: components: rustfmt - name: Run rustfmt run: cargo fmt -- --check clippy: runs-on: ${{ matrix.os }} strategy: matrix: os: - macos-latest - ubuntu-latest - windows-latest steps: - uses: actions/checkout@v3 with: ref: ${{ inputs.checkout-ref }} - uses: ./.github/actions/setup-rust with: components: clippy toolchain: 1.77.2 # MSRV, Minimally Supported Rust Version. Make sure to update README.md and clippy.toml - name: Run clippy run: cargo clippy --locked --all-targets --all-features --workspace -- -D warnings test: runs-on: ${{ matrix.os }} strategy: matrix: os: - macos-latest - ubuntu-latest - windows-latest steps: - uses: actions/checkout@v3 with: ref: ${{ inputs.checkout-ref }} - uses: ./.github/actions/setup-rust - uses: ./.github/actions/cargo-llvm-cov with: name: test-${{matrix.os}} - name: Run unit tests run: cargo test --locked --all-targets --workspace --all-features timeout-minutes: 10 check: runs-on: ubuntu-latest outputs: is-latest: ${{ steps.check.outputs.is-latest }} steps: - uses: actions/checkout@v3 with: ref: ${{ inputs.checkout-ref }} - uses: ./.github/actions/setup-rust - run: cargo xtask ci-job check id: check generate-matrix: runs-on: ubuntu-latest outputs: matrix: ${{ steps.generate-matrix.outputs.matrix }} tests: ${{ steps.generate-matrix.outputs.tests }} steps: - uses: actions/checkout@v3 with: ref: ${{ inputs.checkout-ref }} - uses: ./.github/actions/setup-rust - name: Generate matrix id: generate-matrix run: cargo xtask ci-job target-matrix ${{ github.event_name == 'merge_group' && format('--merge-group {0}', github.ref) || '' }} ${{ inputs.matrix-args || '' }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} build: name: target (${{ matrix.pretty }},${{ matrix.os }}) runs-on: ${{ matrix.os }} needs: [shellcheck, test, generate-matrix, check] if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'merge_group' || github.event_name == 'issue_comment' || github.event_name == 'schedule') && needs.generate-matrix.outputs.matrix != '{}' && needs.generate-matrix.outputs.matrix != '[]' && needs.generate-matrix.outputs.matrix != '' concurrency: group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.pretty }} cancel-in-progress: false strategy: fail-fast: false matrix: include: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} 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 with: ref: ${{ inputs.checkout-ref }} - uses: ./.github/actions/setup-rust - name: Set up Docker Buildx if: runner.os == 'Linux' uses: docker/setup-buildx-action@v2 - name: Build xtask run: cargo build -p xtask - name: Prepare Meta id: prepare-meta timeout-minutes: 60 run: cargo xtask ci-job prepare-meta "${TARGET}${SUB:+.$SUB}" env: 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 && steps.prepare-meta.outputs.test-variant != 'zig' 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 uses: docker/metadata-action@v4 with: images: | name=${{ steps.prepare-meta.outputs.image }} labels: | ${{ fromJSON(steps.prepare-meta.outputs.labels) }} - name: Build Docker image id: build-docker-image if: steps.prepare-meta.outputs.has-image timeout-minutes: 120 run: cargo xtask build-docker-image -v "${TARGET}${SUB:+.$SUB}" ${{ matrix.verbose && '-v' || '' }} env: TARGET: ${{ matrix.target }} SUB: ${{ matrix.sub }} LABELS: ${{ steps.docker-meta.outputs.labels }} LATEST: ${{ needs.check.outputs.is-latest || 'false' }} shell: bash - name: Set Docker image for test if: steps.prepare-meta.outputs.has-image run: | TARGET_VAR="cross_target_${TARGET//-/_}_image" echo "${TARGET_VAR^^}=${IMAGE}" | tee -a "${GITHUB_ENV}" env: TARGET: ${{ matrix.target }} IMAGE: ${{ steps.build-docker-image.outputs.image }} shell: bash - name: Test Image if: steps.prepare-meta.outputs.has-image && steps.prepare-meta.outputs.test-variant == 'default' run: ./ci/test.sh env: TARGET: ${{ matrix.target }} CPP: ${{ matrix.cpp }} DYLIB: ${{ matrix.dylib }} STD: ${{ matrix.std }} BUILD_STD: ${{ matrix.build-std }} RUN: ${{ matrix.run }} RUNNERS: ${{ matrix.runners }} shell: bash - uses: ./.github/actions/cargo-install-upload-artifacts if: matrix.deploy with: target: ${{ matrix.target }} - name: Test Zig Image if: steps.prepare-meta.outputs.has-image && steps.prepare-meta.outputs.test-variant == 'zig' run: ./ci/test-zig-image.sh shell: bash - name: Test Cross Image if: steps.prepare-meta.outputs.has-image && steps.prepare-meta.outputs.test-variant == 'cross' run: ./ci/test-cross-image.sh env: TARGET: 'aarch64-unknown-linux-gnu' IMAGE: 'ghcr.io/cross-rs/aarch64-unknown-linux-gnu:main' shell: bash - name: Login to GitHub Container Registry if: steps.prepare-meta.outputs.has-image uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Push image to GitHub Container Registry if: > (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule') && steps.prepare-meta.outputs.has-image && ( github.ref == format('refs/heads/{0}', github.event.repository.default_branch) || startsWith(github.ref, 'refs/tags/v') ) run: cargo xtask build-docker-image -v --push "${TARGET}${SUB:+.$SUB}" env: TARGET: ${{ matrix.target }} SUB: ${{ matrix.sub }} LABELS: ${{ steps.docker-meta.outputs.labels }} LATEST: ${{ needs.check.outputs.is-latest || 'false' }} shell: bash # we should always have an artifact from a previous build. remote: needs: [test, check, generate-matrix] if: fromJson(needs.generate-matrix.outputs.tests).remote runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: ref: ${{ inputs.checkout-ref }} - uses: ./.github/actions/setup-rust - name: LLVM instrument coverage uses: ./.github/actions/cargo-llvm-cov with: name: integration-remote - name: Run Remote Test env: TARGET: aarch64-unknown-linux-gnu run: ./ci/test-remote.sh shell: bash bisect: needs: [test, check, generate-matrix] if: fromJson(needs.generate-matrix.outputs.tests).bisect runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: ref: ${{ inputs.checkout-ref }} - uses: ./.github/actions/setup-rust - name: LLVM instrument coverage uses: ./.github/actions/cargo-llvm-cov with: name: integration-bisect - name: Run Bisect Test env: TARGET: aarch64-unknown-linux-gnu run: ./ci/test-bisect.sh shell: bash foreign: needs: [test, check, generate-matrix] if: fromJson(needs.generate-matrix.outputs.tests).foreign runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: ref: ${{ inputs.checkout-ref }} - uses: ./.github/actions/setup-rust - name: LLVM instrument coverage uses: ./.github/actions/cargo-llvm-cov with: name: integration-bisect - name: Set up QEMU uses: docker/setup-qemu-action@v2 with: platforms: arm64 - name: Set up docker buildx uses: docker/setup-buildx-action@v2 id: buildx with: install: true - name: Run Foreign toolchain test run: ./ci/test-foreign-toolchain.sh shell: bash docker-in-docker: needs: [test, check, generate-matrix] if: fromJson(needs.generate-matrix.outputs.tests).docker-in-docker runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: ref: ${{ inputs.checkout-ref }} - uses: ./.github/actions/setup-rust - name: LLVM instrument coverage uses: ./.github/actions/cargo-llvm-cov with: name: integration-docker-in-docker - name: Run Docker-in-Docker Test env: TARGET: aarch64-unknown-linux-gnu IMAGE: 'ghcr.io/cross-rs/aarch64-unknown-linux-gnu:main' run: ./ci/test-docker-in-docker.sh shell: bash podman: name: podman runs-on: ubuntu-latest needs: [shellcheck, test, check, generate-matrix] if: fromJson(needs.generate-matrix.outputs.tests).podman strategy: fail-fast: false outputs: coverage-artifact: ${{ steps.cov.outputs.artifact-name }} steps: - uses: actions/checkout@v3 with: ref: ${{ inputs.checkout-ref }} - uses: ./.github/actions/setup-rust - name: Install Podman env: DEBIAN_FRONTEND: noninteractive run: | sudo apt-get update sudo apt-get install podman --no-install-recommends --assume-yes - name: LLVM instrument coverage id: cov uses: ./.github/actions/cargo-llvm-cov with: name: cross-podman-aarch64-unknown-linux-gnu - name: Install cross run: cargo install --path . --force --debug - name: Run Podman Test run: ./ci/test-podman.sh env: CROSS_CONTAINER_ENGINE: podman TARGET: aarch64-unknown-linux-gnu shell: bash publish: needs: [build, check, fmt, clippy, cargo-deny] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: ref: ${{ inputs.checkout-ref }} - uses: ./.github/actions/setup-rust - uses: ./.github/actions/cargo-publish with: cargo-registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }} conclusion: needs: [shellcheck, fmt, clippy, test, generate-matrix, build, publish, check, remote, bisect, docker-in-docker, foreign, podman] if: always() runs-on: ubuntu-latest steps: - name: Result run: | jq -C <<< "${needs}" # Check if all needs were successful or skipped. "$(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 with: ref: ${{ inputs.checkout-ref }} - uses: ./.github/actions/setup-rust - uses: actions/download-artifact@v3 with: path: ${{ runner.temp }}/artifacts - name: Grab PR number run: echo "pr=$(echo ${commit_message} | sed -ne 's/.*#\(.*\):/\1/p')" >> $GITHUB_OUTPUT 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) for file in $(find ${artifacts} -name "lcov.*.info" -exec ls {} +); do name=$(echo $file | awk -F'.' '{print $2}'); ./codecov -F $name ${pr:+-P ${pr}} -f $file --sha ${sha_rev} -n $name; done env: pr: ${{ steps.pr-number.outputs.pr }} artifacts: ${{ runner.temp }}/artifacts