| 1 | -- SPDX-License-Identifier: AGPL-3.0-or-later |
| 2 | -- |
| 3 | -- Branch protection rules. Each rule is one (repo, glob pattern) tuple |
| 4 | -- with a set of bool/array fields the pre-receive hook checks. Pattern |
| 5 | -- matching is glob-style (filepath.Match: `*`, `?`, `[abc]`) — matches |
| 6 | -- GitHub's UX and is easy to author. |
| 7 | -- |
| 8 | -- Some columns are placeholders for later sprints: |
| 9 | -- require_signed_commits — post-MVP signing surface |
| 10 | -- require_pr_for_push — post-MVP "no direct push" enforcement |
| 11 | -- status_checks_required — S24 ships the check engine |
| 12 | -- |
| 13 | -- The pre-receive hook ignores those columns until their owning sprint |
| 14 | -- wires real enforcement; the schema is forward-compatible. |
| 15 | |
| 16 | -- +goose Up |
| 17 | CREATE TABLE branch_protection_rules ( |
| 18 | id bigserial PRIMARY KEY, |
| 19 | repo_id bigint NOT NULL REFERENCES repos(id) ON DELETE CASCADE, |
| 20 | pattern text NOT NULL, |
| 21 | prevent_force_push boolean NOT NULL DEFAULT true, |
| 22 | prevent_deletion boolean NOT NULL DEFAULT true, |
| 23 | require_pr_for_push boolean NOT NULL DEFAULT false, |
| 24 | allowed_pusher_user_ids bigint[] NOT NULL DEFAULT '{}', |
| 25 | require_signed_commits boolean NOT NULL DEFAULT false, |
| 26 | status_checks_required text[] NOT NULL DEFAULT '{}', |
| 27 | created_at timestamptz NOT NULL DEFAULT now(), |
| 28 | updated_at timestamptz NOT NULL DEFAULT now(), |
| 29 | created_by_user_id bigint REFERENCES users(id) ON DELETE SET NULL, |
| 30 | |
| 31 | CONSTRAINT branch_protection_rules_pattern_length CHECK (char_length(pattern) BETWEEN 1 AND 200) |
| 32 | ); |
| 33 | |
| 34 | CREATE INDEX branch_protection_rules_repo_idx ON branch_protection_rules (repo_id, pattern); |
| 35 | |
| 36 | CREATE TRIGGER set_updated_at BEFORE UPDATE ON branch_protection_rules |
| 37 | FOR EACH ROW EXECUTE FUNCTION tg_set_updated_at(); |
| 38 | |
| 39 | -- +goose Down |
| 40 | DROP TABLE IF EXISTS branch_protection_rules; |
| 41 |