Skip to content

Commit 620497c

Browse files
committed
ci: make the template the source of the org standard
setup_repo.py now configures a new repository to the full standard, not just branch protection: environments and Pages where the workflows use them, read-only workflow tokens, squash/merge-commit only with branches deleted on merge, secret scanning + push protection + Dependabot security updates + private vulnerability reporting, topics from pyproject keywords, and a `master` ruleset (pull requests only, no force-push or deletion, "All checks passed" required) in place of classic protection. It is idempotent and is what the existing repositories were aligned with. The template gets a CI of its own: render with copier and run the generated project's gate, aggregated into "All checks passed" so the same ruleset can apply here. Its own CONTRIBUTING, CODE_OF_CONDUCT and SECURITY are added, and the generated SECURITY.md becomes the org-wide one (draft advisory link, no version table that goes stale).
1 parent dd36fc2 commit 620497c

8 files changed

Lines changed: 348 additions & 80 deletions

File tree

.github/workflows/ci.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [master]
6+
pull_request:
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
# The only thing that can be wrong with a template is what it generates, so the
13+
# check is the generated project's own gate: render with the defaults, then run
14+
# exactly what a new library's CI would run.
15+
render:
16+
name: Render the template and run the generated gate
17+
runs-on: ubuntu-latest
18+
steps:
19+
- uses: actions/checkout@v7
20+
- uses: astral-sh/setup-uv@v7
21+
22+
- name: Render with copier
23+
run: |
24+
uvx --with jinja2-time copier copy --defaults --trust --vcs-ref HEAD \
25+
--data project_name=demo-lib \
26+
--data project_slug=demo-lib \
27+
--data package_name=demo_lib \
28+
--data project_description="Demo library rendered from the template" \
29+
--data author_name="Bedrock Python" \
30+
--data author_email="maintainers@example.com" \
31+
. "${RUNNER_TEMP}/demo-lib"
32+
33+
- name: The generated project passes its own gate
34+
working-directory: ${{ runner.temp }}/demo-lib
35+
run: |
36+
uv sync --group dev --all-extras
37+
make check
38+
make test-unit
39+
uv build
40+
41+
all-checks-passed:
42+
name: All checks passed
43+
if: always()
44+
needs: [render]
45+
runs-on: ubuntu-latest
46+
steps:
47+
- name: Every job above succeeded
48+
run: echo '${{ toJSON(needs) }}' | jq -e 'all(.[]; .result == "success")'

CODE_OF_CONDUCT.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Contributor Covenant Code of Conduct
2+
3+
## Our Pledge
4+
5+
We as members, contributors, and leaders pledge to make participation in our
6+
community a harassment-free experience for everyone, regardless of age, body
7+
size, visible or invisible disability, ethnicity, sex characteristics, gender
8+
identity and expression, level of experience, education, socio-economic status,
9+
nationality, personal appearance, race, caste, color, religion, or sexual
10+
identity and orientation.
11+
12+
We pledge to act and interact in ways that contribute to an open, welcoming,
13+
diverse, inclusive, and healthy community.
14+
15+
## Our Standards
16+
17+
Examples of behavior that contributes to a positive environment:
18+
19+
- Demonstrating empathy and kindness toward other people
20+
- Being respectful of differing opinions, viewpoints, and experiences
21+
- Giving and gracefully accepting constructive feedback
22+
- Accepting responsibility and apologizing to those affected by our mistakes
23+
- Focusing on what is best not just for us as individuals, but for the overall community
24+
25+
Examples of unacceptable behavior:
26+
27+
- The use of sexualized language or imagery, and sexual attention or advances of any kind
28+
- Trolling, insulting or derogatory comments, and personal or political attacks
29+
- Public or private harassment
30+
- Publishing others' private information without explicit permission
31+
- Other conduct which could reasonably be considered inappropriate in a professional setting
32+
33+
## Enforcement Responsibilities
34+
35+
Project maintainers are responsible for clarifying and enforcing standards of acceptable
36+
behavior and will take appropriate and fair corrective action in response to any behavior
37+
deemed inappropriate, threatening, offensive, or harmful.
38+
39+
## Scope
40+
41+
This Code of Conduct applies within all community spaces, and also applies when
42+
an individual is officially representing the community in public spaces.
43+
44+
## Enforcement
45+
46+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to
47+
the project maintainer at **shalaevad.alexey@gmail.com**.
48+
49+
All complaints will be reviewed and investigated promptly and fairly.
50+
51+
## Attribution
52+
53+
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/),
54+
version 2.1.

CONTRIBUTING.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Contributing to python-library-template
2+
3+
This repository is the Copier template every bedrock-python library starts from, so a
4+
change here lands in the next library generated — and, through `copier update`, in the
5+
existing ones. Treat it like library code.
6+
7+
## What a change looks like
8+
9+
- Files under `template/` are what gets generated; `.jinja` files are rendered by Copier,
10+
everything else is copied as is. Copier's own variables come from `copier.yml`.
11+
- `scripts/setup_repo.py` configures a freshly created GitHub repository to the org
12+
standard (ruleset on `master`, security settings, merge settings, topics). It is run
13+
once per new library and is also what keeps the existing repositories aligned.
14+
- `NEW_LIBRARY_CHECKLIST.md.jinja` and `.claude/LIBRARY_CREATION.md` are the operator
15+
and agent instructions. Keep them in step with what the template actually does.
16+
17+
## Checking a change
18+
19+
Render the template and run the generated project's own gate — that is exactly what CI
20+
does:
21+
22+
```bash
23+
uvx --with jinja2-time copier copy --defaults --trust --vcs-ref HEAD \
24+
--data project_name=demo-lib --data project_slug=demo-lib --data package_name=demo_lib \
25+
--data project_description="Demo" --data author_name="You" --data author_email="you@example.com" \
26+
. /tmp/demo-lib
27+
cd /tmp/demo-lib && uv sync --group dev --all-extras && make check && make test-unit && uv build
28+
```
29+
30+
A change to `setup_repo.py` is checked by running it against a throwaway repository, or
31+
against one of the org's repositories with `--help` first: the script is idempotent, so a
32+
re-run on an already configured repository is a no-op.
33+
34+
## Commit messages
35+
36+
[Conventional Commits](https://www.conventionalcommits.org/): `feat:` for something new in
37+
the generated project, `fix:` for a bug in it, `ci:` for workflow and setup-script
38+
changes, `docs:` for the instructions. There is no release; the template is consumed by
39+
git ref.
40+
41+
## Pull requests
42+
43+
Branch from `master`, open a PR against it. `master` takes pull requests only and needs
44+
the "All checks passed" status.

NEW_LIBRARY_CHECKLIST.md.jinja

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,15 @@ then run from the template repo:
3131
python /path/to/python-library-template/scripts/setup_repo.py {{ github_org }}/{{ project_slug }}
3232
```
3333

34-
This configures:
35-
- GitHub environments (`pypi`, `github-pages`)
36-
- GitHub Pages (source: GitHub Actions)
37-
- Actions permissions (allow creating PRs for Release Please)
38-
- Branch protection on `master` requiring `All checks passed`
34+
This configures (idempotent, re-run any time):
35+
- GitHub environments (`pypi`, `github-pages`) and Pages (source: GitHub Actions)
36+
- Actions: read-only workflow token by default, Release Please may open PRs
37+
- Merge settings: squash or merge commit, branches deleted on merge, no wiki/projects,
38+
docs site as the homepage, topics from `pyproject` keywords
39+
- Security: secret scanning, push protection, Dependabot alerts + security updates,
40+
private vulnerability reporting
41+
- A `master` ruleset: pull requests only, no force-push or deletion, `All checks passed`
42+
required (left out with a warning if CI has not reported yet — re-run after it has)
3943

4044
## Step 4 — PyPI Trusted Publisher (manual)
4145

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,16 @@ make check
4242

4343
Then:
4444
1. Create a GitHub repo: `gh repo create bedrock-python/my-library --public`
45-
2. **Configure repo** (run once, then delete):
45+
2. **Configure repo** (after the first CI pass, then delete the script):
4646
```bash
4747
python scripts/setup_repo.py bedrock-python/my-library
4848
git rm scripts/setup_repo.py .claude/LIBRARY_CREATION.md
4949
```
50+
Idempotent. Sets the org standard: `pypi`/`github-pages` environments and Pages,
51+
read-only workflow tokens, squash/merge-commit only with branches deleted on merge,
52+
secret scanning + push protection + Dependabot security updates + private
53+
vulnerability reporting, topics from `pyproject` keywords, and a `master` ruleset
54+
(pull requests only, no force-push or deletion, "All checks passed" required).
5055
3. **Push** (⚠️ **no** `Co-Authored-By:` in commits!):
5156
```bash
5257
git init && git add . && git commit -m "feat: initial release" && git push -u origin master

SECURITY.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Security Policy
2+
3+
## Reporting a vulnerability
4+
5+
**Please do not report security vulnerabilities via public GitHub Issues.**
6+
7+
Report it privately through GitHub, by
8+
[opening a draft security advisory](https://github.com/bedrock-python/python-library-template/security/advisories/new),
9+
or send an email to **shalaevad.alexey@gmail.com**. Either way, include:
10+
11+
- Description of the vulnerability
12+
- Steps to reproduce
13+
- Potential impact and affected versions
14+
15+
We aim to acknowledge reports within **48 hours** and provide a fix within **7 days**
16+
for critical issues.
17+
18+
Once the fix is released, we will credit you in the release notes unless you prefer
19+
to remain anonymous.

0 commit comments

Comments
 (0)