Skip to content

Repository settings

What is enforced on github.com/coltonbearden/carrel, why, and how to reproduce it. Applied and verified by scripts/github-harden.sh (idempotent; re-run it any time to re-assert this state).

Branch ruleset main (active)

rule effect
Restrict deletions main cannot be deleted
Block force pushes history on main is append-only
Require linear history squash or rebase merges only, no merge commits
Require a pull request direct pushes are rejected; 0 approvals required (solo maintainer), stale approvals dismissed, review threads must be resolved
Require status checks lint, test (py3.12), test (py3.13), test (py3.14), test-minimal, test-minimal (macos) must pass on the PR head, and the branch must be up to date with main. Pending: promote test-minimal (windows) once it has been green on main for two consecutive weeks (D-028 in docs/DECISIONS.md has the rule, where the count starts and the earliest date) — drop continue-on-error in .github/workflows/test.yml, add the check to REQUIRED_CHECKS, re-run the script
Bypass repository admin role, through a pull request only — the admin can merge a PR past failing or pending checks, never push directly; every other actor (bots, collaborators, tokens) is blocked

Tag ruleset release tags (active, v*)

Release tags cannot be deleted, moved, or force-updated. No bypass — nobody, including the admin, can move a published tag.

Security & analysis

  • Dependabot alerts + security updates: on (.github/dependabot.yml also schedules weekly grouped updates for uv and github-actions).
  • Secret scanning + push protection: on. (Non-provider patterns: the API accepts but ignores the toggle on user-owned repos — flip it under Settings → Advanced Security if wanted.)
  • Private vulnerability reporting: on (SECURITY.md links the form).
  • CodeQL default setup: on, extended query suite, languages python + actions.

Actions

  • Allowed actions: GitHub-owned, verified-creator, plus astral-sh/setup-uv@* and pypa/gh-action-pypi-publish@*.
  • SHA pinning required (all workflows pin to commit SHAs with a version comment).
  • Default GITHUB_TOKEN permissions: read-only; Actions cannot approve PRs.
  • Environment pypi: deployments only from v* tags.
  • Environment github-pages: deployments only from main. docs.yml deploys on every event but pull_request, so this keeps a dispatched branch from deploying through it. A workflow that names another environment is not covered (D-029).

Secrets

Actions secrets carrel's workflows read. Publishing needs none — PyPI is Trusted Publishing (OIDC), so no long-lived token exists anywhere.

Secret Set? Used by If absent
CONTEXT7_API_KEY not set .github/workflows/context7-refresh.yml The job is green and skipped: HAS_KEY is decided at job level and the request step is gated on it. Nothing to disable and no red runs. Context7 re-indexes on its own schedule regardless; the key only buys a nudge and higher refresh limits. Generate one at https://context7.com/dashboard.

Merge behaviour

  • Squash merge (PR title + body) and rebase allowed; merge commits disabled.
  • Auto-merge enabled, head branch auto-deleted, "update branch" button on.
  • Wiki disabled (docs live in docs/, published to GitHub Pages).

Verified state (2026-09-04)

scripts/github-harden.sh applied and read back every setting above after PR #7 merged: both rulesets active, secret scanning + push protection enabled, private vulnerability reporting on, CodeQL default setup configured (extended), Actions restricted to the allow-list with SHA pinning required, pypi environment limited to v* tags. PR #7 itself was the first change to land under the required checks (lint, test (py3.12/3.13/3.14), test-minimal, test-minimal (macos)).

2026-10-09: scripts/github-harden.sh --verify-only read every setting above back again, the github-pages policy included. That policy was already main only; the script had not set or checked it before. For both environments it now checks that custom policies are in force as well as which patterns exist, and applying it deletes any other pattern.

Not enforced (deliberately)

  • Signed commits — would block unsigned commits from automation; enable once every committer signs.
  • Required reviewers on pypi — one maintainer; the ruleset + tag protection + version check already gate releases.