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 🛠️
- Host: GitHub
- URL: https://github.com/followtheprocess/ci
- Owner: FollowTheProcess
- License: mit
- Created: 2025-01-08T08:25:08.000Z (12 months ago)
- Default Branch: main
- Last Pushed: 2025-02-17T16:17:26.000Z (10 months ago)
- Last Synced: 2025-02-17T17:28:55.181Z (10 months ago)
- Topics: ci, github-actions, github-workflow, go
- Language: Python
- Homepage:
- Size: 63.5 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# CI
[](https://github.com/FollowTheProcess/ci)
[](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/