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.4.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.4.0
File Size Uploaded
repo_policy-0.4.0.tar.gz 92.0 kB Details

Built distribution (wheel)

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

Total release size: 115.0 kB

Release files / repo_policy-0.4.0.tar.gz

Download URL repo_policy-0.4.0.tar.gz
Size 92.0 kB
Tags Source
SHA-256 checksum
How to use checksums
518499af823db1e0ebfea5d3ebfeb1516b62df24713a195391de89029a0b922b
BLAKE2b-256 checksum
How to use checksums
3f7a3b7daaf9be823ab8e75311157513964b6124b50dea31c3b0a7d03eaf4542
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.4.0-py3-none-any.whl

Download URL repo_policy-0.4.0-py3-none-any.whl
Size 23.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9bb88f417b7eec2bea529891c1ae016ad0ced4fbe8f1db995e6cd963a13c5b63
BLAKE2b-256 checksum
How to use checksums
28bdc3f08afb5f0c17f3bac4fc52f08e65e84edd1ace067dee2c94a897e901e3
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

This release

0.4.0 This release

2 release files

0.3.0

2 release files

0.2.0

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