Skip to content

Modernize cookiecutter template#21

Merged
ankurs merged 12 commits intomasterfrom
improve/cookiecutter-overhaul
Mar 23, 2026
Merged

Modernize cookiecutter template#21
ankurs merged 12 commits intomasterfrom
improve/cookiecutter-overhaul

Conversation

@ankurs
Copy link
Copy Markdown
Member

@ankurs ankurs commented Mar 23, 2026

Summary

Comprehensive modernization of the cookiecutter-coldbrew template covering bug fixes, security improvements, CI upgrades, Go tooling modernization, and a full test suite.

Bug Fixes

  • Fix healthcheck.go: use caller's ctx instead of context.Background(), fix "server" → "serve" typo
  • Fix service.go formatting, benchmark test accuracy (remove assert from hot path)
  • Fix README typos: wrong make targets, misspellings
  • Fix GitLab CI GOFLAGS conflict with go mod tidy, set GOMODCACHE for cache to work

Security

  • Add .dockerignore to prevent secrets leaking into Docker images
  • Gitignore local.env, rename to local.env.example
  • Add govulncheck for dependency vulnerability scanning (make vulncheck, runs as part of make lint)
  • Bump go.opentelemetry.io/otel/* v1.37.0 → v1.42.0 (fixes GO-2026-4394)

Docker & Build

  • Dockerfile: COPY instead of ADD, CGO_ENABLED=0, ca-certificates, EXPOSE 9090 9091, simplified layout
  • Makefile: add GIT_BRANCH, fix bench pattern, rename installdeps, add fmt/vulncheck targets
  • Complete .PHONY list, fix concurrency groups in GitHub Actions

Go Modernization

  • Replace tools/tools.go with Go 1.24+ tool directive in go.mod
  • Remove templated go.sum (3,730 lines — regenerated by post-gen hook)
  • Update default Go versions to 1.26/1.25

CI/CD

  • Update GitHub Actions: checkout@v4, setup-go@v5 with caching, per-job concurrency groups
  • Remove stale .travis.yml, add GitHub Actions CI for cookiecutter repo itself
  • Add end-to-end integration workflow: generates project, runs build/test/lint
  • Update Python test deps to modern versions (3.11–3.13)

Developer Experience

  • Add comprehensive AGENTS.md (vendor-neutral AI assistant instructions) with architecture, workflows, and rules
  • CLAUDE.md imports AGENTS.md via @AGENTS.md
  • Add .editorconfig for consistent formatting
  • Add local scripts/test-e2e.sh and root Makefile (make test, make test-e2e, make test-all)

Tests

  • 44 pytest tests covering project structure, file content, variable rendering, and parameterized configs
  • All tests run without Go (use accept_hooks=False), completing in ~4s
  • End-to-end integration test generates a full project and runs build/test/lint

Test plan

  • All 44 pytest tests pass locally (pytest tests/ -v)
  • GitHub Actions CI runs pytest across Python 3.11, 3.12, 3.13
  • Integration workflow generates project and runs make build && make test && make lint

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added CI workflows for unit and integration runs; new root Makefile and e2e test script; project template now includes editor config and Docker context rules.
  • Bug Fixes

    • Fixed healthcheck typo and corrected Docker build/runtime configuration.
  • Documentation

    • Added comprehensive architecture/developer guide and updated contributing/README guidance.
  • Tests

    • Added pytest fixtures and expanded generation/integration test suite.
  • Chores

    • Updated test matrices and dependency constraints; removed legacy CI config.

…, and comprehensive tests

- Fix healthcheck.go: use caller's ctx instead of context.Background(), fix "server" typo
- Fix service.go formatting, benchmark test using assert in hot path
- Add .dockerignore to prevent secrets leaking into Docker images
- Rename local.env to local.env.example, gitignore local.env
- Modernize Dockerfile: COPY instead of ADD, CGO_ENABLED=0, ca-certificates, EXPOSE ports
- Fix Makefile: add GIT_BRANCH, fix bench -run pattern, add fmt/doc targets
- Migrate to Go 1.24+ tool directive, remove tools/tools.go and templated go.sum
- Update GitHub Actions to checkout@v4, setup-go@v5 with caching
- Fix GitLab CI: remove go mod tidy conflict with -mod=readonly, use go tool cobertura
- Fix 5 README typos (wrong make targets, misspellings)
- Update Python test deps and tox to modern versions, remove stale .travis.yml
- Add GitHub Actions CI for cookiecutter repo itself
- Add comprehensive test suite (44 tests) covering structure, content, and parameterized configs
- Add CLAUDE.md and .editorconfig to generated projects
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 23, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d893de5c-35f5-408d-8cfa-fb150cb94b4e

📥 Commits

Reviewing files that changed from the base of the PR and between 62568c9 and fdf5087.

📒 Files selected for processing (2)
  • tox.ini
  • {{cookiecutter.app_name}}/service/service_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • tox.ini
  • {{cookiecutter.app_name}}/service/service_test.go

📝 Walkthrough

Walkthrough

Adds GitHub Actions (unit and integration) and local Makefile-based test runners, removes Travis CI, updates Python tooling and tox matrix, introduces pytest cookiecutter bake fixtures and extensive generation tests, adds post-gen local.env setup, and modernizes template files (Docker, Makefile, CI, go.mod, editorconfig) plus small Go test/code tidy-ups.

Changes

Cohort / File(s) Summary
Repo CI workflows
/.github/workflows/test.yml, .github/workflows/integration.yml, .travis.yml
Added GitHub Actions test.yml (Python 3.11–3.13) and integration.yml (cookiecutter → make build/test/lint); removed legacy .travis.yml.
Python tooling & repo Makefile
requirements.txt, tox.ini, Makefile
Loosened/updated Python deps, removed sh, updated tox envs to py311/py312/py313, added repo-level Make targets install/test/test-e2e/test-all.
Tests & fixtures
tests/conftest.py, tests/test_cookiecutter_generation.py
Added cookiecutter bake fixtures and comprehensive generation tests; refactored file checks and removed older simple bake tests.
Template hooks
hooks/post_gen_project.py
Renumbered proto init steps and added setup_local_env() to copy local.env.examplelocal.env when appropriate.
Generated template CI & linting
{{cookiecutter.app_name}}/.github/workflows/go.yml, {{cookiecutter.app_name}}/.gitlab-ci.yml
Bumped Actions versions, enabled setup-go caching, adjusted GitLab shared setup and coverage invocation, removed vet job, added vuln check step in lint job.
Docker, ignore & editor config
{{cookiecutter.app_name}}/Dockerfile, {{cookiecutter.app_name}}/.dockerignore, {{cookiecutter.app_name}}/.gitignore, {{cookiecutter.app_name}}/.editorconfig
Switched build WORKDIR to /app, use COPY . ., install ca-certificates, added EXPOSE 9090 9091, added .dockerignore, updated .gitignore, added .editorconfig.
Build, tools & go modules
{{cookiecutter.app_name}}/Makefile, {{cookiecutter.app_name}}/go.mod, {{cookiecutter.app_name}}/tools/tools.go, cookiecutter.json
Added fmt/vulncheck targets, embed GIT_BRANCH in ldflags, use go tool ... for tools, added tool (...) in go.mod, removed tools/tools.go, bumped docker_build_image_version.
Generated service code & tests
{{cookiecutter.app_name}}/service/healthcheck.go, {{cookiecutter.app_name}}/service/service.go, {{cookiecutter.app_name}}/service/service_test.go
Readiness probe now uses provided ctx and typo fixed; receiver spacing normalized; benchmark uses b.Fatal/b.Fatalf and resets timer.
Repository e2e script & template docs
scripts/test-e2e.sh, {{cookiecutter.app_name}}/AGENTS.md, {{cookiecutter.app_name}}/CLAUDE.md, {{cookiecutter.app_name}}/README.md
Added strict e2e script that bakes template and runs make build/test/lint; added AGENTS.md and CLAUDE.md; README fixes and updated make target references.

Sequence Diagram(s)

sequenceDiagram
    participant Runner as GitHub Actions Runner
    participant Python as Python Setup (3.13)
    participant Cookiecutter as cookiecutter
    participant Generated as Generated Project (myapp)
    participant Make as Make (build/test/lint)

    Runner->>Python: setup-python 3.13
    Python->>Cookiecutter: pip install cookiecutter
    Runner->>Cookiecutter: cookiecutter --no-input --verbose .
    Cookiecutter->>Generated: render template -> workspace/myapp
    Runner->>Generated: cd myapp
    Runner->>Make: make build
    Make->>Make: make test / make lint
    Make-->>Runner: exit code / artifacts
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • fajran
  • kevinjom
  • svetha-cvl
  • wdevarshi

Poem

"🐇 I hopped through CI, templates, and test,
I nudged workflows, let old Travis rest.
I copied .env, tuned Docker’s light,
Baked projects by day and linted by night.
🥕 Fresh templates—ready for flight!"

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.07% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'Modernize cookiecutter template' directly aligns with the main objective of comprehensively modernizing the cookiecutter-coldbrew template across bug fixes, security, CI/CD, Go tooling, Docker, and developer experience.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch improve/cookiecutter-overhaul

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Modernizes the Go microservice cookiecutter template to improve tooling/CI ergonomics, Docker security defaults, and add a much more comprehensive Python-based validation suite for template output.

Changes:

  • Migrates tool dependency tracking from tools/tools.go to the Go tool directive in go.mod, and updates Make/CI to use go tool.
  • Updates Dockerfile/Makefile/CI configs (Actions + GitLab CI), plus small Go fixes (healthcheck context, typo, formatting, benchmark).
  • Adds/updates Python test infrastructure (new fixtures, expanded generation/content tests), modernizes tox/requirements, and removes Travis config.

Reviewed changes

Copilot reviewed 20 out of 24 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
{{cookiecutter.app_name}}/tools/tools.go Removes legacy “tools package” approach for pinning tool deps.
{{cookiecutter.app_name}}/go.mod Adds tool directive entries for buf/lint/mockery/cobertura.
{{cookiecutter.app_name}}/Makefile Switches to go tool usage; adds fmt/doc; updates build/bench behavior.
{{cookiecutter.app_name}}/Dockerfile Uses WORKDIR + COPY, installs ca-certificates, exposes ports.
{{cookiecutter.app_name}}/.dockerignore Reduces build context; excludes env files and misc artifacts.
{{cookiecutter.app_name}}/.gitignore Ignores local.env, cover.html, and misc.
{{cookiecutter.app_name}}/.github/workflows/go.yml Updates Actions versions and enables setup-go caching.
{{cookiecutter.app_name}}/.gitlab-ci.yml Uses go tool for cobertura; adjusts GOFLAGS handling and removes vet job.
{{cookiecutter.app_name}}/service/healthcheck.go Uses caller context and fixes readiness error message typo.
{{cookiecutter.app_name}}/service/service.go Fixes receiver spacing/formatting.
{{cookiecutter.app_name}}/service/service_test.go Makes benchmark timing/assertions more accurate for benchmarks.
{{cookiecutter.app_name}}/README.md Fixes typos and updates Make target names/docs.
{{cookiecutter.app_name}}/local.env.example Adds example local environment file.
{{cookiecutter.app_name}}/CLAUDE.md Adds generated-project “agent instructions”/project notes.
{{cookiecutter.app_name}}/.editorconfig Adds basic formatting defaults for common file types.
hooks/post_gen_project.py Adjusts proto init steps and creates local.env from example.
tests/conftest.py Adds fixtures to bake projects directly via cookiecutter without hooks.
tests/test_cookiecutter_generation.py Replaces minimal tests with extensive structure/content/parameterized checks.
requirements.txt Updates to modern, unpinned minimums for cookiecutter/pytest/tox/test deps.
tox.ini Updates envlist to py311–py313 and removes unused deps.
.github/workflows/test.yml Adds CI for running pytest across supported Python versions.
.travis.yml Removes legacy Travis CI configuration.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread {{cookiecutter.app_name}}/.gitlab-ci.yml Outdated
Comment thread {{cookiecutter.app_name}}/.gitlab-ci.yml
Comment thread tests/test_cookiecutter_generation.py Outdated
Comment thread tests/conftest.py Outdated
Comment thread {{cookiecutter.app_name}}/Makefile Outdated
Comment thread {{cookiecutter.app_name}}/Makefile Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (9)
{{cookiecutter.app_name}}/.gitignore (1)

6-6: Consider anchoring the misc ignore pattern.

Line 6 ignores any path named misc anywhere in the repo. If you only mean the repository-root folder, anchor it to reduce accidental ignores.

Proposed tweak
-misc
+/misc/
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @{{cookiecutter.app_name}}/.gitignore at line 6, The .gitignore entry "misc"
currently matches any path segment named misc anywhere; change that pattern to
an anchored root match (e.g., use "/misc" or "/misc/") so only the
repository-root misc folder is ignored; update the entry in .gitignore (replace
the unanchored "misc" line) to the anchored form to avoid accidentally ignoring
similarly named directories elsewhere.
tox.ini (1)

10-10: Use pytest instead of the legacy py.test alias for consistency with current tox best practices.

Line 10 should use pytest directly, as current tox documentation and examples exclusively recommend pytest over py.test for new configurations. While py.test remains supported in pytest 8.x+, adopting pytest aligns with modern tooling standards.

Proposed change
-commands = py.test {posargs:tests}
+commands = pytest {posargs:tests}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tox.ini` at line 10, Replace the legacy py.test alias in the tox.ini commands
setting with the modern pytest invocation: locate the "commands = py.test
{posargs:tests}" entry and change "py.test" to "pytest" so the line reads using
pytest directly; ensure no other occurrences of "py.test" remain in the file to
keep tox configuration consistent with current best practices.
.github/workflows/test.yml (1)

1-25: LGTM! Well-structured CI workflow with modern action versions.

The workflow correctly tests across Python 3.11-3.13 with pip caching enabled. Using actions/checkout@v4 and actions/setup-python@v5 aligns with the PR's goal to update CI to modern versions.

Optional improvements for robustness:

  • Add fail-fast: false to the strategy to see all matrix results even if one fails
  • Add a timeout-minutes to prevent indefinite hangs
♻️ Optional: Add fail-fast and timeout
     strategy:
+      fail-fast: false
       matrix:
         python-version: ["3.11", "3.12", "3.13"]
     steps:
+      timeout-minutes: 10
       - uses: actions/checkout@v4
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/test.yml around lines 1 - 25, Add robustness to the Test
job by disabling matrix fail-fast and adding a timeout: set strategy.fail-fast
to false under the existing strategy.matrix block (referencing the strategy and
matrix keys) and add a timeout-minutes entry under the test job (referencing
jobs.test) with a sensible value (e.g., 10-30) so long-running runs are
automatically cancelled.
hooks/post_gen_project.py (1)

76-87: Add a progress message for consistency with other functions.

The setup_local_env() function works correctly, but unlike init_proto() and init_git(), it doesn't print any status message. Adding one would provide consistent feedback to users.

♻️ Suggested improvement for user feedback
 def setup_local_env():
     """
     Copies local.env.example to local.env for local development
     """
     import shutil
     example = os.path.join(PROJECT_DIRECTORY, "local.env.example")
     local = os.path.join(PROJECT_DIRECTORY, "local.env")
     if os.path.exists(example) and not os.path.exists(local):
         shutil.copy2(example, local)
+        print("Created local.env from local.env.example")

Also, consider moving import shutil to the top of the file with other imports for consistency with Python conventions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hooks/post_gen_project.py` around lines 76 - 87, Add a user-facing progress
message inside setup_local_env() to match init_proto() and init_git: when the
function starts (or after copying), call the same logger/print used elsewhere to
indicate "Creating local.env from local.env.example" or similar, and ensure it
runs only when the copy occurs; also move the import shutil from inside
setup_local_env to the module-level imports at the top of the file for
consistency with other imports and style. Use the function name setup_local_env
and the PROJECT_DIRECTORY constant to locate the code.
requirements.txt (1)

1-7: Consider adding upper version bounds or using a lockfile for reproducible test environments.

The shift from exact pins to minimum version constraints (>=) provides flexibility but reduces reproducibility. All specified minimum versions exist and are accessible (cookiecutter 2.6.0, pytest 8.0.0, tox 4.0.0, pytest-cookies 0.7.0, binaryornot 0.4.4). For a template/testing repository this approach is acceptable, but adding upper bounds (e.g., cookiecutter>=2.6.0,<3.0) or using a lockfile would ensure consistent CI test results across runs.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@requirements.txt` around lines 1 - 7, The requirements.txt currently uses
only minimum version constraints (cookiecutter, pytest, tox, pytest-cookies,
binaryornot) which reduces reproducibility; update the constraints to include
sensible upper bounds (e.g., cookiecutter>=2.6.0,<3.0) for each listed package
or add a separate lockfile (pip-tools/poetry/requirements-lock.txt) and commit
it, ensuring CI/test jobs consume the lockfile to pin exact versions
reproducibly.
tests/test_cookiecutter_generation.py (2)

315-327: Fragile YAML parsing.

The before_script detection logic assumes 4-space indentation (" -"). This works for the controlled template output but could break if indentation changes. Consider using a YAML parser for robustness, though this is acceptable for template tests.

🧹 Alternative using PyYAML (if already a dependency)
def test_gitlab_ci_no_go_mod_tidy_in_before_script(self, bake_project):
    import yaml
    project = bake_project()
    content = (project / ".gitlab-ci.yml").read_text()
    data = yaml.safe_load(content)
    before_script = data.get("before_script", [])
    for cmd in before_script:
        assert "go mod tidy" not in cmd
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_cookiecutter_generation.py` around lines 315 - 327, The test
test_gitlab_ci_no_go_mod_tidy_in_before_script is fragile because it detects
before_script by hard-coded 4-space indentation; replace the ad-hoc string scan
with YAML parsing of the .gitlab-ci.yml content (e.g., use yaml.safe_load) and
then assert that none of the entries in the parsed before_script list contain
"go mod tidy", referencing the test function name and the ".gitlab-ci.yml"
target.

206-210: Consider using next(iter(...)) for single element access.

Per static analysis, using next(iter(...)) is more idiomatic and avoids creating an intermediate list when only the first element is needed.

🧹 Apply Ruff suggestion
     def test_custom_service_name(self, bake_project):
         project = bake_project({"service_name": "OrderService"})
-        proto_file = list((project / "proto").glob("*.proto"))[0]
+        proto_file = next(iter((project / "proto").glob("*.proto")))
         content = proto_file.read_text()
         assert "service OrderService {" in content
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_cookiecutter_generation.py` around lines 206 - 210, In
test_custom_service_name replace the intermediate list creation when grabbing
the first .proto file: in the test_custom_service_name function in
tests/test_cookiecutter_generation.py change the proto_file assignment from
list((project / "proto").glob("*.proto"))[0] to using next(iter((project /
"proto").glob("*.proto"))) so you avoid allocating a list and follow the
idiomatic pattern for single-element access.
tests/conftest.py (1)

2-2: Unused import.

The os module is imported but not used anywhere in this file.

🧹 Remove unused import
 # -*- coding: utf-8 -*-
-import os
 from pathlib import Path
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/conftest.py` at line 2, Remove the unused top-level import statement
"import os" from the file (it's not referenced anywhere in the module); delete
that line and run the linter/tests to confirm no breakage, and only re-add the
import if you later introduce code that uses the os module.
{{cookiecutter.app_name}}/Makefile (1)

83-84: Consider adding gomarkdoc to the tool directive.

The doc target uses go run ...@latest, which downloads the tool on every invocation and isn't reproducible. Other tools (buf, golangci-lint, mockery) are managed via the tool directive in go.mod. For consistency and reproducibility, consider adding gomarkdoc to the tool block.

♻️ Add to go.mod and update Makefile

In go.mod:

tool (
	github.com/boumenot/gocover-cobertura
	github.com/bufbuild/buf/cmd/buf
	github.com/golangci/golangci-lint/v2/cmd/golangci-lint
	github.com/princjef/gomarkdoc/cmd/gomarkdoc
	github.com/vektra/mockery/v2
)

Then in Makefile:

 doc:
-	go run github.com/princjef/gomarkdoc/cmd/gomarkdoc@latest ./... > README.md
+	go tool gomarkdoc ./... > README.md
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @{{cookiecutter.app_name}}/Makefile around lines 83 - 84, The Makefile doc
target uses "go run github.com/princjef/gomarkdoc/cmd/gomarkdoc@latest ./... >
README.md", which downloads the tool on every run; add
"github.com/princjef/gomarkdoc/cmd/gomarkdoc" to the go.mod tool block (the tool
(...) section) and update the Makefile doc target to call the tool without
`@latest` (e.g., "go run github.com/princjef/gomarkdoc/cmd/gomarkdoc ./... >
README.md") so gomarkdoc is versioned via the tool directive and invocations are
reproducible, touching the go.mod tool list and the doc target in the Makefile.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.github/workflows/test.yml:
- Around line 1-25: Add robustness to the Test job by disabling matrix fail-fast
and adding a timeout: set strategy.fail-fast to false under the existing
strategy.matrix block (referencing the strategy and matrix keys) and add a
timeout-minutes entry under the test job (referencing jobs.test) with a sensible
value (e.g., 10-30) so long-running runs are automatically cancelled.

In @{{cookiecutter.app_name}}/.gitignore:
- Line 6: The .gitignore entry "misc" currently matches any path segment named
misc anywhere; change that pattern to an anchored root match (e.g., use "/misc"
or "/misc/") so only the repository-root misc folder is ignored; update the
entry in .gitignore (replace the unanchored "misc" line) to the anchored form to
avoid accidentally ignoring similarly named directories elsewhere.

In @{{cookiecutter.app_name}}/Makefile:
- Around line 83-84: The Makefile doc target uses "go run
github.com/princjef/gomarkdoc/cmd/gomarkdoc@latest ./... > README.md", which
downloads the tool on every run; add
"github.com/princjef/gomarkdoc/cmd/gomarkdoc" to the go.mod tool block (the tool
(...) section) and update the Makefile doc target to call the tool without
`@latest` (e.g., "go run github.com/princjef/gomarkdoc/cmd/gomarkdoc ./... >
README.md") so gomarkdoc is versioned via the tool directive and invocations are
reproducible, touching the go.mod tool list and the doc target in the Makefile.

In `@hooks/post_gen_project.py`:
- Around line 76-87: Add a user-facing progress message inside setup_local_env()
to match init_proto() and init_git: when the function starts (or after copying),
call the same logger/print used elsewhere to indicate "Creating local.env from
local.env.example" or similar, and ensure it runs only when the copy occurs;
also move the import shutil from inside setup_local_env to the module-level
imports at the top of the file for consistency with other imports and style. Use
the function name setup_local_env and the PROJECT_DIRECTORY constant to locate
the code.

In `@requirements.txt`:
- Around line 1-7: The requirements.txt currently uses only minimum version
constraints (cookiecutter, pytest, tox, pytest-cookies, binaryornot) which
reduces reproducibility; update the constraints to include sensible upper bounds
(e.g., cookiecutter>=2.6.0,<3.0) for each listed package or add a separate
lockfile (pip-tools/poetry/requirements-lock.txt) and commit it, ensuring
CI/test jobs consume the lockfile to pin exact versions reproducibly.

In `@tests/conftest.py`:
- Line 2: Remove the unused top-level import statement "import os" from the file
(it's not referenced anywhere in the module); delete that line and run the
linter/tests to confirm no breakage, and only re-add the import if you later
introduce code that uses the os module.

In `@tests/test_cookiecutter_generation.py`:
- Around line 315-327: The test test_gitlab_ci_no_go_mod_tidy_in_before_script
is fragile because it detects before_script by hard-coded 4-space indentation;
replace the ad-hoc string scan with YAML parsing of the .gitlab-ci.yml content
(e.g., use yaml.safe_load) and then assert that none of the entries in the
parsed before_script list contain "go mod tidy", referencing the test function
name and the ".gitlab-ci.yml" target.
- Around line 206-210: In test_custom_service_name replace the intermediate list
creation when grabbing the first .proto file: in the test_custom_service_name
function in tests/test_cookiecutter_generation.py change the proto_file
assignment from list((project / "proto").glob("*.proto"))[0] to using
next(iter((project / "proto").glob("*.proto"))) so you avoid allocating a list
and follow the idiomatic pattern for single-element access.

In `@tox.ini`:
- Line 10: Replace the legacy py.test alias in the tox.ini commands setting with
the modern pytest invocation: locate the "commands = py.test {posargs:tests}"
entry and change "py.test" to "pytest" so the line reads using pytest directly;
ensure no other occurrences of "py.test" remain in the file to keep tox
configuration consistent with current best practices.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 247fee00-c0b4-424e-b467-6951269f5375

📥 Commits

Reviewing files that changed from the base of the PR and between 314bfb6 and 9b128d8.

⛔ Files ignored due to path filters (1)
  • {{cookiecutter.app_name}}/go.sum is excluded by !**/*.sum
📒 Files selected for processing (22)
  • .github/workflows/test.yml
  • .travis.yml
  • hooks/post_gen_project.py
  • requirements.txt
  • tests/conftest.py
  • tests/test_cookiecutter_generation.py
  • tox.ini
  • {{cookiecutter.app_name}}/.dockerignore
  • {{cookiecutter.app_name}}/.editorconfig
  • {{cookiecutter.app_name}}/.github/workflows/go.yml
  • {{cookiecutter.app_name}}/.gitignore
  • {{cookiecutter.app_name}}/.gitlab-ci.yml
  • {{cookiecutter.app_name}}/CLAUDE.md
  • {{cookiecutter.app_name}}/Dockerfile
  • {{cookiecutter.app_name}}/Makefile
  • {{cookiecutter.app_name}}/README.md
  • {{cookiecutter.app_name}}/go.mod
  • {{cookiecutter.app_name}}/local.env.example
  • {{cookiecutter.app_name}}/service/healthcheck.go
  • {{cookiecutter.app_name}}/service/service.go
  • {{cookiecutter.app_name}}/service/service_test.go
  • {{cookiecutter.app_name}}/tools/tools.go
💤 Files with no reviewable changes (2)
  • .travis.yml
  • {{cookiecutter.app_name}}/tools/tools.go

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
tests/test_cookiecutter_generation.py (2)

47-58: Keep this app-name test tied to the shared default context.

This test only cares about slug derivation, but the inline full_context duplicates almost every template input. Each new cookiecutter field now creates an unrelated maintenance touchpoint here.

Reduce the second source of truth
-    def test_custom_app_name_with_spaces(self, bake_project):
+    def test_custom_app_name_with_spaces(self, bake_project, default_context):
         # Don't set app_name — let the Jinja2 filter derive it from name
-        project = bake_project(full_context={
-            "source_path": "github.com/testorg",
-            "name": "My Cool Service",
-            "grpc_package": "com.github.testorg",
-            "service_name": "TestSvc",
-            "project_short_description": "A test service.",
-            "docker_image": "alpine:latest",
-            "docker_build_image": "golang",
-            "docker_build_image_version": "1.26",
-        })
+        context = default_context.copy()
+        context.pop("app_name", None)
+        context["name"] = "My Cool Service"
+        project = bake_project(full_context=context)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_cookiecutter_generation.py` around lines 47 - 58, The
test_custom_app_name_with_spaces test duplicates the entire cookiecutter
context; instead, rely on the shared default context and only override the field
under test. Update the bake_project call in test_custom_app_name_with_spaces to
remove the full_context bulk and pass a minimal override (e.g., only "name": "My
Cool Service") via bake_project(full_context={...}) so the test focuses on slug
derivation and avoids duplicating unrelated template inputs; keep using the same
bake_project fixture and assertions as before.

315-327: Don't make before_script detection depend on four-space indentation.

A valid YAML reformat can make this loop stop inspecting before_script while still passing, because only - lines are treated as entries.

More robust scan without assuming exact indentation
-        lines = content.split("\n")
-        in_before_script = False
-        for line in lines:
-            if "before_script:" in line:
-                in_before_script = True
-            elif in_before_script and not line.startswith("    -") and line.strip():
-                in_before_script = False
-            if in_before_script:
-                assert "go mod tidy" not in line
+        before_script_blocks = re.findall(
+            r"(?ms)^\s*before_script:\s*\n((?:^\s*-\s.*\n?)*)",
+            content,
+        )
+        assert before_script_blocks
+        for block in before_script_blocks:
+            assert "go mod tidy" not in block
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_cookiecutter_generation.py` around lines 315 - 327, The test
test_gitlab_ci_no_go_mod_tidy_in_before_script currently detects the
before_script block by hardcoding four-space indentation via checks for "    -",
which breaks if YAML is reformatted; change the logic in that test (the
in_before_script detection loop) to first detect the before_script line using a
regex like r'^\s*before_script\s*:' and record its leading indentation, then
treat subsequent lines as list entries if they start with that indentation
followed by '-' (e.g., r'^\s{N}\s*-\s') or any line that is more-indented than
the before_script key; stop the block when you encounter a non-empty line whose
indentation is less than or equal to the before_script key or a new top-level
key (r'^\s*\S.*:'); this makes the assertion that "go mod tidy" is not present
in before_script robust to reformatting while still checking the same variable
names (in_before_script, lines, content).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/test_cookiecutter_generation.py`:
- Around line 9-10: The current PATTERN/RE_OBJ only matches the simple "{{
cookiecutter.* }}" form; update the regex used by PATTERN (and thus RE_OBJ) so
test_no_unrendered_variables scans for other Jinja/Cookiecutter forms too—match
variable and block delimiters including {{ ... }}, {{- ... -}}, {% ... %}, {%-
... -%} (and optional whitespace control) when they contain "cookiecutter" or
other unrendered template tokens; change PATTERN accordingly and ensure
test_no_unrendered_variables uses RE_OBJ to detect any of these variants.
- Around line 249-253: The test test_dockerignore_excludes_secrets currently
only asserts presence of a few entries and doesn't prevent regression where
".git" could be added; update the test to read the .dockerignore via
bake_project(), split the content into lines (or strip and splitlines) and
assert that neither ".git" nor ".git/" appears as a whole line, while still
asserting the required entries (e.g., "local.env", "vendor", ".github") are
present as lines; reference the test function name
test_dockerignore_excludes_secrets and the bake_project fixture/project /
".dockerignore" read to locate where to change the assertions.

---

Nitpick comments:
In `@tests/test_cookiecutter_generation.py`:
- Around line 47-58: The test_custom_app_name_with_spaces test duplicates the
entire cookiecutter context; instead, rely on the shared default context and
only override the field under test. Update the bake_project call in
test_custom_app_name_with_spaces to remove the full_context bulk and pass a
minimal override (e.g., only "name": "My Cool Service") via
bake_project(full_context={...}) so the test focuses on slug derivation and
avoids duplicating unrelated template inputs; keep using the same bake_project
fixture and assertions as before.
- Around line 315-327: The test test_gitlab_ci_no_go_mod_tidy_in_before_script
currently detects the before_script block by hardcoding four-space indentation
via checks for "    -", which breaks if YAML is reformatted; change the logic in
that test (the in_before_script detection loop) to first detect the
before_script line using a regex like r'^\s*before_script\s*:' and record its
leading indentation, then treat subsequent lines as list entries if they start
with that indentation followed by '-' (e.g., r'^\s{N}\s*-\s') or any line that
is more-indented than the before_script key; stop the block when you encounter a
non-empty line whose indentation is less than or equal to the before_script key
or a new top-level key (r'^\s*\S.*:'); this makes the assertion that "go mod
tidy" is not present in before_script robust to reformatting while still
checking the same variable names (in_before_script, lines, content).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6177c549-94c2-4566-ae7a-fb6231ce46e5

📥 Commits

Reviewing files that changed from the base of the PR and between 9b128d8 and d40f012.

📒 Files selected for processing (4)
  • cookiecutter.json
  • tests/conftest.py
  • tests/test_cookiecutter_generation.py
  • {{cookiecutter.app_name}}/.dockerignore
✅ Files skipped from review due to trivial changes (2)
  • {{cookiecutter.app_name}}/.dockerignore
  • cookiecutter.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/conftest.py

Comment thread tests/test_cookiecutter_generation.py
Comment thread tests/test_cookiecutter_generation.py Outdated
- Fix GitLab CI cache: set GOMODCACHE to match cached path
- Complete .PHONY list with all Makefile targets
- Remove unused imports (os in conftest, Path in tests)
- Add regression test: assert .git is NOT in .dockerignore
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
{{cookiecutter.app_name}}/Makefile (1)

83-84: Consider writing to a different file or appending.

The doc target overwrites README.md entirely with gomarkdoc output. If the README contains additional content (badges, setup instructions, examples), it will be lost. Consider writing to a dedicated file like API.md or documenting this behavior.

♻️ Alternative: Write to a separate file
 doc:
-	go run github.com/princjef/gomarkdoc/cmd/gomarkdoc@latest ./... > README.md
+	go run github.com/princjef/gomarkdoc/cmd/gomarkdoc@latest ./... > API.md
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @{{cookiecutter.app_name}}/Makefile around lines 83 - 84, The Makefile's doc
target currently overwrites README.md via the command "go run
github.com/princjef/gomarkdoc/cmd/gomarkdoc@latest ./... > README.md"; change it
to write to a separate file (e.g. API.md) or append instead of overwrite (use
>>) so existing README content (badges, examples) is preserved; update the doc
target invocation string accordingly and add a brief comment in the Makefile
explaining the chosen behavior.
tests/test_cookiecutter_generation.py (2)

205-209: Use next(iter(...)) for single element access.

Using list indexing on a generator is less efficient than using next().

♻️ Proposed fix
     def test_custom_service_name(self, bake_project):
         project = bake_project({"service_name": "OrderService"})
-        proto_file = list((project / "proto").glob("*.proto"))[0]
+        proto_file = next(iter((project / "proto").glob("*.proto")))
         content = proto_file.read_text()
         assert "service OrderService {" in content
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_cookiecutter_generation.py` around lines 205 - 209, Replace the
inefficient list indexing used to get the single .proto file in
test_custom_service_name: instead of building a list with list((project /
"proto").glob("*.proto"))[0], use next(iter((project /
"proto").glob("*.proto"))) to retrieve the first (and only) element; update the
proto_file assignment in the test_custom_service_name function that uses
bake_project so it uses next(iter(...)) for more efficient single-element
access.

318-330: Hardcoded indentation assumption may be fragile.

The logic assumes before_script items are indented with exactly 4 spaces (" -"). While this works for the controlled template, it could break if formatting changes. Consider using a YAML parser for robustness, or document the assumption.

♻️ Alternative using YAML parsing
import yaml

def test_gitlab_ci_no_go_mod_tidy_in_before_script(self, bake_project):
    project = bake_project()
    content = (project / ".gitlab-ci.yml").read_text()
    ci_config = yaml.safe_load(content)
    before_script = ci_config.get("before_script", [])
    for cmd in before_script:
        assert "go mod tidy" not in cmd
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_cookiecutter_generation.py` around lines 318 - 330, The test
test_gitlab_ci_no_go_mod_tidy_in_before_script is fragile because it assumes
items in before_script are indented with exactly four spaces; change it to parse
the .gitlab-ci.yml with a YAML parser (yaml.safe_load) and read the
before_script key as a list, then iterate its elements and assert none contain
"go mod tidy" to avoid brittle whitespace-based parsing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @{{cookiecutter.app_name}}/Makefile:
- Around line 83-84: The Makefile's doc target currently overwrites README.md
via the command "go run github.com/princjef/gomarkdoc/cmd/gomarkdoc@latest ./...
> README.md"; change it to write to a separate file (e.g. API.md) or append
instead of overwrite (use >>) so existing README content (badges, examples) is
preserved; update the doc target invocation string accordingly and add a brief
comment in the Makefile explaining the chosen behavior.

In `@tests/test_cookiecutter_generation.py`:
- Around line 205-209: Replace the inefficient list indexing used to get the
single .proto file in test_custom_service_name: instead of building a list with
list((project / "proto").glob("*.proto"))[0], use next(iter((project /
"proto").glob("*.proto"))) to retrieve the first (and only) element; update the
proto_file assignment in the test_custom_service_name function that uses
bake_project so it uses next(iter(...)) for more efficient single-element
access.
- Around line 318-330: The test test_gitlab_ci_no_go_mod_tidy_in_before_script
is fragile because it assumes items in before_script are indented with exactly
four spaces; change it to parse the .gitlab-ci.yml with a YAML parser
(yaml.safe_load) and read the before_script key as a list, then iterate its
elements and assert none contain "go mod tidy" to avoid brittle whitespace-based
parsing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5349169e-5fac-425f-87c4-8338e262fdca

📥 Commits

Reviewing files that changed from the base of the PR and between d40f012 and 2d1b2d2.

📒 Files selected for processing (4)
  • tests/conftest.py
  • tests/test_cookiecutter_generation.py
  • {{cookiecutter.app_name}}/.gitlab-ci.yml
  • {{cookiecutter.app_name}}/Makefile
✅ Files skipped from review due to trivial changes (1)
  • tests/conftest.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • {{cookiecutter.app_name}}/.gitlab-ci.yml

Generated services are applications, not libraries. Users interact via
gRPC/HTTP endpoints (documented by Swagger UI), not Go imports. The
gomarkdoc-based doc target would overwrite the hand-written README.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
{{cookiecutter.app_name}}/Makefile (1)

1-1: Add an all phony target to satisfy Makefile tooling.

checkmake reports a missing required phony target all. Add a simple alias to test (or default) to keep CI/static checks green.

🔧 Proposed patch
-.PHONY: build build-alpine clean test default install generate run run-docker fmt help bench build-docker coverage-html dep lint mock runj
+.PHONY: all build build-alpine clean test default install generate run run-docker fmt help bench build-docker coverage-html dep lint mock runj
+
+all: test
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @{{cookiecutter.app_name}}/Makefile at line 1, Add a phony "all" target to
the Makefile so tooling like checkmake is satisfied: update the .PHONY line to
include "all" and add a simple "all" target that aliases to the existing "test"
or "default" target (e.g., define target "all:" that runs the same recipe as
"test" or delegates to "default"), ensuring no duplicate recipes and keeping
phony declarations consistent.
tests/test_cookiecutter_generation.py (1)

205-209: Consider using next(iter(...)) for single-element access.

Per static analysis, next(iter(...)) is more idiomatic than list(...)[0] when you only need the first element. Alternatively, mirror the pattern from test_proto_file_exists which explicitly asserts the count first.

♻️ Suggested fix
     def test_custom_service_name(self, bake_project):
         project = bake_project({"service_name": "OrderService"})
-        proto_file = list((project / "proto").glob("*.proto"))[0]
+        proto_file = next(iter((project / "proto").glob("*.proto")))
         content = proto_file.read_text()
         assert "service OrderService {" in content
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_cookiecutter_generation.py` around lines 205 - 209, In
test_custom_service_name, replace the non-idiomatic list((project /
"proto").glob("*.proto"))[0] access with an idiomatic single-element access: use
proto_file = next(iter((project / "proto").glob("*.proto"))) or alternatively
follow the pattern from test_proto_file_exists by first asserting the number of
matches and then indexing; update the test_custom_service_name (and use the
bake_project/proto_file symbols) accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @{{cookiecutter.app_name}}/Makefile:
- Line 1: Add a phony "all" target to the Makefile so tooling like checkmake is
satisfied: update the .PHONY line to include "all" and add a simple "all" target
that aliases to the existing "test" or "default" target (e.g., define target
"all:" that runs the same recipe as "test" or delegates to "default"), ensuring
no duplicate recipes and keeping phony declarations consistent.

In `@tests/test_cookiecutter_generation.py`:
- Around line 205-209: In test_custom_service_name, replace the non-idiomatic
list((project / "proto").glob("*.proto"))[0] access with an idiomatic
single-element access: use proto_file = next(iter((project /
"proto").glob("*.proto"))) or alternatively follow the pattern from
test_proto_file_exists by first asserting the number of matches and then
indexing; update the test_custom_service_name (and use the
bake_project/proto_file symbols) accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 49258e37-6d24-4086-b15e-9830e809514a

📥 Commits

Reviewing files that changed from the base of the PR and between 2d1b2d2 and 4efb1ae.

📒 Files selected for processing (2)
  • tests/test_cookiecutter_generation.py
  • {{cookiecutter.app_name}}/Makefile

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 24 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

{{cookiecutter.app_name}}/Makefile:48

  • build-docker passes --build-arg GIT_BRANCH=..., but the Dockerfile only declares ARG GIT_COMMIT and ARG VERSION, so this build-arg is unused. Either add ARG GIT_BRANCH (and use it, e.g., as a label) or remove the extra build-arg to keep Docker builds self-consistent.
build-docker:
	@echo "building image ${BIN_NAME} ${VERSION} $(GIT_COMMIT)"
	docker build --build-arg VERSION=${VERSION} --build-arg GIT_COMMIT=$(GIT_COMMIT) --build-arg GIT_BRANCH=$(GIT_BRANCH) -t $(IMAGE_NAME):local .

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread {{cookiecutter.app_name}}/Makefile Outdated
Comment thread {{cookiecutter.app_name}}/.github/workflows/go.yml
Comment thread {{cookiecutter.app_name}}/Makefile Outdated
ankurs added 4 commits March 23, 2026 19:04
Ensures tool binaries (buf, golangci-lint, mockery) are installed into
GOBIN in addition to being available via go tool.
- Add golang.org/x/vuln/cmd/govulncheck to go.mod tool block
- Add make vulncheck target, run as prerequisite of make lint
- Add vulnerability check step to GitHub Actions lint job
- Bump go.opentelemetry.io/otel/* from v1.37.0 to v1.42.0 to fix
  GO-2026-4394 (arbitrary code execution via PATH hijacking)
Generates a full project with cookiecutter, then runs make build,
test, and lint to verify the template produces a working service.
- scripts/test-e2e.sh: generates project in temp dir, runs build/test/lint
- Makefile: make install (pip deps), make test (pytest), make test-e2e,
  make test-all
- Add --verbose to cookiecutter in CI for better error visibility
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 27 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

{{cookiecutter.app_name}}/Makefile:50

  • build-docker passes --build-arg GIT_BRANCH=..., but the Dockerfile doesn't declare or use ARG GIT_BRANCH (only GIT_COMMIT and VERSION). This is currently a no-op and can be confusing; either remove the unused build arg or add a corresponding ARG/LABEL in the Dockerfile if you intend to surface branch metadata in the image labels.
build-docker:
	@echo "building image ${BIN_NAME} ${VERSION} $(GIT_COMMIT)"
	docker build --build-arg VERSION=${VERSION} --build-arg GIT_COMMIT=$(GIT_COMMIT) --build-arg GIT_BRANCH=$(GIT_BRANCH) -t $(IMAGE_NAME):local .


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/test-e2e.sh
Comment thread .github/workflows/integration.yml
Comment thread {{cookiecutter.app_name}}/CLAUDE.md Outdated
- Replace CLAUDE.md content with comprehensive AGENTS.md (architecture,
  workflows, rules); CLAUDE.md imports via @AGENTS.md
- Fix git identity in CI workflow for post-gen hook git commit
- Fix GitHub Actions concurrency groups to allow parallel jobs
- Rename install target to deps (it only downloads modules)
@ankurs ankurs requested a review from Copilot March 23, 2026 13:42
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
scripts/test-e2e.sh (1)

17-18: Consider dynamically determining the project directory.

The hardcoded myapp path depends on cookiecutter.json having "name": "MyApp" which transforms to myapp. If the default name changes, this script silently breaks. Consider finding the generated directory dynamically.

More robust approach
 cookiecutter --no-input --verbose --output-dir "$TMPDIR" "$REPO_DIR"

-PROJECT_DIR="$TMPDIR/myapp"
+# Find the generated project directory (should be the only subdirectory)
+PROJECT_DIR=$(find "$TMPDIR" -mindepth 1 -maxdepth 1 -type d | head -1)
+if [[ -z "$PROJECT_DIR" ]]; then
+    echo "ERROR: No project directory generated"
+    exit 1
+fi
 cd "$PROJECT_DIR"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/test-e2e.sh` around lines 17 - 18, The script currently hardcodes
PROJECT_DIR="$TMPDIR/myapp" and then cd "$PROJECT_DIR", which will break if the
generated project folder name differs; update the logic in scripts/test-e2e.sh
to discover the created project directory dynamically (e.g., search $TMPDIR for
the single non-temp directory or the newest/first directory created) and assign
that path to PROJECT_DIR before the cd; reference the PROJECT_DIR variable and
the cd "$PROJECT_DIR" call when locating where to change the assignment so the
script works regardless of the cookiecutter "name" value.
tests/test_cookiecutter_generation.py (1)

207-211: Prefer next(iter(...)) over single-element slice.

Using next(iter(...)) is more idiomatic and avoids constructing a full list just to access the first element.

Suggested fix
     def test_custom_service_name(self, bake_project):
         project = bake_project({"service_name": "OrderService"})
-        proto_file = list((project / "proto").glob("*.proto"))[0]
+        proto_file = next(iter((project / "proto").glob("*.proto")))
         content = proto_file.read_text()
         assert "service OrderService {" in content
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_cookiecutter_generation.py` around lines 207 - 211, The test
creates proto_file by materializing a list then indexing [0], which
unnecessarily builds a list; change the retrieval to use an iterator like
next(iter((project / "proto").glob("*.proto"))) so test_custom_service_name uses
next(iter(...)) for proto_file (keeping bake_project and the subsequent
read_text/assert unchanged) to avoid allocating a full list when only the first
element is needed.
{{cookiecutter.app_name}}/AGENTS.md (1)

27-49: Add language hint to fenced code block.

Static analysis flags the architecture diagram code block as missing a language. While this is an ASCII tree diagram, adding text or plaintext satisfies linters and improves rendering consistency.

Suggested fix
-```
+```text
 .
 ├── main.go              # Entry point: initializes ColdBrew, registers services
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @{{cookiecutter.app_name}}/AGENTS.md around lines 27 - 49, Update the fenced
ASCII tree in AGENTS.md to include a language hint (e.g., add "text" or
"plaintext" after the opening triple-backticks) so the code block becomes a
labeled plaintext block; this change targets the existing ASCII diagram block
that begins with "." and the tree lines (e.g., "├── main.go") to satisfy linters
and ensure consistent rendering.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @{{cookiecutter.app_name}}/AGENTS.md:
- Around line 27-49: Update the fenced ASCII tree in AGENTS.md to include a
language hint (e.g., add "text" or "plaintext" after the opening
triple-backticks) so the code block becomes a labeled plaintext block; this
change targets the existing ASCII diagram block that begins with "." and the
tree lines (e.g., "├── main.go") to satisfy linters and ensure consistent
rendering.

In `@scripts/test-e2e.sh`:
- Around line 17-18: The script currently hardcodes PROJECT_DIR="$TMPDIR/myapp"
and then cd "$PROJECT_DIR", which will break if the generated project folder
name differs; update the logic in scripts/test-e2e.sh to discover the created
project directory dynamically (e.g., search $TMPDIR for the single non-temp
directory or the newest/first directory created) and assign that path to
PROJECT_DIR before the cd; reference the PROJECT_DIR variable and the cd
"$PROJECT_DIR" call when locating where to change the assignment so the script
works regardless of the cookiecutter "name" value.

In `@tests/test_cookiecutter_generation.py`:
- Around line 207-211: The test creates proto_file by materializing a list then
indexing [0], which unnecessarily builds a list; change the retrieval to use an
iterator like next(iter((project / "proto").glob("*.proto"))) so
test_custom_service_name uses next(iter(...)) for proto_file (keeping
bake_project and the subsequent read_text/assert unchanged) to avoid allocating
a full list when only the first element is needed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 85edb16d-e58d-4f4d-93b4-e63ea759d72a

📥 Commits

Reviewing files that changed from the base of the PR and between 4efb1ae and b4fad72.

📒 Files selected for processing (9)
  • .github/workflows/integration.yml
  • Makefile
  • scripts/test-e2e.sh
  • tests/test_cookiecutter_generation.py
  • {{cookiecutter.app_name}}/.github/workflows/go.yml
  • {{cookiecutter.app_name}}/AGENTS.md
  • {{cookiecutter.app_name}}/CLAUDE.md
  • {{cookiecutter.app_name}}/Makefile
  • {{cookiecutter.app_name}}/go.mod
✅ Files skipped from review due to trivial changes (1)
  • .github/workflows/integration.yml

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 24 out of 28 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread {{cookiecutter.app_name}}/service/service_test.go Outdated
Comment thread tox.ini Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@CONTRIBUTING.md`:
- Line 53: Remove the leading shell prompt from the example command in
CONTRIBUTING.md: replace the line containing "$ git clone
git@github.com:your_name_here/cookiecutter-coldbrew.git" with the plain command
"git clone git@github.com:your_name_here/cookiecutter-coldbrew.git" so the
markdown no longer includes the "$" prompt (fixes markdownlint MD014).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b1fc0bbb-5b0f-45c3-b345-c030c7c79d69

📥 Commits

Reviewing files that changed from the base of the PR and between b4fad72 and 62568c9.

📒 Files selected for processing (1)
  • CONTRIBUTING.md

Comment thread CONTRIBUTING.md
- Add cookiecutter and pytest explicitly to tox deps, use pytest command
- Move context.Background() and EchoRequest allocation outside benchmark loop
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 25 out of 29 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ankurs ankurs merged commit 2e0075c into master Mar 23, 2026
12 checks passed
@ankurs ankurs deleted the improve/cookiecutter-overhaul branch March 23, 2026 23:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants