Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
aa5569a
Document template agent workflow
leynos May 23, 2026
60063ab
Import Rust template tooling
leynos May 23, 2026
5b743a9
Record tooling import progress
leynos May 23, 2026
2993b19
Record final template validation
leynos May 23, 2026
3b94065
Record draft PR handoff
leynos May 23, 2026
ca44b42
Remove unsupported parent CI gates
leynos May 23, 2026
a16f3e2
Run parent template tests in CI
leynos May 24, 2026
6bbe943
Fix pytest-copier CI template fixture
leynos May 24, 2026
6ccafb8
Document pytest-copier fixture scope
leynos May 24, 2026
b57045a
Install CI template test dependencies
leynos May 24, 2026
035d1cb
Pin workflow actions and clarify template tests
leynos May 24, 2026
da72c32
Restore generated test fallback coverage
leynos May 24, 2026
2ee870f
Document binstall template placeholders
leynos May 24, 2026
23a38b3
Clarify generated coverage linker policy
leynos May 24, 2026
2648557
Update ExecPlan branch status note
leynos May 24, 2026
ed8a026
Fix AGENTS test log command example
leynos May 24, 2026
2d2e8a8
Remove unsupported Windows ARM release target
leynos May 24, 2026
f4f7b43
Disable parent checkout credential persistence
leynos May 24, 2026
4997428
Address template review check failures
leynos May 24, 2026
4369d14
Harden generated template contracts
leynos May 24, 2026
54b91a2
Test generated Whitaker fallback resolution
leynos May 24, 2026
08d47ad
Tighten generated tooling contract tests
leynos May 24, 2026
85f4c1d
Clarify Copier prompt meanings in user guide
leynos May 24, 2026
a436991
Harden generated tooling verification
leynos May 24, 2026
9985d28
Document release workflow toolchain overrides
leynos May 24, 2026
7388745
Clarify snapshot and lint test diagnostics
leynos May 24, 2026
74e42d8
Tighten generated tooling review fixes
leynos May 24, 2026
3e5ccf0
Format developer tooling names
leynos May 24, 2026
e5722cd
Share checkout step extraction in tests
leynos May 24, 2026
f788402
Split generated tooling contract assertions
leynos May 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 43 additions & 20 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,49 @@ jobs:
env:
CARGO_TERM_COLOR: always
BUILD_PROFILE: debug
WHITAKER_INSTALLER_REV: f768c2e53c47df13658af1168a67851d388750bf
steps:
- uses: actions/checkout@v5
- name: Setup Rust
uses: leynos/shared-actions/.github/actions/setup-rust@854baf3f4cb322d48ceececb22d4ea72fd4f84d0
- name: Format
run: make check-fmt
- name: Lint
run: make lint
- name: Test and Measure Coverage
uses: leynos/shared-actions/.github/actions/generate-coverage@854baf3f4cb322d48ceececb22d4ea72fd4f84d0
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd
Comment thread
coderabbitai[bot] marked this conversation as resolved.
with:
output-path: lcov.info
format: lcov
- name: Upload coverage data to CodeScene
env:
CS_ACCESS_TOKEN: ${{ secrets.CS_ACCESS_TOKEN }}
if: ${{ env.CS_ACCESS_TOKEN }}
uses: leynos/shared-actions/.github/actions/upload-codescene-coverage@854baf3f4cb322d48ceececb22d4ea72fd4f84d0

persist-credentials: false
- name: Setup Rust
uses: leynos/shared-actions/.github/actions/setup-rust@e4c6b0e200a057edf927c45c298e7ddf229b3934
- name: Install mold linker
if: runner.os == 'Linux'
run: |
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
sudo apt-get update \
&& sudo apt-get install --yes --no-install-recommends clang lld mold
- name: Setup uv
uses: astral-sh/setup-uv@12d13f90bc3a5a1971bebad4beb09a4dfa962e91
- name: Install template test tools
run: |
set -euo pipefail
cargo binstall --no-confirm cargo-nextest
uv tool install mbake
- name: Cache Whitaker installation
id: cache-whitaker
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae
with:
format: lcov
access-token: ${{ env.CS_ACCESS_TOKEN }}
installer-checksum: ${{ vars.CODESCENE_CLI_SHA256 }}
path: |
~/.cargo/bin/whitaker-installer
~/.local/bin/whitaker
~/.dylint_drivers
~/.local/share/whitaker
key: whitaker-v2-${{ runner.os }}-${{ env.WHITAKER_INSTALLER_REV }}
- name: Install Whitaker
run: |
set -euo pipefail
echo "Whitaker cache hit: ${{ steps.cache-whitaker.outputs.cache-hit }}"
if [ "${{ steps.cache-whitaker.outputs.cache-hit }}" != "true" ]; then
echo "Installing Whitaker installer at ${WHITAKER_INSTALLER_REV}"
cargo install --locked \
--git https://github.com/leynos/whitaker \
--rev "${WHITAKER_INSTALLER_REV}" \
whitaker-installer
fi
whitaker-installer --cranelift
echo "Whitaker binary: $(command -v whitaker || true)"
- name: Test
run: make test
2 changes: 1 addition & 1 deletion .github/workflows/delayed-pr-comment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
run: sleep ${{ steps.calc.outputs.secs }}
shell: bash
- name: Comment PR
uses: thollander/actions-comment-pull-request@v3
uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b
with:
pr-number: ${{ github.event.inputs.pr_number }}
message: ${{ github.event.inputs.message }}
61 changes: 61 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Agent Instructions

## Repository Purpose

This repository is a Copier template for generating Rust projects. It is not
itself the generated Rust project. Files under `template/` are copied or
rendered into downstream projects, and files under `tests/` validate the
template output through `pytest-copier`.

When changing generated Rust project behaviour, update the template files and
the parent repository tests that prove the rendered output. Prefer assertions
against the generated project's public commands, such as `make all`, over
testing private implementation details in the parent repository.

## Copier Test Dependencies

Template tests use `pytest` and `pytest-copier`. Install or run them through
`uv` so the parent repository does not need a manually managed virtual
environment.

See `docs/users-guide.md` for generated-project features and
`docs/developers-guide.md` for parent-template tooling requirements.

The repository Makefile exposes the expected entrypoint:

```sh
make test
```

That target currently runs:

```sh
uvx --with pytest-copier pytest tests/
```

If tests import additional pytest plugins or assertion helpers, add them to
the `uvx --with ...` invocation or to the documented dependency list before
using them in tests. Do not rely on packages installed in an ambient shell
environment.

When debugging generated projects manually, render with Copier into a temporary
directory, then run the generated project's public gates from that rendered
directory. Keep build output in the rendered project or Cargo's default shared
cache; do not configure an isolated Cargo cache.

## Validation

Run parent-template tests after changing `copier.yaml`, `template/`, or
`tests/`:

```sh
make test
```

For long test runs, capture output with `tee` into `/tmp`, for example:

```sh
make test 2>&1 | tee /tmp/test-agent-template-rust-$(git branch --show-current).out
```

Review the log before committing if the terminal output is truncated.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.PHONY: test

test: ## Run template tests
uvx --with pytest-copier pytest tests/
uvx --with pytest-copier --with pyyaml --with syrupy pytest tests/

help: ## Show available targets
@grep -E '^[a-zA-Z_-]+:.*?##' $(MAKEFILE_LIST) | \
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ The template requires **Copier 9.0** or later to avoid incompatibilities.
enabled【F:template/Cargo.toml†L1-L9】.
- **Pinned toolchain** file specifying a configurable nightly release
【F:template/rust-toolchain.toml.jinja†L1-L3】.
- **Project metadata prompts** for repository URL, homepage, crates.io keywords,
crates.io categories, nightly date, and optional Linux development target.
- **Fast generated tooling** including Cranelift debug code generation, Linux
mold linking for development builds, cargo-nextest tests with a cargo-test
fallback, Whitaker linting, and a lld-backed coverage target.
- **Starter code** providing either a binary entry point or a library
function depending on flavour【F:template/src/{% if flavour == APP %}main.rs{% else %}lib.rs{% endif %}.jinja†L1-L10】.
- **GitHub CI workflow** that formats, lints, tests, and uploads
Expand All @@ -41,3 +46,8 @@ linters run from the very first commit.
Install the test requirements and run `pytest` to ensure the template renders
correctly using `pytest-copier`. Additional details are in
[`docs/testing.md`](docs/testing.md).

User-facing generated-project behaviour is documented in
[`docs/users-guide.md`](docs/users-guide.md). Parent-template development
requirements are documented in
[`docs/developers-guide.md`](docs/developers-guide.md).
40 changes: 38 additions & 2 deletions copier.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,36 @@ package_name:
help: 'Crate name for Cargo.toml (lowercase, underscores)'
placeholder: 'e.g. my_awesome_tool'

package_description:
type: str
default: 'A Rust project generated from agent-template-rust.'
help: 'Crates.io package description'
placeholder: 'e.g. Command-line tools for analysing project metadata'

repository_url:
type: str
default: 'https://github.com/example/{{ package_name }}'
help: 'Repository URL for Cargo.toml metadata'
placeholder: 'e.g. https://github.com/example/my_awesome_tool'

homepage_url:
type: str
default: '{{ repository_url }}'
help: 'Homepage URL for Cargo.toml metadata'
placeholder: 'e.g. https://example.com/my-awesome-tool'

package_keywords:
type: str
default: 'rust,template'
help: 'Comma-separated crates.io keywords, up to five'
placeholder: 'e.g. cli,automation,tooling'

package_categories:
type: str
default: 'development-tools'
help: 'Comma-separated crates.io categories'
placeholder: 'e.g. command-line-utilities,development-tools'

_flavour_choices: &flavour_choices
- lib
- app
Expand All @@ -42,13 +72,13 @@ flavour:

license_holder:
type: str
default: 'Payton McIntosh'
default: 'Example Maintainer'
help: 'Your name (for the ISC licence)'
placeholder: 'e.g. Jane Smith'

license_email:
type: str
default: 'pmcintosh@df12.net'
default: 'maintainer@example.com'
help: 'Your email (for the ISC licence)'
placeholder: 'e.g. jane@example.com'

Expand All @@ -62,3 +92,9 @@ rust_nightly_date:
default: '2025-06-10'
help: 'Rust nightly toolchain date (YYYY-MM-DD)'
placeholder: 'e.g. 2025-06-10'

dev_target:
type: str
default: 'x86_64-unknown-linux-gnu'
help: 'Optional Linux target triple for mold linker config'
placeholder: 'e.g. x86_64-unknown-linux-gnu'
52 changes: 52 additions & 0 deletions docs/developers-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Developers Guide

This guide documents the tooling needed to work on the template itself. It is
separate from the generated-project guide because this parent repository runs
pytest-copier tests that render temporary Rust projects.

## Parent Template Tests

Run the public parent gate:

```sh
make test
```

The target uses `uvx --with pytest-copier --with pyyaml pytest tests/`, so
Python test dependencies must be added to that invocation before tests import
them. Keep long runs logged through `tee` into `/tmp`, following the example
in `AGENTS.md`.

The tests render both library and application projects, run generated public
gates such as `make all`, validate generated Makefiles with `mbake`, and parse
generated `Cargo.toml` files as TOML.

## Required Tooling

The parent tests expect these tools to be available when validating generated
projects:

- `uv` for isolated Python test dependency execution.
- `pytest-copier` for rendering Copier templates in tests.
- `PyYAML` for parsing rendered GitHub Actions workflows in tests.
- `syrupy` for generated structured file snapshots in tests.
- Rust and Cargo through `rustup`.
- cargo-nextest for generated fast test execution in CI, while generated
Makefiles still fall back to `cargo test` for contributors.
- `mbake` for generated Makefile validation.
- `Whitaker` for generated lint gates.
- `clang`, `lld`, and `mold` for generated linker and coverage behaviour.

The generated project itself uses Cranelift for debug code generation, Linux
`mold` linking for development builds, and `lld` for coverage because coverage
is driven by LLVM tooling.

## Design Notes

Keep generated-project behaviour in `template/` and prove it from parent tests
under `tests/`. Prefer assertions that render a real project and run public
generated commands over checks that only inspect template source text.

GitHub Actions in both parent and generated workflows are SHA-pinned. When an
action revision changes, update the rendered workflow assertions that lock the
pin.
Loading
Loading