Skip to content
140 linesCodeBlameRaw

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Merge main into the run-protection branch1-- Keeping runs safe: what a job's token may do, environments' protection
2-- rules, approval for pull requests from outside, a job's own concurrency
3-- group, and a cache scoped by ref. Builds on 0006 (repo_settings and the
4-- cache's version). See src/protection.rs, src/plan.rs and src/cache.rs.
5
6-- A repository's choices for its workflows, beside 0006's artifact
7-- retention. Null is "not chosen":
8-- default_permissions: read or write, what a workflow without
9-- `permissions:` gets. Unchosen, a repository made before this
10-- migration ran keeps write, as it had; a newer one takes its
11-- workspace's default (read unless the workspace says otherwise).
12-- approval_policy: which pull requests' runs wait for approval:
13-- first_time_contributors, outside_contributors (the default) or
14-- all_external_contributors.
15-- can_approve_pulls: whether a job's token may open and approve pull
16-- requests (off unless chosen, and only where the workspace allows).
17ALTER TABLE repo_settings ADD COLUMN default_permissions TEXT;
18ALTER TABLE repo_settings ADD COLUMN approval_policy TEXT;
19ALTER TABLE repo_settings ADD COLUMN can_approve_pulls INTEGER;
20
21-- When restricted tokens began: repositories made before keep read and
22-- write unless someone chooses otherwise, as GitHub kept them for older
23-- repositories. Written once.
24CREATE TABLE IF NOT EXISTS actions_meta (
25 key TEXT PRIMARY KEY,
26 value TEXT NOT NULL
27);
28INSERT OR IGNORE INTO actions_meta (key, value) VALUES ('restricted_since', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'));
29
30-- A workspace's policy for its repositories' tokens. A workspace without a
31-- row has the defaults: new repositories start read-only, any repository
32-- may choose write, and jobs may not open or approve pull requests.
33CREATE TABLE IF NOT EXISTS workspace_actions_settings (
34 -- The workspace's slug, lowercase.
35 namespace TEXT PRIMARY KEY,
36 -- read or write: what a new repository's workflows get by default.
37 default_permissions TEXT NOT NULL DEFAULT 'read',
38 -- read or write: the most a repository's default may be.
39 max_permissions TEXT NOT NULL DEFAULT 'write',
40 -- Whether its repositories may let jobs open and approve pull requests.
41 can_approve_pulls INTEGER NOT NULL DEFAULT 0,
42 updated_at TEXT NOT NULL,
43 updated_by TEXT
44);
45
46-- An environment's protection rules. An environment without a row has
47-- none: its jobs run as soon as their needs are done.
48CREATE TABLE IF NOT EXISTS environments (
49 repo_id TEXT NOT NULL,
50 -- Lowercase, as secrets' environments are.
51 name TEXT NOT NULL,
52 -- JSON: [{"type": "user" | "team", "name": "ada" | "deployers"}], up to 6.
53 reviewers TEXT NOT NULL DEFAULT '[]',
54 -- Whoever started a run may not approve its jobs.
55 prevent_self_review INTEGER NOT NULL DEFAULT 0,
56 -- Minutes a job waits before it may start, 0 to 43200.
57 wait_minutes INTEGER NOT NULL DEFAULT 0,
58 -- all, protected (branches the rules protect) or selected (patterns).
59 branch_policy TEXT NOT NULL DEFAULT 'all',
60 -- JSON: [{"name": "release/*", "type": "branch" | "tag"}].
61 branch_patterns TEXT NOT NULL DEFAULT '[]',
62 -- Admins may approve without being a reviewer, skipping the wait.
63 admins_bypass INTEGER NOT NULL DEFAULT 1,
64 created_at TEXT NOT NULL,
65 updated_at TEXT NOT NULL,
66 updated_by TEXT,
67 PRIMARY KEY (repo_id, name)
68);
69
70-- A run's jobs held at an environment's rules: one row per run attempt and
71-- environment, however many of its jobs name it, as one review approves
72-- them all.
73CREATE TABLE IF NOT EXISTS environment_gates (
74 run_id TEXT NOT NULL,
75 attempt INTEGER NOT NULL,
76 environment TEXT NOT NULL,
77 repo_id TEXT NOT NULL,
78 -- waiting, approved or rejected.
79 state TEXT NOT NULL,
80 -- Whether a reviewer must approve it.
81 needs_review INTEGER NOT NULL DEFAULT 0,
82 -- When its wait timer lets it through; null without one.
83 wait_until TEXT,
84 reviewed_by TEXT,
85 comment TEXT,
86 reviewed_at TEXT,
87 created_at TEXT NOT NULL,
88 PRIMARY KEY (run_id, attempt, environment)
89);
90CREATE INDEX IF NOT EXISTS environment_gates_waiting ON environment_gates (state, wait_until);
91
92-- A run of a pull request from outside that waits to be approved:
93-- `approval` is JSON {"state": "required" | "approved", "reason",
94-- "approvedBy"}; `approved_by` a username.
95ALTER TABLE runs ADD COLUMN approval TEXT;
96ALTER TABLE runs ADD COLUMN approved_by TEXT;
97-- The run's concurrency group cancels what it replaces.
98ALTER TABLE runs ADD COLUMN cancel_in_progress INTEGER NOT NULL DEFAULT 0;
99
100-- A job's environment, read when its needs were done (an expression
101-- included), and its own concurrency group.
102ALTER TABLE jobs ADD COLUMN environment TEXT;
103ALTER TABLE jobs ADD COLUMN concurrency_group TEXT;
104ALTER TABLE jobs ADD COLUMN cancel_in_progress INTEGER NOT NULL DEFAULT 0;
105CREATE INDEX IF NOT EXISTS jobs_by_group ON jobs (repo_id, concurrency_group, status) WHERE concurrency_group IS NOT NULL;
106
107-- The cache, scoped by ref: an entry belongs to the ref whose run saved it
108-- (refs/heads/main, refs/pull/3/merge), and a run restores from its own
109-- ref, then its pull request's base branch, then the default branch. A
110-- pull request from outside the repository saves under `untrusted:<ref>`,
111-- which no other ref reads. 0006's `version` (the hash of an entry's paths
112-- and compression, which the toolkit and g1t's runner both send) is now
113-- part of the key, and its `upload` stays.
114--
115-- The unique key changes, so the table is made again. Entries saved
116-- before scopes are marked expired: the next sweep deletes their objects
117-- and rows, so nothing saved without a scope is ever restored.
118CREATE TABLE cache_entries_v2 (
119 id TEXT PRIMARY KEY,
120 repo_id TEXT NOT NULL,
121 namespace TEXT NOT NULL,
122 scope TEXT NOT NULL,
123 key TEXT NOT NULL,
124 version TEXT NOT NULL DEFAULT '',
125 object TEXT NOT NULL,
126 size INTEGER NOT NULL DEFAULT 0,
127 status TEXT NOT NULL,
128 created_at TEXT NOT NULL,
129 last_used_at TEXT NOT NULL,
130 upload TEXT,
131 UNIQUE (repo_id, scope, key, version)
132);
133INSERT INTO cache_entries_v2 (id, repo_id, namespace, scope, key, version, object, size, status, created_at, last_used_at, upload)
134SELECT id, repo_id, namespace, 'legacy:' || id, key, version, object, size, 'expired', created_at, last_used_at, NULL FROM cache_entries;
135DROP TABLE cache_entries;
136ALTER TABLE cache_entries_v2 RENAME TO cache_entries;
137CREATE INDEX IF NOT EXISTS cache_entries_by_use ON cache_entries (repo_id, status, last_used_at);
138CREATE INDEX IF NOT EXISTS cache_entries_by_status ON cache_entries (status, last_used_at);
139CREATE INDEX IF NOT EXISTS cache_entries_by_namespace ON cache_entries (namespace, status);
140CREATE INDEX IF NOT EXISTS cache_entries_by_scope ON cache_entries (repo_id, scope, status, created_at);

This file's history is long; its oldest lines are credited to the oldest commit read.