MySQL · 4790 bytes Raw Blame History
1 -- SPDX-License-Identifier: AGPL-3.0-or-later
2 --
3 -- S22 pull requests subsystem. PRs reuse the S21 issues table for
4 -- title/body/state/timeline/comments/labels/milestones/assignees;
5 -- this migration adds the PR-specific surface:
6 --
7 -- pull_requests — keyed on issue_id; PR-only fields
8 -- pull_request_commits — head-side commit list (refreshed on sync)
9 -- pull_request_files — changed-files list (refreshed on sync)
10 --
11 -- Plus the merge-method config columns on `repos` that S11 deferred:
12 -- `allow_squash_merge`, `allow_rebase_merge`, `allow_merge_commit`,
13 -- `default_merge_method`. UI hides disallowed methods at merge time.
14
15 -- +goose Up
16
17 CREATE TYPE pr_merge_method AS ENUM ('merge', 'squash', 'rebase');
18 CREATE TYPE pr_mergeable_state AS ENUM ('unknown', 'clean', 'dirty', 'blocked', 'behind');
19 CREATE TYPE pr_file_status AS ENUM ('added', 'modified', 'deleted', 'renamed', 'copied');
20
21 ALTER TABLE repos
22 ADD COLUMN allow_squash_merge boolean NOT NULL DEFAULT true,
23 ADD COLUMN allow_rebase_merge boolean NOT NULL DEFAULT true,
24 ADD COLUMN allow_merge_commit boolean NOT NULL DEFAULT true,
25 ADD COLUMN default_merge_method pr_merge_method NOT NULL DEFAULT 'merge',
26 ADD CONSTRAINT repos_at_least_one_merge_method CHECK (
27 allow_squash_merge OR allow_rebase_merge OR allow_merge_commit
28 );
29
30
31 CREATE TABLE pull_requests (
32 issue_id bigint PRIMARY KEY REFERENCES issues(id) ON DELETE CASCADE,
33 base_ref text NOT NULL, -- e.g. "trunk"
34 head_ref text NOT NULL, -- e.g. "feature/x"
35 head_repo_id bigint NOT NULL REFERENCES repos(id) ON DELETE CASCADE,
36 -- Snapshotted at PR open + every synchronize so the diff renderer
37 -- and merge-tree probe always have stable inputs even if the
38 -- branches move between job ticks.
39 base_oid text NOT NULL DEFAULT '',
40 head_oid text NOT NULL DEFAULT '',
41 draft boolean NOT NULL DEFAULT false,
42 mergeable boolean, -- NULL until first probe
43 mergeable_state pr_mergeable_state NOT NULL DEFAULT 'unknown',
44 merge_commit_sha text,
45 merged_at timestamptz,
46 merged_by_user_id bigint REFERENCES users(id) ON DELETE SET NULL,
47 merge_method pr_merge_method,
48 base_oid_at_merge text,
49 head_oid_at_merge text,
50 last_synchronized_at timestamptz,
51
52 -- Same-repo PR can't merge a branch into itself. Cross-fork PRs
53 -- (S27) will need a richer invariant covering head_repo_id != repo_id.
54 CONSTRAINT pull_requests_base_head_distinct CHECK (base_ref <> head_ref)
55 );
56
57 CREATE INDEX pull_requests_head_idx ON pull_requests (head_repo_id, head_ref);
58 CREATE INDEX pull_requests_state_idx ON pull_requests (head_repo_id, mergeable_state);
59
60
61 CREATE TABLE pull_request_commits (
62 pr_id bigint NOT NULL REFERENCES pull_requests(issue_id) ON DELETE CASCADE,
63 sha text NOT NULL,
64 position int NOT NULL, -- 0-based, head-side order
65 author_name text NOT NULL DEFAULT '',
66 author_email text NOT NULL DEFAULT '',
67 committer_name text NOT NULL DEFAULT '',
68 committer_email text NOT NULL DEFAULT '',
69 subject text NOT NULL DEFAULT '',
70 body text NOT NULL DEFAULT '',
71 authored_at timestamptz,
72 committed_at timestamptz,
73
74 PRIMARY KEY (pr_id, sha)
75 );
76
77 CREATE INDEX pull_request_commits_position_idx
78 ON pull_request_commits (pr_id, position);
79
80
81 CREATE TABLE pull_request_files (
82 pr_id bigint NOT NULL REFERENCES pull_requests(issue_id) ON DELETE CASCADE,
83 path text NOT NULL,
84 status pr_file_status NOT NULL,
85 old_path text,
86 additions int NOT NULL DEFAULT 0,
87 deletions int NOT NULL DEFAULT 0,
88 changes int NOT NULL DEFAULT 0,
89
90 PRIMARY KEY (pr_id, path)
91 );
92
93
94 -- +goose Down
95 DROP TABLE IF EXISTS pull_request_files;
96 DROP TABLE IF EXISTS pull_request_commits;
97 DROP TABLE IF EXISTS pull_requests;
98 ALTER TABLE repos
99 DROP CONSTRAINT IF EXISTS repos_at_least_one_merge_method,
100 DROP COLUMN IF EXISTS default_merge_method,
101 DROP COLUMN IF EXISTS allow_merge_commit,
102 DROP COLUMN IF EXISTS allow_rebase_merge,
103 DROP COLUMN IF EXISTS allow_squash_merge;
104 DROP TYPE IF EXISTS pr_file_status;
105 DROP TYPE IF EXISTS pr_mergeable_state;
106 DROP TYPE IF EXISTS pr_merge_method;
107