From b8f1fb1a0b87024aea7be9bc4dc745a4e784e0ec Mon Sep 17 00:00:00 2001 From: Josh McKinney Date: Tue, 2 Apr 2024 22:40:32 -0700 Subject: [PATCH] ci: add dependabot and ci workflow configuration Sets up a standard set of CI workflows to automatically build, test, and pubish the crate (using release-plz). Also adds a dependabot configuration to automatically update dependencies. This is mostly a copy of the workflows I use in my own projects, without the msrv check, as I don't think that's necessary for this crate. See https://github.com/joshka/github-workflows/ for more information. With the release-plz workflow, anytime you push to main, it will create a PR with the new version number and changelog. You can then merge this PR to publish the new version to crates.io. See https://github.com/joshka/tui-scrollview/pull/25 for an example of what this looks like. --- .github/dependabot.yml | 12 ++ .github/workflows/rust-check.yml | 67 +++++++++++ .github/workflows/rust-release-plz.yml | 30 +++++ .github/workflows/rust-test.yml | 157 +++++++++++++++++++++++++ 4 files changed, 266 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/rust-check.yml create mode 100644 .github/workflows/rust-release-plz.yml create mode 100644 .github/workflows/rust-test.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..de3743d --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "cargo" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/rust-check.yml b/.github/workflows/rust-check.yml new file mode 100644 index 0000000..9d4b8a6 --- /dev/null +++ b/.github/workflows/rust-check.yml @@ -0,0 +1,67 @@ +name: Check + +on: + push: + branches: + - main + pull_request: + +env: + CARGO_TERM_COLOR: always + +# ensure that the workflow is only triggered once per PR, subsequent pushes to the PR will cancel +# and restart the workflow. See https://docs.github.com/en/actions/using-jobs/using-concurrency +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + fmt: + name: stable / fmt + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt + - name: Run cargo fmt + run: cargo fmt -- --check + - name: Cache Cargo dependencies + uses: Swatinem/rust-cache@v2 + clippy: + name: ${{ matrix.toolchain }} / clippy + runs-on: ubuntu-latest + permissions: + checks: write + strategy: + fail-fast: false + matrix: + # Get early warnings about new lints introduced in the beta channel + toolchain: [stable, beta] + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + with: + components: clippy + - name: Run clippy action + uses: clechasseur/rs-clippy-check@v3 + - name: Cache Cargo dependencies + uses: Swatinem/rust-cache@v2 + doc: + # run docs generation on nightly rather than stable. This enables features like + # https://doc.rust-lang.org/beta/unstable-book/language-features/doc-cfg.html which allows an + # API be documented as only available in some specific platforms. + name: nightly / doc + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install Rust nightly + uses: dtolnay/rust-toolchain@nightly + - name: Run cargo doc + run: cargo doc --no-deps --all-features + env: + RUSTDOCFLAGS: --cfg docsrs diff --git a/.github/workflows/rust-release-plz.yml b/.github/workflows/rust-release-plz.yml new file mode 100644 index 0000000..7207ade --- /dev/null +++ b/.github/workflows/rust-release-plz.yml @@ -0,0 +1,30 @@ +name: Release-plz +# see https://release-plz.ieni.dev/docs/github +# for more information + +permissions: + pull-requests: write + contents: write + +on: + push: + branches: + - main + pull_request: + +jobs: + release-plz: + name: Release-plz + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + - name: Run release-plz + uses: MarcoIeni/release-plz-action@v0.5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} diff --git a/.github/workflows/rust-test.yml b/.github/workflows/rust-test.yml new file mode 100644 index 0000000..7448dc5 --- /dev/null +++ b/.github/workflows/rust-test.yml @@ -0,0 +1,157 @@ +name: Test + +# This is the main CI workflow that runs the test suite on all pushes to main and all pull requests. +# It runs the following jobs: +# - required: runs the test suite on ubuntu with stable and beta rust toolchains +# - minimal: runs the test suite with the minimal versions of the dependencies that satisfy the +# requirements of this crate, and its dependencies +# - os-check: runs the test suite on mac and windows +# - coverage: runs the test suite and collects coverage information +on: + push: + branches: + - main + pull_request: + +# ensure that the workflow is only triggered once per PR, subsequent pushes to the PR will cancel +# and restart the workflow. See https://docs.github.com/en/actions/using-jobs/using-concurrency +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + required: + runs-on: ubuntu-latest + name: ubuntu / ${{ matrix.toolchain }} + strategy: + matrix: + # run on stable and beta to ensure that tests won't break on the next version of the rust + # toolchain + toolchain: [stable, beta] + steps: + - uses: actions/checkout@v4 + - name: Install ${{ matrix.toolchain }} + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.toolchain }} + # enable this ci template to run regardless of whether the lockfile is checked in or not + - name: cargo generate-lockfile + if: hashFiles('Cargo.lock') == '' + run: cargo generate-lockfile + - name: cargo test --locked + run: cargo test --locked --all-features --all-targets + - name: cargo test --doc + run: cargo test --locked --all-features --doc + minimal-versions: + # This action chooses the oldest version of the dependencies permitted by Cargo.toml to ensure + # that this crate is compatible with the minimal version that this crate and its dependencies + # require. This will pickup issues where this create relies on functionality that was introduced + # later than the actual version specified (e.g., when we choose just a major version, but a + # method was added after this version). + # + # This particular check can be difficult to get to succeed as often transitive dependencies may + # be incorrectly specified (e.g., a dependency specifies 1.0 but really requires 1.1.5). There + # is an alternative flag available -Zdirect-minimal-versions that uses the minimal versions for + # direct dependencies of this crate, while selecting the maximal versions for the transitive + # dependencies. Alternatively, you can add a line in your Cargo.toml to artificially increase + # the minimal dependency, which you do with e.g.: + # ```toml + # # for minimal-versions + # [target.'cfg(any())'.dependencies] + # openssl = { version = "0.10.55", optional = true } # needed to allow foo to build with -Zminimal-versions + # ``` + # The optional = true is necessary in case that dependency isn't otherwise transitively required + # by your library, and the target bit is so that this dependency edge never actually affects + # Cargo build order. See also + # https://github.com/jonhoo/fantoccini/blob/fde336472b712bc7ebf5b4e772023a7ba71b2262/Cargo.toml#L47-L49. + # This action is run on ubuntu with the stable toolchain, as it is not expected to fail + runs-on: ubuntu-latest + name: ubuntu / stable / minimal-versions + steps: + - uses: actions/checkout@v4 + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + - name: Install nightly for -Zdirect-minimal-versions + uses: dtolnay/rust-toolchain@nightly + - name: rustup default stable + run: rustup default stable + - name: cargo update -Zdirect-minimal-versions + run: cargo +nightly update -Zdirect-minimal-versions + - name: cargo test + run: cargo test --locked --all-features --all-targets + - name: Cache Cargo dependencies + uses: Swatinem/rust-cache@v2 + os-check: + # run cargo test on mac and windows + runs-on: ${{ matrix.os }} + name: ${{ matrix.os }} / stable + strategy: + fail-fast: false + matrix: + os: [macos-latest, windows-latest] + steps: + # if your project needs OpenSSL, uncomment this to fix Windows builds. + # it's commented out by default as the install command takes 5-10m. + # - run: echo "VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" | Out-File -FilePath $env:GITHUB_ENV -Append + # if: runner.os == 'Windows' + # - run: vcpkg install openssl:x64-windows-static-md + # if: runner.os == 'Windows' + - name: Checkout + uses: actions/checkout@v4 + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + - name: cargo generate-lockfile + if: hashFiles('Cargo.lock') == '' + run: cargo generate-lockfile + - name: cargo test + run: cargo test --locked --all-features --all-targets + - name: Cache Cargo dependencies + uses: Swatinem/rust-cache@v2 + coverage: + # use llvm-cov to build and collect coverage and outputs in a format that + # is compatible with codecov.io + # + # note that codecov as of v4 requires that CODECOV_TOKEN from + # + # https://app.codecov.io/gh///settings + # + # is set in two places on your repo: + # + # - https://github.com/jonhoo/guardian/settings/secrets/actions + # - https://github.com/jonhoo/guardian/settings/secrets/dependabot + # + # (the former is needed for codecov uploads to work with Dependabot PRs) + # + # PRs coming from forks of your repo will not have access to the token, but + # for those, codecov allows uploading coverage reports without a token. + # it's all a little weird and inconvenient. see + # + # https://github.com/codecov/feedback/issues/112 + # + # for lots of more discussion + runs-on: ubuntu-latest + name: ubuntu / stable / coverage + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + with: + components: llvm-tools-preview + - name: cargo install cargo-llvm-cov + uses: taiki-e/install-action@cargo-llvm-cov + - name: cargo generate-lockfile + if: hashFiles('Cargo.lock') == '' + run: cargo generate-lockfile + - name: cargo llvm-cov + run: cargo llvm-cov --locked --all-features --lcov --output-path lcov.info + - name: Record Rust version + run: echo "RUST=$(rustc --version)" >> "$GITHUB_ENV" + - name: Cache Cargo dependencies + uses: Swatinem/rust-cache@v2 + - name: Upload to codecov.io + uses: codecov/codecov-action@v4 + with: + fail_ci_if_error: true + token: ${{ secrets.CODECOV_TOKEN }} + env_vars: OS,RUST