A comprehensive template for AI-driven Rust development with full CI/CD pipeline support.
- Rust stable support: Works with Rust stable version
- Cross-platform testing: CI runs on Ubuntu, macOS, and Windows
- Comprehensive testing: Unit tests, integration tests, and doc tests
- Code quality: rustfmt + Clippy with pedantic lints
- Pre-commit hooks: Automated code quality checks before commits
- CI/CD pipeline: GitHub Actions with multi-platform support
- Changelog management: Fragment-based changelog (like Changesets/Scriv)
- Code coverage: Automated coverage reports with cargo-llvm-cov and Codecov
- Release automation: Automatic GitHub releases, crates.io publishing, post-publish smoke tests, and optional Docker Hub image publishing
- Template-safe defaults: CI/CD skips publishing when package name is
example-sum-package-name
- Click "Use this template" on GitHub to create a new repository
- Clone your new repository
- Update
Cargo.toml:- Change
namefromexample-sum-package-nameto your package name - Update
description,repository, anddocumentationURLs - Update
[lib]name and[[bin]]name
- Change
- Keep
Cargo.lockcommitted when the project has a binary target ([[bin]]orsrc/main.rs) - Update imports in
src/main.rs,tests/, andexamples/ - Build and start developing!
# Clone the repository
git clone https://github.com/link-foundation/rust-ai-driven-development-pipeline-template.git
cd rust-ai-driven-development-pipeline-template
# Build the project
cargo build
# Run tests
cargo test
# Run the CLI binary
cargo run -- --a 3 --b 7
# Run an example
cargo run --example basic_usage# Run all tests
cargo test
# Run tests with verbose output
cargo test --verbose
# Run doc tests
cargo test --doc
# Run a specific test
cargo test test_sum_positive_numbers
# Run tests with output
cargo test -- --nocaptureCI caps each test-matrix job at 10 minutes. cargo test does not provide a portable global per-test timeout, so long-running network, IO, or async tests should use explicit test-level timeouts. Repositories that adopt cargo nextest can configure runner deadlines with options such as --slow-timeout and --leak-timeout.
# Format code
cargo fmt
# Check formatting (CI style)
cargo fmt --check
# Run Clippy lints
cargo clippy --all-targets --all-features
# Check file size limits (requires rust-script: cargo install rust-script)
rust-script scripts/check-file-size.rs
# Check the packaged crate stays under the crates.io 10 MiB upload limit
rust-script scripts/check-crate-size.rs
# Run all checks
cargo fmt --check && cargo clippy --all-targets --all-features && rust-script scripts/check-file-size.rs.
βββ .github/
β βββ workflows/
β βββ release.yml # CI/CD pipeline configuration
βββ changelog.d/ # Changelog fragments
β βββ README.md # Fragment instructions
β βββ *.md # Individual changelog entries
βββ examples/
β βββ basic_usage.rs # Usage examples
βββ experiments/ # Experiment and debug scripts
β βββ test-changelog-parsing.rs # Changelog parsing validation
β βββ test-crates-io-check.rs # Crates.io version check validation
βββ scripts/ # Rust scripts (via rust-script)
β βββ bump-version.rs # Version bumping utility
β βββ check-changelog-fragment.rs # Changelog fragment validation
β βββ check-crate-size.rs # Crate archive size guard (crates.io 10 MiB limit)
β βββ check-file-size.rs # File size validation script
β βββ check-release-needed.rs # Release necessity check
β βββ check-version-modification.rs # Version modification detection
β βββ collect-changelog.rs # Changelog collection script
β βββ create-changelog-fragment.rs # Changelog fragment creation
β βββ create-github-release.rs # GitHub release creation
β βββ detect-code-changes.rs # Code change detection for CI
β βββ get-bump-type.rs # Version bump type determination
β βββ get-version.rs # Version extraction from Cargo.toml
β βββ git-config.rs # Git configuration for CI
β βββ publish-crate.rs # Crates.io publishing
β βββ release-naming.rs # Release tag/title/badge naming helpers
β βββ rust-paths.rs # Rust root path detection
β βββ smoke-test-published-crate.rs # Install/import/run smoke test for published crates
β βββ version-and-commit.rs # CI/CD version management
β βββ wait-for-crate.rs # Crates.io availability wait before image publishing
βββ src/
β βββ lib.rs # Library entry point
β βββ main.rs # CLI binary (uses lino-arguments)
β βββ sum.rs # Sum function module
βββ tests/
β βββ unit_tests.rs # Unit test entry point
β βββ unit/
β β βββ mod.rs
β β βββ sum.rs # Unit tests for sum function
β β βββ ci-cd/
β β βββ mod.rs
β β βββ changelog_parsing.rs # CI/CD changelog parsing tests
β βββ integration_tests.rs # Integration test entry point
β βββ integration/
β βββ mod.rs
β βββ sum.rs # CLI integration tests
βββ .gitignore # Git ignore patterns
βββ .pre-commit-config.yaml # Pre-commit hooks configuration
βββ Cargo.toml # Project configuration
βββ CHANGELOG.md # Project changelog
βββ CONTRIBUTING.md # Contribution guidelines
βββ LICENSE # Unlicense (public domain)
βββ README.md # This file
The template includes a simple CLI sum application using lino-arguments (a drop-in replacement for clap that also supports .lenv and .env files). This demonstrates:
- Library module (
src/sum.rs) with a pure function - CLI binary (
src/main.rs) usinglino-argumentsfor argument parsing - Unit tests (
tests/unit/sum.rs) testing the function directly - Integration tests (
tests/integration/sum.rs) testing the full CLI binary
- rustfmt: Standard Rust code formatter
- Clippy: Rust linter with pedantic and nursery lints enabled
- Pre-commit hooks: Automated checks before each commit
The template supports multiple levels of testing:
- Unit tests: In
tests/unit/directory, testing functions directly - Integration tests: In
tests/integration/directory, testing CLI binary - CI/CD tests: In
tests/unit/ci-cd/directory, testing CI/CD script logic - Doc tests: In documentation examples using
///comments - Examples: In
examples/directory (also serve as documentation)
Users can easily delete CI/CD tests in tests/unit/ci-cd/ if not needed.
This template uses a fragment-based changelog system similar to Changesets and Scriv.
# Create a changelog fragment
touch changelog.d/$(date +%Y%m%d_%H%M%S)_my_change.md
# Edit the fragment to document your changesThe GitHub Actions workflow provides:
- Change detection: Only runs relevant jobs based on changed files
- Changelog check: Validates changelog fragments on PRs with code changes
- Version check: Prevents manual version modification in PRs
- Linting: rustfmt and Clippy checks
- Test matrix: 3 OS (Ubuntu, macOS, Windows) with Rust stable
- Code coverage: cargo-llvm-cov with Codecov upload
- Building: Release build and package validation
- Auto release: Automatic releases when changelog fragments are merged to main
- Manual release: Workflow dispatch with version bump type selection
- Published crate smoke test: Installs the just-published crate from crates.io, runs CLI entry points with captured output, and compiles a fresh dependent crate against the library
- Optional Docker Hub publishing: Pushes
latestand version tags after the matching crates.io version is visible and smoke-tested - Documentation: Automatic docs deployment to GitHub Pages after release
Release scripts auto-detect the Rust layout with no extra configuration. A root Cargo.toml is treated as a single-language repository and keeps the plain v<version> tag plus <crate> <version> GitHub release title. A rust/Cargo.toml layout is treated as a multi-language monorepo and uses rust_v<version> tags plus [Rust] <version> titles so Rust releases do not collide with JavaScript or other language releases in the same GitHub Releases list.
GitHub release notes include a crates.io badge that links to the exact published version page, for example https://crates.io/crates/<crate>/<version>.
The default package name example-sum-package-name triggers skip logic in CI/CD scripts:
publish-crate.rsskips crates.io publishingsmoke-test-published-crate.rsskips install-from-package verificationcreate-github-release.rsskips GitHub release creation- Docker Hub publishing stays disabled unless
DOCKERHUB_IMAGEis configured and a rootDockerfileexists
Rename the package in Cargo.toml to enable full CI/CD publishing.
After creating a repository from this template:
-
Update
Cargo.toml:- Change
namefield fromexample-sum-package-name - Update
repositoryanddocumentationURLs - Change
[lib]name and[[bin]]name - Keep
Cargo.lockcommitted for executable crates
- Change
-
Update imports:
src/main.rstests/unit/sum.rstests/integration/sum.rsexamples/basic_usage.rs
-
Update badges in this
README.md
This template leaves Cargo.lock committed because it includes a CLI binary.
Downstream executable crates should do the same. The CI workflow runs
scripts/check-cargo-lock.rs and fails when a binary package has no
Cargo.lock committed at HEAD.
This prevents fresh dependency resolution from changing between CI runs. It also
keeps cargo cache keys deterministic: without a lockfile, GitHub Actions'
hashFiles('**/Cargo.lock') expression resolves to the same empty hash, so an
unpinned dependency graph can be cached and hide resolution drift.
If the guard fails, generate the lockfile and commit it:
cargo generate-lockfile
git add Cargo.lockProjects that ship a Docker image can publish Docker Hub releases from the same Rust release workflow. Add a root Dockerfile, then configure:
| Name | Type | Example | Purpose |
|---|---|---|---|
DOCKERHUB_IMAGE |
Repository variable | my-dockerhub-user/my-image |
Docker Hub repository to publish |
DOCKERHUB_USERNAME |
Repository variable or secret | my-dockerhub-user |
Docker Hub login username |
DOCKERHUB_TOKEN |
Repository secret | Docker Hub access token | Docker Hub login token |
When configured, the release workflow publishes both latest and the Cargo package version tag, for example my-dockerhub-user/my-image:0.10.0. Docker publishing runs only after crates.io reports the matching version as available, and release checks rerun missing Docker Hub or GitHub release artifacts without bumping the version again.
Add a visible Docker Hub badge next to the crates.io badge in repositories that enable image publishing:
[](https://hub.docker.com/r/my-dockerhub-user/my-image)The deploy-docs job in .github/workflows/release.yml publishes cargo doc --no-deps --all-features output to GitHub Pages on every push to main and on workflow_dispatch with release_mode == 'instant'. It adds a root index.html redirect to the generated crate documentation and a .nojekyll marker so rustdoc assets are served verbatim. It uses the official actions/configure-pages / actions/upload-pages-artifact / actions/deploy-pages flow, which requires the repository's Pages source to be set to GitHub Actions.
Before the first run on main, open Settings β Pages of the new repository and set Source = GitHub Actions. This is a one-time manual step and cannot be configured from a workflow. The deploy-docs job will then provision the Pages site on its first run.
If this step is skipped, the first deploy-docs run fails on actions/deploy-pages@v5 with Error: Get Pages site failed. / Error: Failed to create deployment. Flip the Pages source as described above and re-run the failed job; no workflow changes are required.
All scripts in scripts/ are Rust scripts that use rust-script.
Install rust-script with: cargo install rust-script
| Command | Description |
|---|---|
cargo test |
Run all tests |
cargo fmt |
Format code |
cargo clippy |
Run lints |
cargo run -- --a 3 --b 7 |
Run CLI (sum 3 + 7) |
cargo run --example basic_usage |
Run example |
rust-script scripts/check-cargo-lock.rs |
Require committed Cargo.lock for binary crates |
rust-script scripts/check-file-size.rs |
Check file size limits |
rust-script scripts/check-crate-size.rs |
Check crate archive size (crates.io 10 MiB limit) |
rust-script scripts/smoke-test-published-crate.rs --release-version <version> |
Verify the published crates.io artifact from a clean install |
rust-script scripts/bump-version.rs |
Bump version |
use example_sum_package_name::sum;
fn main() {
let result = sum(2, 3);
println!("2 + 3 = {result}");
}See examples/basic_usage.rs for more examples.
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Make your changes and add tests
- Run quality checks:
cargo fmt && cargo clippy && cargo test - Add a changelog fragment
- Commit your changes (pre-commit hooks will run automatically)
- Push and create a Pull Request
Unlicense - Public Domain
This is free and unencumbered software released into the public domain. See LICENSE for details.
Inspired by: