pr-policy 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pr_policy-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +34 -0
- pr_policy-0.1.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- pr_policy-0.1.0/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
- pr_policy-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +20 -0
- pr_policy-0.1.0/.github/pr-policy.yml +40 -0
- pr_policy-0.1.0/.github/workflows/ci.yml +83 -0
- pr_policy-0.1.0/.github/workflows/release.yml +105 -0
- pr_policy-0.1.0/.gitignore +18 -0
- pr_policy-0.1.0/CHANGELOG.md +65 -0
- pr_policy-0.1.0/CODE_OF_CONDUCT.md +42 -0
- pr_policy-0.1.0/CONTRIBUTING.md +88 -0
- pr_policy-0.1.0/LICENSE +21 -0
- pr_policy-0.1.0/PKG-INFO +259 -0
- pr_policy-0.1.0/README.md +210 -0
- pr_policy-0.1.0/SECURITY.md +19 -0
- pr_policy-0.1.0/action.yml +120 -0
- pr_policy-0.1.0/docs/releasing.md +68 -0
- pr_policy-0.1.0/docs/repo-ready.md +99 -0
- pr_policy-0.1.0/pyproject.toml +56 -0
- pr_policy-0.1.0/src/pr_policy/__init__.py +5 -0
- pr_policy-0.1.0/src/pr_policy/__main__.py +4 -0
- pr_policy-0.1.0/src/pr_policy/cli.py +225 -0
- pr_policy-0.1.0/src/pr_policy/config.py +182 -0
- pr_policy-0.1.0/src/pr_policy/context.py +182 -0
- pr_policy-0.1.0/src/pr_policy/infer.py +224 -0
- pr_policy-0.1.0/src/pr_policy/report.py +83 -0
- pr_policy-0.1.0/src/pr_policy/rules.py +256 -0
- pr_policy-0.1.0/src/repo_ready/__init__.py +7 -0
- pr_policy-0.1.0/src/repo_ready/__main__.py +4 -0
- pr_policy-0.1.0/src/repo_ready/checks.py +412 -0
- pr_policy-0.1.0/src/repo_ready/cli.py +136 -0
- pr_policy-0.1.0/tests/conftest.py +62 -0
- pr_policy-0.1.0/tests/test_action.py +113 -0
- pr_policy-0.1.0/tests/test_checks.py +160 -0
- pr_policy-0.1.0/tests/test_cli.py +84 -0
- pr_policy-0.1.0/tests/test_config.py +109 -0
- pr_policy-0.1.0/tests/test_context.py +125 -0
- pr_policy-0.1.0/tests/test_infer.py +162 -0
- pr_policy-0.1.0/tests/test_policy_cli.py +190 -0
- pr_policy-0.1.0/tests/test_rules.py +209 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: A check reports the wrong result, or the tool misbehaves
|
|
4
|
+
title: ''
|
|
5
|
+
labels: bug
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
**What happened**
|
|
9
|
+
|
|
10
|
+
<!-- Which check was wrong, and what did it say? -->
|
|
11
|
+
|
|
12
|
+
**What you expected**
|
|
13
|
+
|
|
14
|
+
**How to reproduce**
|
|
15
|
+
|
|
16
|
+
<!-- The smallest directory layout that shows the problem is ideal:
|
|
17
|
+
|
|
18
|
+
my-repo/
|
|
19
|
+
LICENSE
|
|
20
|
+
docs/CONTRIBUTING.md
|
|
21
|
+
-->
|
|
22
|
+
|
|
23
|
+
**Output**
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
$ repo-ready . --format json
|
|
27
|
+
paste the output here
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Environment**
|
|
31
|
+
|
|
32
|
+
- repo-ready version (`repo-ready --version`):
|
|
33
|
+
- Python version (`python --version`):
|
|
34
|
+
- OS:
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: New check or feature
|
|
3
|
+
about: Suggest a check to add, or another way to use the output
|
|
4
|
+
title: ''
|
|
5
|
+
labels: enhancement
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
**What should it check, or what should it do**
|
|
9
|
+
|
|
10
|
+
**Why it matters to a maintainer**
|
|
11
|
+
|
|
12
|
+
<!-- A check earns its place if a project failing it is meaningfully worse off.
|
|
13
|
+
What goes wrong for a repo that doesn't have this? -->
|
|
14
|
+
|
|
15
|
+
**What should count as passing**
|
|
16
|
+
|
|
17
|
+
<!-- Which filenames, locations or contents? Remember that checks are filesystem-only:
|
|
18
|
+
repo-ready makes no network calls and has no dependencies. -->
|
|
19
|
+
|
|
20
|
+
**Roughly what should it be worth**
|
|
21
|
+
|
|
22
|
+
<!-- Weights total 100, so a new check means taking points from somewhere. -->
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
## What this changes
|
|
2
|
+
|
|
3
|
+
<!-- Describe the change and why it is needed. Replace this comment. -->
|
|
4
|
+
|
|
5
|
+
## Generative AI
|
|
6
|
+
|
|
7
|
+
This project asks you to say whether AI tools were involved. Either answer is
|
|
8
|
+
fine — we route on the disclosure, we do not judge it.
|
|
9
|
+
|
|
10
|
+
- [ ] I did not use generative AI tools for this change
|
|
11
|
+
- [ ] I used generative AI tools, and I have reviewed and understood the result
|
|
12
|
+
|
|
13
|
+
If you used a coding agent, record it in the commit with
|
|
14
|
+
`Assisted-by: <tool>:<model>`. Sign-off, where used, stays human.
|
|
15
|
+
|
|
16
|
+
## Checks
|
|
17
|
+
|
|
18
|
+
- [ ] `pytest` passes
|
|
19
|
+
- [ ] `ruff check .` and `ruff format --check .` pass
|
|
20
|
+
- [ ] New behaviour has a test
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# pr-policy configuration, generated by `pr-policy init` on 2026-09-12.
|
|
2
|
+
#
|
|
3
|
+
# Rules switched on by inference quote the line that justified them, so you can
|
|
4
|
+
# check the reasoning rather than take it on trust. Everything here is a
|
|
5
|
+
# starting point — edit it freely.
|
|
6
|
+
#
|
|
7
|
+
# Severities are `error`, `warn` or `info`. Nothing fails a build while
|
|
8
|
+
# `enforce` is false: pr-policy reports signals and leaves the decision to you.
|
|
9
|
+
|
|
10
|
+
version: 1
|
|
11
|
+
enforce: false
|
|
12
|
+
|
|
13
|
+
rules:
|
|
14
|
+
|
|
15
|
+
attribution:
|
|
16
|
+
enabled: true
|
|
17
|
+
severity: "warn"
|
|
18
|
+
forbid_agent_sign_off: true
|
|
19
|
+
prefer_assisted_by: true
|
|
20
|
+
require_signed_off: false
|
|
21
|
+
|
|
22
|
+
disclosure:
|
|
23
|
+
# CONTRIBUTING.md:38 — "You may use AI tools here."
|
|
24
|
+
enabled: true
|
|
25
|
+
severity: "warn"
|
|
26
|
+
|
|
27
|
+
template:
|
|
28
|
+
enabled: true
|
|
29
|
+
severity: "warn"
|
|
30
|
+
min_body_chars: 30
|
|
31
|
+
|
|
32
|
+
linked_issue:
|
|
33
|
+
enabled: false
|
|
34
|
+
severity: "warn"
|
|
35
|
+
|
|
36
|
+
size:
|
|
37
|
+
enabled: true
|
|
38
|
+
severity: "info"
|
|
39
|
+
max_lines: 1000
|
|
40
|
+
max_files: 100
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["**"]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ci-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
test:
|
|
18
|
+
name: test (${{ matrix.os }}, python ${{ matrix.python-version }})
|
|
19
|
+
runs-on: ${{ matrix.os }}
|
|
20
|
+
strategy:
|
|
21
|
+
fail-fast: false
|
|
22
|
+
matrix:
|
|
23
|
+
os: [ubuntu-latest]
|
|
24
|
+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
|
|
25
|
+
include:
|
|
26
|
+
# One run per other platform catches path and encoding bugs.
|
|
27
|
+
- os: windows-latest
|
|
28
|
+
python-version: "3.12"
|
|
29
|
+
- os: macos-latest
|
|
30
|
+
python-version: "3.12"
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v4
|
|
33
|
+
- uses: actions/setup-python@v5
|
|
34
|
+
with:
|
|
35
|
+
python-version: ${{ matrix.python-version }}
|
|
36
|
+
- name: Install
|
|
37
|
+
run: python -m pip install -e ".[dev]"
|
|
38
|
+
- name: Test
|
|
39
|
+
run: pytest -q
|
|
40
|
+
|
|
41
|
+
lint:
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
steps:
|
|
44
|
+
- uses: actions/checkout@v4
|
|
45
|
+
- uses: actions/setup-python@v5
|
|
46
|
+
with:
|
|
47
|
+
python-version: "3.12"
|
|
48
|
+
- name: Install
|
|
49
|
+
run: python -m pip install -e ".[dev]"
|
|
50
|
+
- name: Ruff
|
|
51
|
+
run: |
|
|
52
|
+
ruff check .
|
|
53
|
+
ruff format --check .
|
|
54
|
+
|
|
55
|
+
self-audit:
|
|
56
|
+
name: self-audit (repo-ready grades itself)
|
|
57
|
+
runs-on: ubuntu-latest
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/checkout@v4
|
|
60
|
+
- uses: actions/setup-python@v5
|
|
61
|
+
with:
|
|
62
|
+
python-version: "3.12"
|
|
63
|
+
- name: Install
|
|
64
|
+
run: python -m pip install -e .
|
|
65
|
+
- name: Audit this repository
|
|
66
|
+
run: repo-ready . --min-score 100
|
|
67
|
+
|
|
68
|
+
self-policy:
|
|
69
|
+
name: self-policy (pr-policy checks its own pull requests)
|
|
70
|
+
runs-on: ubuntu-latest
|
|
71
|
+
if: github.event_name == 'pull_request'
|
|
72
|
+
permissions:
|
|
73
|
+
contents: read
|
|
74
|
+
pull-requests: write
|
|
75
|
+
steps:
|
|
76
|
+
- uses: actions/checkout@v4
|
|
77
|
+
with:
|
|
78
|
+
# pr-policy reads commit trailers, so it needs the branch history.
|
|
79
|
+
fetch-depth: 0
|
|
80
|
+
- name: Check this pull request against our own policy
|
|
81
|
+
uses: ./
|
|
82
|
+
with:
|
|
83
|
+
comment: "true"
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v[0-9]+.[0-9]+.[0-9]+"]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
name: Build and verify
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
|
|
21
|
+
- name: Install
|
|
22
|
+
run: python -m pip install --quiet build ".[dev]"
|
|
23
|
+
|
|
24
|
+
- name: The tag must match the packaged version
|
|
25
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
26
|
+
run: |
|
|
27
|
+
set -euo pipefail
|
|
28
|
+
tag="${GITHUB_REF_NAME#v}"
|
|
29
|
+
version=$(python -c "import importlib.metadata as m; print(m.version('pr-policy'))")
|
|
30
|
+
if [ "$tag" != "$version" ]; then
|
|
31
|
+
echo "::error::Tag $GITHUB_REF_NAME does not match package version $version" >&2
|
|
32
|
+
exit 1
|
|
33
|
+
fi
|
|
34
|
+
echo "Releasing $version"
|
|
35
|
+
|
|
36
|
+
- name: Test before shipping
|
|
37
|
+
run: |
|
|
38
|
+
pytest -q
|
|
39
|
+
ruff check .
|
|
40
|
+
repo-ready . --min-score 100
|
|
41
|
+
|
|
42
|
+
- name: Build
|
|
43
|
+
run: python -m build
|
|
44
|
+
|
|
45
|
+
- uses: actions/upload-artifact@v4
|
|
46
|
+
with:
|
|
47
|
+
name: distributions
|
|
48
|
+
path: dist/
|
|
49
|
+
|
|
50
|
+
publish:
|
|
51
|
+
name: Publish to PyPI
|
|
52
|
+
needs: build
|
|
53
|
+
runs-on: ubuntu-latest
|
|
54
|
+
environment:
|
|
55
|
+
name: pypi
|
|
56
|
+
url: https://pypi.org/p/pr-policy
|
|
57
|
+
permissions:
|
|
58
|
+
id-token: write # trusted publishing; no API token is stored anywhere
|
|
59
|
+
steps:
|
|
60
|
+
- uses: actions/download-artifact@v4
|
|
61
|
+
with:
|
|
62
|
+
name: distributions
|
|
63
|
+
path: dist/
|
|
64
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
65
|
+
|
|
66
|
+
github-release:
|
|
67
|
+
name: Publish the GitHub release
|
|
68
|
+
needs: publish
|
|
69
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
70
|
+
runs-on: ubuntu-latest
|
|
71
|
+
permissions:
|
|
72
|
+
contents: write
|
|
73
|
+
steps:
|
|
74
|
+
- uses: actions/checkout@v4
|
|
75
|
+
- uses: actions/download-artifact@v4
|
|
76
|
+
with:
|
|
77
|
+
name: distributions
|
|
78
|
+
path: dist/
|
|
79
|
+
- name: Create the release
|
|
80
|
+
env:
|
|
81
|
+
GH_TOKEN: ${{ github.token }}
|
|
82
|
+
run: |
|
|
83
|
+
gh release create "$GITHUB_REF_NAME" dist/* \
|
|
84
|
+
--title "$GITHUB_REF_NAME" \
|
|
85
|
+
--notes "See [CHANGELOG.md](CHANGELOG.md) for what changed."
|
|
86
|
+
|
|
87
|
+
major-tag:
|
|
88
|
+
name: Move the major version tag
|
|
89
|
+
needs: publish
|
|
90
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
91
|
+
runs-on: ubuntu-latest
|
|
92
|
+
permissions:
|
|
93
|
+
contents: write
|
|
94
|
+
steps:
|
|
95
|
+
- uses: actions/checkout@v4
|
|
96
|
+
- name: Point v<major> at this release
|
|
97
|
+
run: |
|
|
98
|
+
set -euo pipefail
|
|
99
|
+
# `uses: rodny90/pr-policy@v1` should follow the newest 1.x release,
|
|
100
|
+
# which is the convention every published action uses.
|
|
101
|
+
major="${GITHUB_REF_NAME%%.*}"
|
|
102
|
+
git config user.name "github-actions[bot]"
|
|
103
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
104
|
+
git tag -f "$major"
|
|
105
|
+
git push -f origin "$major"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
.pytest_cache/
|
|
4
|
+
.ruff_cache/
|
|
5
|
+
.mypy_cache/
|
|
6
|
+
.coverage
|
|
7
|
+
htmlcov/
|
|
8
|
+
build/
|
|
9
|
+
dist/
|
|
10
|
+
*.egg-info/
|
|
11
|
+
.venv/
|
|
12
|
+
venv/
|
|
13
|
+
.env
|
|
14
|
+
.DS_Store
|
|
15
|
+
|
|
16
|
+
# Written into the workspace by the pr-policy action
|
|
17
|
+
policy-comment.md
|
|
18
|
+
policy-findings.json
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to
|
|
5
|
+
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.1.0] - 2026-09-12
|
|
10
|
+
|
|
11
|
+
First release. Two commands: `pr-policy`, which checks pull requests against the
|
|
12
|
+
policy a project wrote down, and `repo-ready`, which checks that the policy was
|
|
13
|
+
written down at all.
|
|
14
|
+
|
|
15
|
+
### Added — pr-policy
|
|
16
|
+
|
|
17
|
+
- **`attribution`** — enforces the [Linux kernel's AI attribution
|
|
18
|
+
policy](https://docs.kernel.org/process/coding-assistants.html) on commit trailers:
|
|
19
|
+
a coding agent must never add `Signed-off-by:` (only a human can certify the DCO),
|
|
20
|
+
tool assistance belongs in `Assisted-by:` rather than `Co-authored-by:`, and
|
|
21
|
+
optionally every commit must be signed off. Matching is on identities an agent
|
|
22
|
+
writes about itself, never on the code.
|
|
23
|
+
- **`disclosure`** — checks that the project's AI-disclosure checkbox was answered.
|
|
24
|
+
Either answer passes; the rule fires only when the question was ignored.
|
|
25
|
+
- **`template`** — checks the description is not empty and that the template's
|
|
26
|
+
`<!-- ... -->` prompts were replaced.
|
|
27
|
+
- **`linked_issue`** — checks the body references an issue with a closing keyword.
|
|
28
|
+
- **`size`** — reports diffs over the project's line and file guidelines.
|
|
29
|
+
- **`pr-policy init`** — generates a starter config by reading `CONTRIBUTING.md`,
|
|
30
|
+
the pull request template and `AGENTS.md`, quoting the line behind every
|
|
31
|
+
inference so the maintainer can check the reasoning. Inference works over
|
|
32
|
+
sentences, skips prohibitions ("agents must never sign off" is not a sign-off
|
|
33
|
+
policy), and requires requirement-shaped language before enabling a rule.
|
|
34
|
+
- Reporting-only by default: nothing fails a build until `enforce: true` or `--strict`.
|
|
35
|
+
- Three output formats: `text` (coloured on a terminal, honouring `NO_COLOR`),
|
|
36
|
+
`json`, and `markdown` for posting as a pull request comment.
|
|
37
|
+
- A composite GitHub Action that posts a single sticky comment and updates it on
|
|
38
|
+
each push. It resolves the base branch with an explicit refspec, so it works on
|
|
39
|
+
the default shallow checkout rather than only with `fetch-depth: 0`.
|
|
40
|
+
- Rules that read the pull request body are skipped, not failed, when no title or
|
|
41
|
+
body is available — an absent body is not an empty one.
|
|
42
|
+
- Strict configuration validation: unknown rules and unknown options are errors,
|
|
43
|
+
so a typo never quietly disables a rule.
|
|
44
|
+
|
|
45
|
+
### Added — release tooling
|
|
46
|
+
|
|
47
|
+
- A tag-driven release workflow publishing to PyPI through
|
|
48
|
+
[trusted publishing](https://docs.pypi.org/trusted-publishers/), so no API token
|
|
49
|
+
is stored in the repository. It refuses to publish when the tag and the packaged
|
|
50
|
+
version disagree, and runs the full suite before building.
|
|
51
|
+
- The `v<major>` tag moves to each new release, so `uses: rodny90/pr-policy@v0`
|
|
52
|
+
follows the newest 0.x.
|
|
53
|
+
- The action's shell logic is covered by tests that lift the `run:` block out of
|
|
54
|
+
`action.yml` and execute it, rather than leaving CI to run it first.
|
|
55
|
+
|
|
56
|
+
### Added — repo-ready
|
|
57
|
+
|
|
58
|
+
- Twelve weighted repository readiness checks, an A–F grade, and a concrete
|
|
59
|
+
suggested fix for every failure, ordered by weight.
|
|
60
|
+
- `--min-score N` to gate CI, plus `json` and `markdown` output.
|
|
61
|
+
- Case-insensitive file lookup that also searches `.github/` and `docs/`, and skips
|
|
62
|
+
vendored directories so a dependency's tests cannot make a repository look tested.
|
|
63
|
+
|
|
64
|
+
[Unreleased]: https://github.com/rodny90/pr-policy/compare/v0.1.0...HEAD
|
|
65
|
+
[0.1.0]: https://github.com/rodny90/pr-policy/releases/tag/v0.1.0
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
|
6
|
+
|
|
7
|
+
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
|
|
8
|
+
|
|
9
|
+
## Our Standards
|
|
10
|
+
|
|
11
|
+
Examples of behavior that contributes to a positive environment:
|
|
12
|
+
|
|
13
|
+
* Demonstrating empathy and kindness toward other people
|
|
14
|
+
* Being respectful of differing opinions, viewpoints, and experiences
|
|
15
|
+
* Giving and gracefully accepting constructive feedback
|
|
16
|
+
* Accepting responsibility and apologizing to those affected by our mistakes
|
|
17
|
+
* Focusing on what is best for the overall community
|
|
18
|
+
|
|
19
|
+
Examples of unacceptable behavior:
|
|
20
|
+
|
|
21
|
+
* The use of sexualized language or imagery, and sexual attention or advances of any kind
|
|
22
|
+
* Trolling, insulting or derogatory comments, and personal or political attacks
|
|
23
|
+
* Public or private harassment
|
|
24
|
+
* Publishing others' private information, such as a physical or email address, without their explicit permission
|
|
25
|
+
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
|
26
|
+
|
|
27
|
+
## Enforcement Responsibilities
|
|
28
|
+
|
|
29
|
+
Project maintainers are responsible for clarifying and enforcing these standards and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
|
|
30
|
+
|
|
31
|
+
## Scope
|
|
32
|
+
|
|
33
|
+
This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces.
|
|
34
|
+
|
|
35
|
+
## Enforcement
|
|
36
|
+
|
|
37
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the project maintainers by opening a report through [GitHub's private reporting](https://github.com/rodny90/pr-policy/security/advisories/new) or contacting a maintainer directly. All complaints will be reviewed and investigated promptly and fairly, and the privacy and security of the reporter will be respected.
|
|
38
|
+
|
|
39
|
+
## Attribution
|
|
40
|
+
|
|
41
|
+
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.1, available at
|
|
42
|
+
https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Contributing to pr-policy
|
|
2
|
+
|
|
3
|
+
Thanks for taking the time. Bug reports, new checks and documentation fixes are all welcome.
|
|
4
|
+
|
|
5
|
+
## Getting set up
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/rodny90/pr-policy
|
|
9
|
+
cd pr-policy
|
|
10
|
+
python -m pip install -e ".[dev]"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Running the checks locally
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pytest # the test suite
|
|
17
|
+
ruff check . # lint
|
|
18
|
+
ruff format --check .
|
|
19
|
+
repo-ready . --min-score 100 # repo-ready audits this repository
|
|
20
|
+
pr-policy check --base origin/main # pr-policy checks your own branch
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
CI runs exactly these four commands, so a clean local run means a green pull request.
|
|
24
|
+
|
|
25
|
+
## Adding a rule to pr-policy
|
|
26
|
+
|
|
27
|
+
Rules live in `src/pr_policy/rules.py`. Each is a function taking a `PullRequest`
|
|
28
|
+
and a `RuleConfig` and yielding `Finding` objects.
|
|
29
|
+
|
|
30
|
+
1. Write the function, then register it in `RULES` and add its defaults to
|
|
31
|
+
`DEFAULTS` in `src/pr_policy/config.py`.
|
|
32
|
+
2. If the rule reads the pull request title or body, add it to `NEEDS_METADATA`
|
|
33
|
+
so it is skipped rather than failed when no body is available.
|
|
34
|
+
3. **Keep it deterministic.** A rule may check whether a trailer exists, whether a
|
|
35
|
+
box is ticked, whether a reference resolves. A rule may never try to infer
|
|
36
|
+
whether a human or a model wrote something. That boundary is the project.
|
|
37
|
+
4. Default new rules to `warn`, and default anything project-specific to
|
|
38
|
+
`enabled: false` until `pr-policy init` can infer it from documentation.
|
|
39
|
+
5. Add tests for the passing and the failing case, and a row to the rules table
|
|
40
|
+
in `README.md`.
|
|
41
|
+
|
|
42
|
+
## Adding a check to repo-ready
|
|
43
|
+
|
|
44
|
+
Checks live in `src/repo_ready/checks.py`. Each one is a function taking a `Repo` and returning `(passed, detail)`, registered as a `Check` in the `CHECKS` tuple.
|
|
45
|
+
|
|
46
|
+
1. Write the function. Keep it filesystem-only — `repo-ready` makes no network calls and has no dependencies, and both of those are deliberate.
|
|
47
|
+
2. Add a `Check(...)` entry with an `id`, a `title`, a `weight` and a `fix`. The `fix` is what the user reads when the check fails, so make it a concrete instruction rather than a restatement of the problem.
|
|
48
|
+
3. **Weights must still total 100.** Adjust the existing weights in the same pull request and say why in the description; `test_weights_sum_to_one_hundred` will fail otherwise.
|
|
49
|
+
4. Add tests for both the passing and the failing case.
|
|
50
|
+
5. Add a row to the check table in `README.md`, and a line to `CHANGELOG.md`.
|
|
51
|
+
|
|
52
|
+
A check should earn its weight. Ask whether a maintainer who fails it is meaningfully worse off — if not, it is probably a lint rule rather than a readiness check.
|
|
53
|
+
|
|
54
|
+
## AI-assisted contributions
|
|
55
|
+
|
|
56
|
+
You may use AI tools here. We ask two things, both of which this project's own
|
|
57
|
+
tooling checks:
|
|
58
|
+
|
|
59
|
+
1. **Disclose it.** The pull request template has a checkbox. Tick whichever
|
|
60
|
+
option is true — either answer is accepted, the box only needs an answer.
|
|
61
|
+
2. **Attribute it correctly.** Record tool assistance with an `Assisted-by:`
|
|
62
|
+
trailer, following the [Linux kernel's
|
|
63
|
+
convention](https://docs.kernel.org/process/coding-assistants.html):
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
Assisted-by: Claude:claude-opus-5
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
An agent must never add a `Signed-off-by:` trailer. Only a human can certify
|
|
70
|
+
the Developer Certificate of Origin, and only a human can take
|
|
71
|
+
responsibility for a change.
|
|
72
|
+
|
|
73
|
+
Whoever opens the pull request is responsible for the code in it, however it
|
|
74
|
+
was written.
|
|
75
|
+
|
|
76
|
+
## Pull requests
|
|
77
|
+
|
|
78
|
+
- One logical change per pull request.
|
|
79
|
+
- Keep the public output formats stable: the JSON shape is something people script against, so a change to it needs a note in `CHANGELOG.md` under a new version.
|
|
80
|
+
- Describe the behaviour change, not the diff.
|
|
81
|
+
|
|
82
|
+
## Reporting bugs
|
|
83
|
+
|
|
84
|
+
Open an issue using the bug report template. A repository that reproduces the wrong result is worth more than a description of it — even a three-file example is enough.
|
|
85
|
+
|
|
86
|
+
## Code of conduct
|
|
87
|
+
|
|
88
|
+
This project follows the [Contributor Covenant](CODE_OF_CONDUCT.md).
|
pr_policy-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 rodny90
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|