Skip to main content

repo-policy

Lightweight, declarative repository governance for GitHub. Define expected branch protection and ruleset configuration in YAML; audit, preview, and apply it locally or in CI.

Not a Terraform replacement — no state file, no backend. repo-policy is safe to adopt incrementally on a live repository: by default it only ever touches branches you declare, and never deletes anything you didn't ask it to manage.

Install

pip install repo-policy

Quick start

# policy.yml
version: 1

branches:
  main:
    pull_requests:
      required: true
      approvals: 2
      code_owner_review: true
    status_checks:
      required: [build, test]
    signed_commits: true
    linear_history: true
    allow_force_push: false
    allow_deletion: false
repo-policy validate
repo-policy audit --repo acme/widgets
repo-policy plan --repo acme/widgets
repo-policy apply --repo acme/widgets

CLI Reference

Command Flags Behavior Exit codes
validate --config (default policy.yml) Parses and schema-validates the policy file only; no network calls 0 valid, 2 invalid
audit --config, --repo, --token Read-only compliance check 0 compliant, 1 drift found, 2 invalid config, 3 API/auth error
plan --config, --repo, --token Same diff engine as audit, renders a human-readable +/-/~/✓ preview same as audit
apply --config, --repo, --token Executes only the changes plan would show 0 success (incl. no-op), 2 invalid config, 3 API/auth error

Token resolution order: --tokenGITHUB_TOKENGH_TOKEN. Repo resolution order: --repo owner/name$GITHUB_REPOSITORY → the local git origin remote.

GitHub Action

- uses: shipsolid/repo-policy@v0
  env:
    GITHUB_TOKEN: ${{ secrets.REPO_POLICY_TOKEN }}
  with:
    config: .github/repository-policy.yml
    mode: audit

secrets.GITHUB_TOKEN will not work here, in any workflow, no matter what permissions: you grant it — confirmed against a real repo. GitHub Actions' automatically-generated token has no permission scope covering branch protection or ruleset administration; that's a platform constraint, not something a workflow can opt into. Create a PAT with repo scope (classic) or Administration: Read and write (fine-grained), store it as a repository secret — REPO_POLICY_TOKEN above is just an example name — and reference that secret instead.

The floating tag tracks the current major version (v0 until a 1.0.0 release ships), the same convention actions/checkout and similar Actions use.

How it works

Every declared branch is diffed against live GitHub state and reconciled through one of two backends, selected per branch with enforcement: branch_protection | ruleset (default branch_protection). See ARCHITECTURE.md for the full data flow, safety model, and known v1 limitations, and docs/adrs/ for why it's built this way.

Exit codes

Code Meaning
0 Success / compliant / no-op
1 Drift detected (audit/plan)
2 Invalid policy.yml
3 GitHub API or auth error

More docs

License

MIT

Release files for repo-policy 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for repo-policy 0.2.0
File Size Uploaded
repo_policy-0.2.0.tar.gz 62.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for repo-policy 0.2.0
File Interpreter ABI Platform
repo_policy-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 81.3 kB

Release files / repo_policy-0.2.0.tar.gz

Download URL repo_policy-0.2.0.tar.gz
Size 62.3 kB
Tags Source
SHA-256 checksum
How to use checksums
2c0aa630b17e7acfd95050ba6c17f5e09ecb1e687d3184075f264f9d18bbcb91
BLAKE2b-256 checksum
How to use checksums
366ce960827f68b4708355e633506b9bde57ba9b1f0eb0e9cbd3cc8b69f11f57
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 19, 2026.

Transparency log

Release files / repo_policy-0.2.0-py3-none-any.whl

Download URL repo_policy-0.2.0-py3-none-any.whl
Size 19.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7ff2c33de87fae0cc7a946c0efe14513011a29e6df6fca9fa72866ef30913d3b
BLAKE2b-256 checksum
How to use checksums
a21e3514b69a48dc65b266b9ca175a72edb1b5ed8b0bce40d4fba4b644555066
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 19, 2026.

Transparency log

Release history Release notifications | RSS feed

0.5.0

2 release files

0.4.10

2 release files

0.4.9

2 release files

0.4.7

2 release files

0.4.6

2 release files

0.4.5

2 release files

0.4.4

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

This release

0.2.0 This release

2 release files

0.1.4

2 release files

0.1.3

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page