├── .github └── workflows │ ├── rust-release-plz.yml │ ├── rust-check.yml │ └── rust-test.yml └── README.md /.github/workflows/rust-release-plz.yml: -------------------------------------------------------------------------------- 1 | name: Release-plz 2 | # see https://release-plz.ieni.dev/docs/github 3 | # for more information 4 | 5 | permissions: 6 | pull-requests: write 7 | contents: write 8 | 9 | on: 10 | workflow_call: 11 | secrets: 12 | CARGO_REGISTRY_TOKEN: 13 | description: "Token to publish to crates.io" 14 | required: true 15 | 16 | jobs: 17 | release-plz: 18 | name: Release-plz 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@v4 23 | with: 24 | fetch-depth: 0 25 | - name: Install Rust stable 26 | uses: dtolnay/rust-toolchain@stable 27 | - name: Run release-plz 28 | uses: MarcoIeni/release-plz-action@v0.5 29 | env: 30 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 31 | CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} 32 | -------------------------------------------------------------------------------- /.github/workflows/rust-check.yml: -------------------------------------------------------------------------------- 1 | name: Check 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | msrv: 7 | description: "The minimal supported Rust version" 8 | required: false 9 | default: "1.56.1" # Rust 2021 edition release version 10 | type: string 11 | env: 12 | CARGO_TERM_COLOR: always 13 | 14 | # ensure that the workflow is only triggered once per PR, subsequent pushes to the PR will cancel 15 | # and restart the workflow. See https://docs.github.com/en/actions/using-jobs/using-concurrency 16 | concurrency: 17 | group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} 18 | cancel-in-progress: true 19 | 20 | jobs: 21 | fmt: 22 | name: stable / fmt 23 | runs-on: ubuntu-latest 24 | steps: 25 | - name: Checkout 26 | uses: actions/checkout@v4 27 | - name: Install Rust stable 28 | uses: dtolnay/rust-toolchain@stable 29 | with: 30 | components: rustfmt 31 | - name: Run cargo fmt 32 | run: cargo fmt -- --check 33 | - name: Cache Cargo dependencies 34 | uses: Swatinem/rust-cache@v2 35 | clippy: 36 | name: ${{ matrix.toolchain }} / clippy 37 | runs-on: ubuntu-latest 38 | permissions: 39 | checks: write 40 | strategy: 41 | fail-fast: false 42 | matrix: 43 | # Get early warnings about new lints introduced in the beta channel 44 | toolchain: [stable, beta] 45 | steps: 46 | - name: Checkout 47 | uses: actions/checkout@v4 48 | - name: Install Rust stable 49 | uses: dtolnay/rust-toolchain@stable 50 | with: 51 | components: clippy 52 | - name: Run clippy action 53 | uses: clechasseur/rs-clippy-check@v3 54 | - name: Cache Cargo dependencies 55 | uses: Swatinem/rust-cache@v2 56 | doc: 57 | # run docs generation on nightly rather than stable. This enables features like 58 | # https://doc.rust-lang.org/beta/unstable-book/language-features/doc-cfg.html which allows an 59 | # API be documented as only available in some specific platforms. 60 | name: nightly / doc 61 | runs-on: ubuntu-latest 62 | steps: 63 | - uses: actions/checkout@v4 64 | - name: Install Rust nightly 65 | uses: dtolnay/rust-toolchain@nightly 66 | - name: Run cargo doc 67 | run: cargo doc --no-deps --all-features 68 | env: 69 | RUSTDOCFLAGS: --cfg docsrs 70 | msrv: 71 | # check that we can build using the minimal rust version that is specified by this crate 72 | name: ${{ inputs.msrv }} / check 73 | runs-on: ubuntu-latest 74 | steps: 75 | - uses: actions/checkout@v4 76 | - name: Install ${{ inputs.msrv }} 77 | uses: dtolnay/rust-toolchain@master 78 | with: 79 | toolchain: ${{ inputs.msrv }} 80 | - name: cargo +${{ inputs.msrv }} check 81 | run: cargo check 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GitHub workflows 2 | 3 | This repository contains a collection of [reusable GitHub workflows] for use in Rust projects. 4 | 5 | - [rust-check](#rust-check) 6 | - [rust-release-plz](#rust-release-plz) 7 | - [rust-test](#rust-test) 8 | 9 | [reusable GitHub workflows]: https://docs.github.com/en/actions/using-workflows/reusing-workflows 10 | 11 | ## Usage 12 | 13 | - Fork this repo to your own user. 14 | - In your application or library crate, add 3 files pointing to your fork. 15 | - Copy the contents below and change the username (If you skip this step, any changes to this template will directly affect your builds). 16 | - .github/workflows/check.yml 17 | - .github/workflows/test.yml 18 | - .github/workflows/release-plz.yml 19 | - Follow the instructions on each of the workflows to set the right settings 20 | 21 | ## Rust Check 22 | 23 | [rust-check.yml](.github/workflows/rust-check.yml) 24 | 25 | - formatting using rustfmt 26 | - lints using clippy and [rs-clippy-check](https://github.com/marketplace/actions/rs-clippy-check) 27 | - docs (using nightly) 28 | - msrv 29 | 30 | ```yaml 31 | # .github/workflows/check.yml 32 | on: 33 | push: 34 | branches: 35 | - main 36 | pull_request: 37 | 38 | jobs: 39 | check: 40 | permissions: 41 | checks: write 42 | uses: joshka/github-workflows/.github/workflows/rust-check.yml@main 43 | with: 44 | msrv: 1.76.0 # this is optional defaults to 1.56.0 45 | ``` 46 | 47 | ## Rust Test 48 | 49 | [rust-test.yml](.github/workflows/rust-test.yml) 50 | 51 | Runs tests: 52 | 53 | - ubuntu with stable and beta 54 | - mac / windows with stable 55 | - minimal versions 56 | - upload coverage to codecov.io (requires CODECOV_TOKEN to be added to the repository secrets) 57 | 58 | ```yaml 59 | # .github/workflows/test.yml 60 | on: 61 | push: 62 | branches: 63 | - main 64 | pull_request: 65 | 66 | jobs: 67 | test: 68 | uses: joshka/github-workflows/.github/workflows/rust-test.yml@main 69 | with: 70 | crate_type: lib # (optional) change to bin to avoid running cargo test --doc 71 | secrets: 72 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 73 | ``` 74 | 75 | ## Rust Release-plz 76 | 77 | [rust-release-plz.yml](.github/workflows/rust-replease-plz.yml) 78 | 79 | Publishes the crate using [Release-plz]. This is pretty neat, it automatically creates or updates 80 | a release PR every time you push to main. Merging the PR automatically releases your crate. 81 | 82 | Required Settings: 83 | 84 | - `Settings | Actions | General | Allow GitHub Actions to create and approve pull requests`: \ 85 | ticked 86 | - `Settings | Secrets and Variables | Actions | Repository Secret | CARGO_REGISTRY_TOKEN`: \ 87 | set to value from 88 | 89 | [Release-plz]: https://release-plz.ieni.dev 90 | 91 | ```yaml 92 | # .github/workflows/release-plz.yml 93 | permissions: 94 | pull-requests: write 95 | contents: write 96 | 97 | on: 98 | push: 99 | branches: 100 | - main 101 | jobs: 102 | release-plz: 103 | uses: joshka/github-workflows/.github/workflows/rust-release-plz.yml@main 104 | permissions: 105 | pull-requests: write 106 | contents: write 107 | secrets: 108 | CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} 109 | ``` 110 | -------------------------------------------------------------------------------- /.github/workflows/rust-test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | # This is the main CI workflow that runs the test suite on all pushes to main and all pull requests. 4 | # It runs the following jobs: 5 | # - required: runs the test suite on ubuntu with stable and beta rust toolchains 6 | # - minimal: runs the test suite with the minimal versions of the dependencies that satisfy the 7 | # requirements of this crate, and its dependencies 8 | # - os-check: runs the test suite on mac and windows 9 | # - coverage: runs the test suite and collects coverage information 10 | # See check.yml for information about how the concurrency cancellation and workflow triggering works 11 | on: 12 | workflow_call: 13 | inputs: 14 | crate_type: 15 | description: "The type of crate to test (lib or bin)" 16 | required: false 17 | default: "lib" 18 | type: string 19 | secrets: 20 | CODECOV_TOKEN: 21 | description: "Token for codecov.io" 22 | required: true 23 | 24 | # ensure that the workflow is only triggered once per PR, subsequent pushes to the PR will cancel 25 | # and restart the workflow. See https://docs.github.com/en/actions/using-jobs/using-concurrency 26 | concurrency: 27 | group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} 28 | cancel-in-progress: true 29 | 30 | jobs: 31 | required: 32 | runs-on: ubuntu-latest 33 | name: ubuntu / ${{ matrix.toolchain }} 34 | strategy: 35 | matrix: 36 | # run on stable and beta to ensure that tests won't break on the next version of the rust 37 | # toolchain 38 | toolchain: [stable, beta] 39 | steps: 40 | - uses: actions/checkout@v4 41 | - name: Install ${{ matrix.toolchain }} 42 | uses: dtolnay/rust-toolchain@master 43 | with: 44 | toolchain: ${{ matrix.toolchain }} 45 | # enable this ci template to run regardless of whether the lockfile is checked in or not 46 | - name: cargo generate-lockfile 47 | if: hashFiles('Cargo.lock') == '' 48 | run: cargo generate-lockfile 49 | - name: cargo test --locked 50 | run: cargo test --locked --all-features --all-targets 51 | - name: cargo test --doc 52 | if: ${{ inputs.crate_type == 'lib' }} 53 | run: cargo test --locked --all-features --doc 54 | minimal-versions: 55 | # This action chooses the oldest version of the dependencies permitted by Cargo.toml to ensure 56 | # that this crate is compatible with the minimal version that this crate and its dependencies 57 | # require. This will pickup issues where this create relies on functionality that was introduced 58 | # later than the actual version specified (e.g., when we choose just a major version, but a 59 | # method was added after this version). 60 | # 61 | # This particular check can be difficult to get to succeed as often transitive dependencies may 62 | # be incorrectly specified (e.g., a dependency specifies 1.0 but really requires 1.1.5). There 63 | # is an alternative flag available -Zdirect-minimal-versions that uses the minimal versions for 64 | # direct dependencies of this crate, while selecting the maximal versions for the transitive 65 | # dependencies. Alternatively, you can add a line in your Cargo.toml to artificially increase 66 | # the minimal dependency, which you do with e.g.: 67 | # ```toml 68 | # # for minimal-versions 69 | # [target.'cfg(any())'.dependencies] 70 | # openssl = { version = "0.10.55", optional = true } # needed to allow foo to build with -Zminimal-versions 71 | # ``` 72 | # The optional = true is necessary in case that dependency isn't otherwise transitively required 73 | # by your library, and the target bit is so that this dependency edge never actually affects 74 | # Cargo build order. See also 75 | # https://github.com/jonhoo/fantoccini/blob/fde336472b712bc7ebf5b4e772023a7ba71b2262/Cargo.toml#L47-L49. 76 | # This action is run on ubuntu with the stable toolchain, as it is not expected to fail 77 | runs-on: ubuntu-latest 78 | name: ubuntu / stable / minimal-versions 79 | steps: 80 | - uses: actions/checkout@v4 81 | - name: Install Rust stable 82 | uses: dtolnay/rust-toolchain@stable 83 | - name: Install nightly for -Zdirect-minimal-versions 84 | uses: dtolnay/rust-toolchain@nightly 85 | - name: rustup default stable 86 | run: rustup default stable 87 | - name: cargo update -Zdirect-minimal-versions 88 | run: cargo +nightly update -Zdirect-minimal-versions 89 | - name: cargo test 90 | run: cargo test --locked --all-features --all-targets 91 | - name: Cache Cargo dependencies 92 | uses: Swatinem/rust-cache@v2 93 | os-check: 94 | # run cargo test on mac and windows 95 | runs-on: ${{ matrix.os }} 96 | name: ${{ matrix.os }} / stable 97 | strategy: 98 | fail-fast: false 99 | matrix: 100 | os: [macos-latest, windows-latest] 101 | steps: 102 | # if your project needs OpenSSL, uncomment this to fix Windows builds. 103 | # it's commented out by default as the install command takes 5-10m. 104 | # - run: echo "VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" | Out-File -FilePath $env:GITHUB_ENV -Append 105 | # if: runner.os == 'Windows' 106 | # - run: vcpkg install openssl:x64-windows-static-md 107 | # if: runner.os == 'Windows' 108 | - name: Checkout 109 | uses: actions/checkout@v4 110 | - name: Install Rust stable 111 | uses: dtolnay/rust-toolchain@stable 112 | - name: cargo generate-lockfile 113 | if: hashFiles('Cargo.lock') == '' 114 | run: cargo generate-lockfile 115 | - name: cargo test 116 | run: cargo test --locked --all-features --all-targets 117 | - name: Cache Cargo dependencies 118 | uses: Swatinem/rust-cache@v2 119 | coverage: 120 | # use llvm-cov to build and collect coverage and outputs in a format that 121 | # is compatible with codecov.io 122 | # 123 | # note that codecov as of v4 requires that CODECOV_TOKEN from 124 | # 125 | # https://app.codecov.io/gh///settings 126 | # 127 | # is set in two places on your repo: 128 | # 129 | # - https://github.com/jonhoo/guardian/settings/secrets/actions 130 | # - https://github.com/jonhoo/guardian/settings/secrets/dependabot 131 | # 132 | # (the former is needed for codecov uploads to work with Dependabot PRs) 133 | # 134 | # PRs coming from forks of your repo will not have access to the token, but 135 | # for those, codecov allows uploading coverage reports without a token. 136 | # it's all a little weird and inconvenient. see 137 | # 138 | # https://github.com/codecov/feedback/issues/112 139 | # 140 | # for lots of more discussion 141 | runs-on: ubuntu-latest 142 | name: ubuntu / stable / coverage 143 | steps: 144 | - name: Checkout 145 | uses: actions/checkout@v4 146 | - name: Install Rust stable 147 | uses: dtolnay/rust-toolchain@stable 148 | with: 149 | components: llvm-tools-preview 150 | - name: cargo install cargo-llvm-cov 151 | uses: taiki-e/install-action@cargo-llvm-cov 152 | - name: cargo generate-lockfile 153 | if: hashFiles('Cargo.lock') == '' 154 | run: cargo generate-lockfile 155 | - name: cargo llvm-cov 156 | run: cargo llvm-cov --locked --all-features --lcov --output-path lcov.info 157 | - name: Record Rust version 158 | run: echo "RUST=$(rustc --version)" >> "$GITHUB_ENV" 159 | - name: Cache Cargo dependencies 160 | uses: Swatinem/rust-cache@v2 161 | - name: Upload to codecov.io 162 | uses: codecov/codecov-action@v4 163 | with: 164 | fail_ci_if_error: true 165 | token: ${{ secrets.CODECOV_TOKEN }} 166 | env_vars: OS,RUST 167 | --------------------------------------------------------------------------------