Skip to content

Commit d1126f4

Browse files
authored
CONTRIBUTING.md: Document cookiecutter workflow (#493)
Add detailed cookiecutter template modification workflow to CONTRIBUTING.md. This includes adding steps to the migration script.
2 parents a72bd53 + 8459738 commit d1126f4

1 file changed

Lines changed: 78 additions & 11 deletions

File tree

CONTRIBUTING.md

Lines changed: 78 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Or you can use `nox`:
5353
nox -R -s pytest -- test/test_*.py
5454
```
5555

56-
The same appliest to `pylint` or `mypy` for example:
56+
The same applies to `pylint` or `mypy` for example:
5757

5858
```sh
5959
nox -R -s pylint -- test/test_*.py
@@ -78,27 +78,94 @@ Failures in the golden tests could indicate two things:
7878
2. The generated files don't match the golden files because an intended change
7979
was introduced. In this case, the golden files need to be updated.
8080

81-
In the latter case, manually updating files is complicated and error-prone, so
82-
a simpler (though hacky) way is provided.
81+
In the latter case, manually updating files is complicated and error-prone,
82+
please consult [Update the golden test
83+
fixtures](#2-update-the-golden-test-fixtures) below for the recommended way to
84+
update the golden files.
8385

84-
To update the golden files, simply run `pytest` for the tests using golden
85-
files setting the environment variable `UPDATE_GOLDEN` to `1`:
86+
### Modifying Cookiecutter Templates
87+
88+
When you need to make changes to the cookiecutter templates (located in
89+
`cookiecutter/{{cookiecutter.github_repo_name}}/`), there's a specific workflow
90+
to follow. The templates support different project types (actor, api, app, lib,
91+
model) using Jinja2 conditional sections.
92+
93+
#### 1. Make your template changes
94+
95+
Edit the files in the `cookiecutter/` directory. Keep in mind that some files
96+
have conditional sections for different project types.
97+
98+
#### 2. Update the golden test fixtures
99+
100+
After modifying templates, you need to regenerate the golden files so the tests
101+
pass:
86102

87103
```sh
88104
UPDATE_GOLDEN=1 pytest tests/integration/test_cookiecutter_generation.py::test_golden
89105
```
90106

91-
This will replace the existing golden files (stored in `tests_golden/`) with
92-
the newly generated files.
107+
If you renamed or removed files, it's safest to wipe the golden directory first:
93108

94-
Note that if you rename, or remove golden files, you should also manually
95-
remove the files that were affected. An easy way to make sure there are no old
96-
unused golden files left is to just wipe the whole `tests_golden/` directory
97-
before running `pytest` to generate the new ones.
109+
```sh
110+
rm -rf tests_golden/
111+
UPDATE_GOLDEN=1 pytest tests/integration/test_cookiecutter_generation.py::test_golden
112+
```
98113

99114
**Please ensure that all introduced changes are intended before updating the
100115
golden files.**
101116

117+
#### 3. Write a migration script
118+
119+
Existing projects using these templates need a way to migrate to the new
120+
version. Update `cookiecutter/migrate.py` to handle this migration. The script
121+
is reset to a blank template (from `.github/cookiecutter-migrate.template.py`)
122+
after each release.
123+
124+
A few guidelines for migration scripts:
125+
126+
- Make them idempotent (safe to run multiple times)
127+
- Print clear messages about what's being done
128+
- Use the helper functions: `replace_file_contents_atomically()` for simple
129+
replacements, `apply_patch()` for more complex changes
130+
131+
For changes that can't be automated (like GitHub repository settings that
132+
require admin permissions, or changes that would make the script overly
133+
complex), use the `manual_step()` function to clearly communicate to users
134+
what they need to do manually:
135+
136+
```python
137+
manual_step(
138+
"Update branch protection rules in GitHub settings:\n"
139+
" Settings > Branches > Enable 'Require status checks'"
140+
)
141+
```
142+
143+
#### 4. Validate with this repository
144+
145+
Run the migration script on this repository itself to make sure it works:
146+
147+
```sh
148+
python3 cookiecutter/migrate.py
149+
git diff .github/workflows/ # Check the changes look correct
150+
```
151+
152+
Note that some changes (e.g., API-specific features like protolint) won't be
153+
testable on this repository since it's a `lib` type project.
154+
155+
#### 5. Update the release notes
156+
157+
Add an entry to `RELEASE_NOTES.md` describing what changed in the templates.
158+
159+
#### 6. Commit separately
160+
161+
Create two separate commits to keep the history clean:
162+
163+
1. First commit: the template changes, migration script, golden tests, and
164+
release notes
165+
2. Second commit: the changes to this repository from running the migration
166+
167+
This separation makes it easier to review and understand what changed.
168+
102169
### Building the documentation
103170

104171
To build the documentation, first install the dependencies (if you didn't

0 commit comments

Comments
 (0)