An open API service indexing awesome lists of open source software.

https://github.com/followtheprocess/ci

Consistent, high quality, and configurable CI for various languages and ecosystems 🛠️
https://github.com/followtheprocess/ci

ci github-actions github-workflow go

Last synced: 10 months ago
JSON representation

Consistent, high quality, and configurable CI for various languages and ecosystems 🛠️

Awesome Lists containing this project

README

          

# CI

[![License](https://img.shields.io/github/license/FollowTheProcess/ci)](https://github.com/FollowTheProcess/ci)
[![GitHub](https://img.shields.io/github/v/release/FollowTheProcess/ci?logo=github&sort=semver)](https://github.com/FollowTheProcess/ci)

Consistent, high quality, and configurable CI for various languages and ecosystems 🛠️

- [CI](#ci)
- [Go](#go)
- [Inputs](#inputs)
- [Usage](#usage)
- [Rust](#rust)
- [Inputs](#inputs-1)
- [Usage](#usage-1)
- [Python](#python)
- [Inputs](#inputs-2)
- [Usage](#usage-2)
- [Zig](#zig)
- [Inputs](#inputs-3)
- [Usage](#usage-3)
- [Setting Environment Variables](#setting-environment-variables)

## Go

A great drop in CI pipeline for Go projects!

- Run tests with `go test` on linux, macos, and windows with the option to pass in additional flags as desired
- Race detector on by default
- Go version automatically detected from `go.mod`
- Uses [tparse] to output a nice test summary to `$GITHUB_STEP_SUMMARY` (with an option to disable)
- Optionally upload coverage reports to [CodeCov.io] (with tokenless upload)
- Linting with [golangci-lint] via the [golangci-lint-action], driven from your local `.golangci-lint.yml` config
- Check for typos with [typos-cli]
- Vulnerability analysis with [govulncheck]
- Automatically discover and run fuzz tests in a matrix with a configurable fuzz time

### Inputs

| name | description | type | required | default |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | -------- | ----------------------------------------------------- |
| `test-summary` |

Use https://github.com/mfridman/tparse to summarise test output to GITHUB_STEP_SUMMARY

| `boolean` | `false` | `true` |
| `test-flags` |

Additional flags to pass to go test. -race, -cover and -covermode are all already set. If test-summary is true, then the -json flag will be automatically set as well. But here you may pass -v for example or any other test flag.

| `string` | `false` | `""` |
| `matrix-os` |

List of operating systems to test on. Must be in pseudo-JSON array syntax e.g. '["ubuntu-latest", "windows-latest"]' etc.

| `string` | `false` | `["ubuntu-latest", "macos-latest", "windows-latest"]` |
| `fuzz` |

Automatically generate a matrix of fuzz tests and run them in parallel for a configurable fuzz-time. If there are no fuzz tests in the project, this is a no op so is a safe option to leave on.

| `boolean` | `false` | `true` |
| `fuzz-time` |

Time (in Go time.Duration format) to run each fuzz test for

| `string` | `false` | `1m` |
| `codecov` |

Send coverage data to CodeCov.io. Requires that tokenless uploading has been configured and is enabled.

| `boolean` | `false` | `true` |
| `golangci-lint-version` |

The version of golangci-lint to use

| `string` | `false` | `latest` |
| `timeout-minutes` |

Maximum number of minutes to let each step execute for, will be cancelled when timeout is met.

| `number` | `false` | `15` |
| `working-directory` |

The working directory to be in for the entire workflow

| `string` | `false` | `.` |
| `env` |

JSON string of an object containing environment variables to set for the whole workflow

| `string` | `false` | `{}` |

### Usage

```yaml
jobs:
job1:
uses: FollowTheProcess/ci/.github/workflows/Go.yml@v1
with:
test-summary:
# Use https://github.com/mfridman/tparse to summarise test output to `GITHUB_STEP_SUMMARY`
#
# Type: boolean
# Required: false
# Default: true

test-flags:
# Additional flags to pass to `go test`. `-race`, `-cover` and `-covermode` are all already set. If `test-summary` is true, then the `-json` flag will be automatically set as well. But here you may pass `-v` for example or any other test flag.
#
# Type: string
# Required: false
# Default: ""

matrix-os:
# List of operating systems to test on. Must be in pseudo-JSON array syntax e.g. `'["ubuntu-latest", "windows-latest"]'` etc.
#
# Type: string
# Required: false
# Default: ["ubuntu-latest", "macos-latest", "windows-latest"]

fuzz:
# Automatically generate a matrix of fuzz tests and run them in parallel for a configurable `fuzz-time`. If there are no fuzz tests in the project, this is a no op so is a safe option to leave on.
#
# Type: boolean
# Required: false
# Default: true

fuzz-time:
# Time (in Go `time.Duration` format) to run each fuzz test for
#
# Type: string
# Required: false
# Default: 1m

codecov:
# Send coverage data to CodeCov.io. Requires that tokenless uploading has been configured and is enabled.
#
# Type: boolean
# Required: false
# Default: true

golangci-lint-version:
# The version of golangci-lint to use
#
# Type: string
# Required: false
# Default: latest

timeout-minutes:
# Maximum number of minutes to let each step execute for, will be cancelled when timeout is met.
#
# Type: number
# Required: false
# Default: 15

working-directory:
# The working directory to be in for the entire workflow
#
# Type: string
# Required: false
# Default: .

env:
# JSON string of an object containing environment variables to set for the whole workflow
#
# Type: string
# Required: false
# Default: {}
```

## Rust

Rust CI can get complex, but this is a great simple CI flow for most crates

- Tests run on all 3 major OS's (ubuntu, macos, windows)
- Configurable rust [toolchain] via [rustup]
- Optionally use [nextest] as the test runner
- Dependency caching
- Linting with [clippy] and format checks with rustfmt
- Check for typos with [typos-cli]

### Inputs

| name | description | type | required | default |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | -------- | ----------------------------------------------------- |
| `toolchain` |

The rust toolchain to install e.g "stable", "nightly" etc. any rustup toolchain expression is supported, see https://rust-lang.github.io/rustup/concepts/toolchains.html

| `string` | `false` | `stable` |
| `matrix-os` |

List of operating systems to test on. Must be in pseudo-JSON array syntax e.g. '["ubuntu-latest", "windows-latest"]' etc.

| `string` | `false` | `["ubuntu-latest", "macos-latest", "windows-latest"]` |
| `nextest` |

Use cargo nextest as the test runner, instead of cargo test. If true, doctests will be run as a separate step with cargo test as nextest does not yet support them

| `boolean` | `false` | `false` |
| `nextest-profile` |

Name of the nextest profile to use for cargo nextest. Only has any effect if using nextest as the test runner

| `string` | `false` | `default` |
| `rustflags` |

Value of the RUSTFLAGS env var

| `string` | `false` | `--deny warnings` |
| `test-flags` |

Command line flags to pass to cargo test (or cargo nextest run if using nextest). --locked is used regardless.

| `string` | `false` | `--all-targets --all-features` |
| `timeout-minutes` |

Maximum number of minutes to let each step execute for, will be cancelled when timeout is met.

| `number` | `false` | `15` |
| `working-directory` |

The working directory to be in for the entire workflow

| `string` | `false` | `.` |
| `env` |

JSON string of an object containing environment variables to set for the whole workflow

| `string` | `false` | `{}` |

### Usage

```yaml
jobs:
job1:
uses: FollowTheProcess/ci/.github/workflows/Rust.yml@v1
with:
toolchain:
# The rust toolchain to install e.g "stable", "nightly" etc. any rustup toolchain expression is supported, see https://rust-lang.github.io/rustup/concepts/toolchains.html
#
# Type: string
# Required: false
# Default: stable

matrix-os:
# List of operating systems to test on. Must be in pseudo-JSON array syntax e.g. `'["ubuntu-latest", "windows-latest"]'` etc.
#
# Type: string
# Required: false
# Default: ["ubuntu-latest", "macos-latest", "windows-latest"]

nextest:
# Use `cargo nextest` as the test runner, instead of `cargo test`. If true, doctests will be run as a separate step with `cargo test` as nextest does not yet support them
#
# Type: boolean
# Required: false
# Default: false

nextest-profile:
# Name of the nextest profile to use for `cargo nextest`. Only has any effect if using nextest as the test runner
#
# Type: string
# Required: false
# Default: default

rustflags:
# Value of the `RUSTFLAGS` env var
#
# Type: string
# Required: false
# Default: --deny warnings

test-flags:
# Command line flags to pass to `cargo test` (or `cargo nextest run` if using nextest). `--locked` is used regardless.
#
# Type: string
# Required: false
# Default: --all-targets --all-features

timeout-minutes:
# Maximum number of minutes to let each step execute for, will be cancelled when timeout is met.
#
# Type: number
# Required: false
# Default: 15

working-directory:
# The working directory to be in for the entire workflow
#
# Type: string
# Required: false
# Default: .

env:
# JSON string of an object containing environment variables to set for the whole workflow
#
# Type: string
# Required: false
# Default: {}
```

## Python

A simple but effective CI pipeline for python packages and projects

- Tests run on all 3 major OS's (ubuntu, macos, windows) with [pytest]
- Configurable matrix of python versions to multiply by the OS matrix for complete coverage
- Dependency caching
- Optionally upload coverage reports to [CodeCov.io] (with tokenless upload)
- Linting and format checks with [ruff]
- Type checking with [MyPy] and/or [Pyright] (they can be combined!)
- Check for typos with [typos-cli]

> [!NOTE]
> The python workflow uses [uv] but should work with any [PEP-621] compliant `pyproject.toml`

### Inputs

| name | description | type | required | default |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | -------- | ----------------------------------------------------- |
| `python-version` |

The version of python to use as the project default, overrides python-version-file. Defaults to reading from python-version-file.

| `string` | `false` | `""` |
| `python-version-file` |

File to use to detect default python version, can be a PEP621 compliant pyproject.toml, or a .python-version file. If python-version is specified, this is ignored.

| `string` | `false` | `pyproject.toml` |
| `matrix-python-versions` |

List of python versions to test against in the matrix. Must be in pseudo-JSON array syntax e.g. '["3.12", "3.13"]' etc.

| `string` | `false` | `["3.10", "3.11", "3.12", "3.13"]` |
| `matrix-os` |

List of operating systems to test on. Must be in pseudo-JSON array syntax e.g. '["ubuntu-latest", "windows-latest"]' etc.

| `string` | `false` | `["ubuntu-latest", "macos-latest", "windows-latest"]` |
| `codecov` |

Send coverage data to CodeCov.io. Requires that tokenless uploading has been configured and is enabled.

| `boolean` | `false` | `true` |
| `uv-version` |

The version of uv to install

| `string` | `false` | `latest` |
| `ruff-version` |

The version of ruff to use for formatting and linting

| `string` | `false` | `latest` |
| `mypy` |

Use the mypy type checker for the type check step, it is expected to be a dev dependency and have config inside pyproject.toml

| `boolean` | `false` | `true` |
| `pyright` |

Use the pyright type checker for the type check step, can be combined with mypy, it is expected to be a dev dependency and have config inside pyproject.toml

| `boolean` | `false` | `false` |
| `pytest-flags` |

Command line flags to pass to pytest e.g. --cov, --cov-report etc.

| `string` | `false` | `""` |
| `timeout-minutes` |

Maximum number of minutes to let each step execute for, will be cancelled when timeout is met.

| `number` | `false` | `15` |
| `working-directory` |

The working directory to be in for the entire workflow

| `string` | `false` | `.` |
| `env` |

JSON string of an object containing environment variables to set for the whole workflow

| `string` | `false` | `{}` |

### Usage

```yaml
jobs:
job1:
uses: FollowTheProcess/ci/.github/workflows/Python.yml@v1
with:
python-version:
# The version of python to use as the project default, overrides `python-version-file`. Defaults to reading from `python-version-file`.
#
# Type: string
# Required: false
# Default: ""

python-version-file:
# File to use to detect default python version, can be a PEP621 compliant pyproject.toml, or a `.python-version` file. If `python-version` is specified, this is ignored.
#
# Type: string
# Required: false
# Default: pyproject.toml

matrix-python-versions:
# List of python versions to test against in the matrix. Must be in pseudo-JSON array syntax e.g. `'["3.12", "3.13"]'` etc.
#
# Type: string
# Required: false
# Default: ["3.10", "3.11", "3.12", "3.13"]

matrix-os:
# List of operating systems to test on. Must be in pseudo-JSON array syntax e.g. `'["ubuntu-latest", "windows-latest"]'` etc.
#
# Type: string
# Required: false
# Default: ["ubuntu-latest", "macos-latest", "windows-latest"]

codecov:
# Send coverage data to CodeCov.io. Requires that tokenless uploading has been configured and is enabled.
#
# Type: boolean
# Required: false
# Default: true

uv-version:
# The version of uv to install
#
# Type: string
# Required: false
# Default: latest

ruff-version:
# The version of ruff to use for formatting and linting
#
# Type: string
# Required: false
# Default: latest

mypy:
# Use the mypy type checker for the type check step, it is expected to be a dev dependency and have config inside pyproject.toml
#
# Type: boolean
# Required: false
# Default: true

pyright:
# Use the pyright type checker for the type check step, can be combined with mypy, it is expected to be a dev dependency and have config inside pyproject.toml
#
# Type: boolean
# Required: false
# Default: false

pytest-flags:
# Command line flags to pass to pytest e.g. `--cov`, `--cov-report` etc.
#
# Type: string
# Required: false
# Default: ""

timeout-minutes:
# Maximum number of minutes to let each step execute for, will be cancelled when timeout is met.
#
# Type: number
# Required: false
# Default: 15

working-directory:
# The working directory to be in for the entire workflow
#
# Type: string
# Required: false
# Default: .

env:
# JSON string of an object containing environment variables to set for the whole workflow
#
# Type: string
# Required: false
# Default: {}
```

## Zig

Zig doesn't have much in the way of linting etc. at the moment, but this is a simple test pipeline

- Tests run on all 3 major OS's (macos, linux, windows)
- Zig build caching
- Configurable `zig build` flags
- Check for typos with [typos-cli]

> [!WARNING]
> I don't do much Zig yet, so this might not be very thorough but hopefully I can adjust/improve as I spend more time with the language/tooling

### Inputs

| name | description | type | required | default |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -------- | ----------------------------------------------------- |
| `zig-version` |

The zig version to install, can be a stable version e.g. "0.13.0", a specific nightly e.g. "0.14.0-dev.2+0884a4341", "master" for latest nightly build, or "latest" for latest stable

| `string` | `false` | `latest` |
| `matrix-os` |

List of operating systems to test on. Must be in pseudo-JSON array syntax e.g. '["ubuntu-latest", "windows-latest"]' etc.

| `string` | `false` | `["ubuntu-latest", "macos-latest", "windows-latest"]` |
| `build-flags` |

User flags to pass to zig build e.g. "-Dmy-flag=value"

| `string` | `false` | `""` |
| `timeout-minutes` |

Maximum number of minutes to let each step execute for, will be cancelled when timeout is met.

| `number` | `false` | `15` |
| `working-directory` |

The working directory to be in for the entire workflow

| `string` | `false` | `.` |
| `env` |

JSON string of an object containing environment variables to set for the whole workflow

| `string` | `false` | `{}` |

### Usage

```yaml
jobs:
job1:
uses: FollowTheProcess/ci/.github/workflows/Zig.yml@v1
with:
zig-version:
# The zig version to install, can be a stable version e.g. "0.13.0", a specific nightly e.g. "0.14.0-dev.2+0884a4341", "master" for latest nightly build, or "latest" for latest stable
#
# Type: string
# Required: false
# Default: latest

matrix-os:
# List of operating systems to test on. Must be in pseudo-JSON array syntax e.g. `'["ubuntu-latest", "windows-latest"]'` etc.
#
# Type: string
# Required: false
# Default: ["ubuntu-latest", "macos-latest", "windows-latest"]

build-flags:
# User flags to pass to `zig build` e.g. "-Dmy-flag=value"
#
# Type: string
# Required: false
# Default: ""

timeout-minutes:
# Maximum number of minutes to let each step execute for, will be cancelled when timeout is met.
#
# Type: number
# Required: false
# Default: 15

working-directory:
# The working directory to be in for the entire workflow
#
# Type: string
# Required: false
# Default: .

env:
# JSON string of an object containing environment variables to set for the whole workflow
#
# Type: string
# Required: false
# Default: {}
```

## Setting Environment Variables

GitHub unfortunately doesn't let you pass environment variables directly to reusable workflows, so I've implemented a workaround in each of the workflows. You pass a JSON string containing a map of env var name to intended value, and this is parsed and set for you inside each workflow. Like so...

```yaml
jobs:
ci:
name: CI
permissions:
contents: read
uses: FollowTheProcess/ci/.github/workflows/Go.yml@v1
with:
env: '{"NO_COLOR": "true"}' # Here we set the $NO_COLOR env var
```

[tparse]: https://github.com/mfridman/tparse
[CodeCov.io]: https://about.codecov.io/
[golangci-lint]: https://golangci-lint.run/
[golangci-lint-action]: https://github.com/golangci/golangci-lint-action
[govulncheck]: https://go.dev/blog/vuln
[typos-cli]: https://github.com/crate-ci/typos
[toolchain]: https://rust-lang.github.io/rustup/concepts/toolchains.html
[rustup]: https://github.com/rust-lang/rustup
[clippy]: https://doc.rust-lang.org/clippy/
[nextest]: https://nexte.st/
[uv]: https://docs.astral.sh/uv/
[PEP-621]: https://peps.python.org/pep-0621/
[ruff]: https://docs.astral.sh/ruff/
[mypy]: https://github.com/python/mypy
[pyright]: https://microsoft.github.io/pyright/#/
[pytest]: https://docs.pytest.org/en/stable/