diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 619297e..e3a0c27 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,6 +9,10 @@ on: branches: [ "main" ] pull_request: +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + permissions: contents: write pull-requests: write diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1cb7f5c..e74335d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,6 +9,10 @@ on: tags: - "v*" +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + jobs: checks: uses: ./.github/workflows/reusable-ci.yml diff --git a/.github/workflows/reusable-ci.yml b/.github/workflows/reusable-ci.yml index bed8187..efbe3ca 100644 --- a/.github/workflows/reusable-ci.yml +++ b/.github/workflows/reusable-ci.yml @@ -12,16 +12,12 @@ on: default: true jobs: - ci: + msrv: runs-on: ubuntu-latest - env: - CARGO_LOCKED: "true" - + outputs: + version: ${{ steps.msrv.outputs.msrv }} steps: - uses: actions/checkout@v5 - with: - fetch-depth: 0 - persist-credentials: true # оставляем токен в origin, чтобы git push работал - name: Read MSRV from Cargo.toml id: msrv @@ -40,10 +36,28 @@ jobs: echo "msrv=${RV}" >> "$GITHUB_OUTPUT" echo "Using MSRV: $RV" - - name: Install Rust (${{ steps.msrv.outputs.msrv }}) + ci: + runs-on: ubuntu-latest + needs: msrv + strategy: + fail-fast: false + matrix: + rust: + - ${{ needs.msrv.outputs.version }} + - stable + env: + CARGO_LOCKED: "true" + + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + persist-credentials: true # оставляем токен в origin, чтобы git push работал + + - name: Install Rust (${{ matrix.rust }}) uses: dtolnay/rust-toolchain@v1 with: - toolchain: ${{ steps.msrv.outputs.msrv }} + toolchain: ${{ matrix.rust }} components: clippy - name: Install nightly rustfmt @@ -68,6 +82,7 @@ jobs: # ---------- README handling ---------- - name: Build (may regenerate README to temp) + if: matrix.rust == needs.msrv.outputs.version shell: bash env: TZ: UTC @@ -78,7 +93,7 @@ jobs: run: | set -euo pipefail tmp="$(mktemp)" - cargo +${{ steps.msrv.outputs.msrv }} build --workspace -q || cargo +${{ steps.msrv.outputs.msrv }} build -q + cargo +${{ matrix.rust }} build --workspace -q || cargo +${{ matrix.rust }} build -q if [ -f README.md ]; then cp -f README.md "$tmp" last_byte="$(tail -c1 "$tmp" 2>/dev/null || true)" @@ -89,7 +104,7 @@ jobs: echo "README_CANDIDATE=$tmp" >> "$GITHUB_ENV" - name: README drift on PR (report only) - if: github.event_name == 'pull_request' + if: github.event_name == 'pull_request' && matrix.rust == needs.msrv.outputs.version shell: bash run: | set -euo pipefail @@ -105,7 +120,7 @@ jobs: fi - name: README autocommit on main (push or PR) - if: github.event_name == 'push' && github.ref == 'refs/heads/main' + if: github.event_name == 'push' && github.ref == 'refs/heads/main' && matrix.rust == needs.msrv.outputs.version id: readme_update shell: bash env: @@ -159,7 +174,7 @@ jobs: git push -u origin "$BR" - name: Create pull request for README (fallback) - if: steps.readme_update.outputs.updated == 'true' && github.event_name == 'push' && github.ref == 'refs/heads/main' + if: steps.readme_update.outputs.updated == 'true' && github.event_name == 'push' && github.ref == 'refs/heads/main' && matrix.rust == needs.msrv.outputs.version uses: peter-evans/create-pull-request@v6 with: token: ${{ secrets.GITHUB_TOKEN }} @@ -173,30 +188,33 @@ jobs: # ---------- end README handling ---------- - name: Check formatting (nightly rustfmt) + if: matrix.rust == needs.msrv.outputs.version uses: ./.github/actions/cargo-fmt with: toolchain: nightly - - name: Clippy (MSRV) + - name: Clippy (${{ matrix.rust }}) uses: ./.github/actions/cargo-clippy with: - toolchain: ${{ steps.msrv.outputs.msrv }} + toolchain: ${{ matrix.rust }} all-features: ${{ inputs.all-features }} - name: Cargo deny + if: matrix.rust == needs.msrv.outputs.version uses: ./.github/actions/cargo-deny - - name: Tests (MSRV) + - name: Tests (${{ matrix.rust }}) uses: ./.github/actions/cargo-test with: - toolchain: ${{ steps.msrv.outputs.msrv }} + toolchain: ${{ matrix.rust }} all-features: ${{ inputs.all-features }} - name: Security audit + if: matrix.rust == needs.msrv.outputs.version uses: ./.github/actions/cargo-audit - name: Auto-commit README changes (any branch) - if: always() + if: always() && matrix.rust == needs.msrv.outputs.version run: | set -euo pipefail if ! cmp -s README.md "$README_CANDIDATE"; then @@ -212,6 +230,7 @@ jobs: fi - name: Ensure tree is clean before package + if: matrix.rust == needs.msrv.outputs.version shell: bash run: | set -euo pipefail @@ -222,5 +241,38 @@ jobs: fi - name: Package (dry-run) - run: cargo +${{ steps.msrv.outputs.msrv }} package --locked + if: matrix.rust == needs.msrv.outputs.version + run: cargo +${{ matrix.rust }} package --locked + + coverage: + runs-on: ubuntu-latest + needs: ci + steps: + - uses: actions/checkout@v5 + + - name: Install Rust (stable) + uses: dtolnay/rust-toolchain@v1 + with: + toolchain: stable + components: llvm-tools-preview + + - name: Install cargo-llvm-cov + uses: taiki-e/install-action@v2 + with: + tool: cargo-llvm-cov + + - name: Cache cargo + uses: Swatinem/rust-cache@v2 + with: + save-if: ${{ github.ref == 'refs/heads/main' }} + + - name: Generate coverage + run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info + + - name: Upload to Codecov + uses: codecov/codecov-action@v4 + with: + files: ./lcov.info + fail_ci_if_error: false + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/Cargo.lock b/Cargo.lock index aa451e7..db3939a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1806,7 +1806,7 @@ dependencies = [ [[package]] name = "masterror" -version = "0.24.18" +version = "0.24.19" dependencies = [ "actix-web", "anyhow",