tenseleyflow/shithub / c50d265

Browse files

actions: add policy and approval schema (S41j-3)

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
c50d2656553405c0a2cd68f411a1db8bfa5c44c5
Parents
0945a74
Tree
b092da2

26 changed files

StatusFile+-
A internal/actions/queries/actions_policy.sql 89 0
M internal/actions/queries/workflow_jobs.sql 30 0
A internal/actions/queries/workflow_run_approvals.sql 108 0
M internal/actions/queries/workflow_runs.sql 1 0
A internal/actions/sqlc/actions_policy.sql.go 229 0
M internal/actions/sqlc/models.go 94 0
M internal/actions/sqlc/querier.go 15 0
M internal/actions/sqlc/workflow_jobs.sql.go 30 0
A internal/actions/sqlc/workflow_run_approvals.sql.go 322 0
M internal/actions/sqlc/workflow_runs.sql.go 1 0
M internal/admin/sqlc/models.go 94 0
M internal/auth/policy/sqlc/models.go 129 0
M internal/billing/sqlc/models.go 94 0
M internal/checks/sqlc/models.go 94 0
M internal/issues/sqlc/models.go 94 0
M internal/meta/sqlc/models.go 94 0
A internal/migrationsfs/migrations/0066_actions_policy_approvals.sql 118 0
M internal/notif/sqlc/models.go 94 0
M internal/orgs/sqlc/models.go 94 0
M internal/pulls/sqlc/models.go 94 0
M internal/ratelimit/sqlc/models.go 94 0
M internal/repos/sqlc/models.go 94 0
M internal/social/sqlc/models.go 94 0
M internal/users/sqlc/models.go 94 0
M internal/webhook/sqlc/models.go 94 0
M internal/worker/sqlc/models.go 94 0
internal/actions/queries/actions_policy.sqladded
@@ -0,0 +1,89 @@
1
+-- SPDX-License-Identifier: AGPL-3.0-or-later
2
+
3
+-- name: GetEffectiveActionsPolicyForRepo :one
4
+SELECT
5
+    r.id AS repo_id,
6
+    COALESCE(sp.actions_enabled, true)::boolean AS site_actions_enabled,
7
+    COALESCE(op.actions_enabled, 'inherit'::actions_policy_state)::actions_policy_state AS org_actions_enabled,
8
+    COALESCE(rp.actions_enabled, 'inherit'::actions_policy_state)::actions_policy_state AS repo_actions_enabled,
9
+    CASE
10
+        WHEN COALESCE(rp.actions_enabled, 'inherit'::actions_policy_state) = 'enabled' THEN true
11
+        WHEN COALESCE(rp.actions_enabled, 'inherit'::actions_policy_state) = 'disabled' THEN false
12
+        WHEN COALESCE(op.actions_enabled, 'inherit'::actions_policy_state) = 'enabled' THEN true
13
+        WHEN COALESCE(op.actions_enabled, 'inherit'::actions_policy_state) = 'disabled' THEN false
14
+        ELSE COALESCE(sp.actions_enabled, true)
15
+    END::boolean AS actions_enabled,
16
+    COALESCE(rp.require_pr_approval, op.require_pr_approval, sp.require_pr_approval, true)::boolean AS require_pr_approval,
17
+    COALESCE(rp.max_repo_queued_runs, op.max_repo_queued_runs, sp.max_repo_queued_runs, 50)::integer AS max_repo_queued_runs,
18
+    COALESCE(rp.max_repo_concurrent_jobs, op.max_repo_concurrent_jobs, sp.max_repo_concurrent_jobs, 20)::integer AS max_repo_concurrent_jobs,
19
+    COALESCE(rp.max_owner_concurrent_jobs, op.max_owner_concurrent_jobs, sp.max_owner_concurrent_jobs, 100)::integer AS max_owner_concurrent_jobs,
20
+    COALESCE(rp.actor_trigger_limit_per_hour, op.actor_trigger_limit_per_hour, sp.actor_trigger_limit_per_hour, 120)::integer AS actor_trigger_limit_per_hour
21
+FROM repos r
22
+LEFT JOIN actions_site_policy sp ON sp.id = true
23
+LEFT JOIN actions_org_policies op ON op.org_id = r.owner_org_id
24
+LEFT JOIN actions_repo_policies rp ON rp.repo_id = r.id
25
+WHERE r.id = $1;
26
+
27
+-- name: GetActionsRepoPolicy :one
28
+SELECT repo_id, actions_enabled, require_pr_approval,
29
+       max_repo_queued_runs, max_repo_concurrent_jobs,
30
+       max_owner_concurrent_jobs, actor_trigger_limit_per_hour,
31
+       updated_by_user_id, created_at, updated_at
32
+FROM actions_repo_policies
33
+WHERE repo_id = $1;
34
+
35
+-- name: UpsertActionsRepoPolicy :one
36
+INSERT INTO actions_repo_policies (
37
+    repo_id, actions_enabled, require_pr_approval,
38
+    max_repo_queued_runs, max_repo_concurrent_jobs,
39
+    max_owner_concurrent_jobs, actor_trigger_limit_per_hour,
40
+    updated_by_user_id
41
+) VALUES (
42
+    $1, $2, sqlc.narg(require_pr_approval)::boolean,
43
+    sqlc.narg(max_repo_queued_runs)::integer,
44
+    sqlc.narg(max_repo_concurrent_jobs)::integer,
45
+    sqlc.narg(max_owner_concurrent_jobs)::integer,
46
+    sqlc.narg(actor_trigger_limit_per_hour)::integer,
47
+    sqlc.narg(updated_by_user_id)::bigint
48
+)
49
+ON CONFLICT (repo_id) DO UPDATE SET
50
+    actions_enabled = EXCLUDED.actions_enabled,
51
+    require_pr_approval = EXCLUDED.require_pr_approval,
52
+    max_repo_queued_runs = EXCLUDED.max_repo_queued_runs,
53
+    max_repo_concurrent_jobs = EXCLUDED.max_repo_concurrent_jobs,
54
+    max_owner_concurrent_jobs = EXCLUDED.max_owner_concurrent_jobs,
55
+    actor_trigger_limit_per_hour = EXCLUDED.actor_trigger_limit_per_hour,
56
+    updated_by_user_id = EXCLUDED.updated_by_user_id,
57
+    updated_at = now()
58
+RETURNING repo_id, actions_enabled, require_pr_approval,
59
+          max_repo_queued_runs, max_repo_concurrent_jobs,
60
+          max_owner_concurrent_jobs, actor_trigger_limit_per_hour,
61
+          updated_by_user_id, created_at, updated_at;
62
+
63
+-- name: CountQueuedWorkflowRunsForRepo :one
64
+SELECT COUNT(*)::bigint
65
+FROM workflow_runs
66
+WHERE repo_id = $1 AND status = 'queued';
67
+
68
+-- name: CountRecentWorkflowRunsForActor :one
69
+SELECT COUNT(*)::bigint
70
+FROM workflow_runs
71
+WHERE actor_user_id = $1 AND created_at >= sqlc.arg(since)::timestamptz;
72
+
73
+-- name: CountRunningWorkflowJobsForRepo :one
74
+SELECT COUNT(*)::bigint
75
+FROM workflow_jobs j
76
+JOIN workflow_runs r ON r.id = j.run_id
77
+WHERE r.repo_id = $1 AND j.status = 'running';
78
+
79
+-- name: CountRunningWorkflowJobsForOwner :one
80
+SELECT COUNT(*)::bigint
81
+FROM workflow_jobs j
82
+JOIN workflow_runs wr ON wr.id = j.run_id
83
+JOIN repos run_repo ON run_repo.id = wr.repo_id
84
+JOIN repos anchor_repo ON anchor_repo.id = sqlc.arg(repo_id)::bigint
85
+WHERE j.status = 'running'
86
+  AND (
87
+      (anchor_repo.owner_user_id IS NOT NULL AND run_repo.owner_user_id = anchor_repo.owner_user_id)
88
+      OR (anchor_repo.owner_org_id IS NOT NULL AND run_repo.owner_org_id = anchor_repo.owner_org_id)
89
+  );
internal/actions/queries/workflow_jobs.sqlmodified
@@ -103,10 +103,40 @@ WITH candidate AS (
103103
     SELECT j.id
104104
     FROM workflow_jobs j
105105
     JOIN workflow_runs r ON r.id = j.run_id
106
+    JOIN repos repo ON repo.id = r.repo_id
107
+    LEFT JOIN actions_site_policy sp ON sp.id = true
108
+    LEFT JOIN actions_org_policies op ON op.org_id = repo.owner_org_id
109
+    LEFT JOIN actions_repo_policies rp ON rp.repo_id = r.repo_id
106110
     WHERE j.status = 'queued'
107111
       AND r.status IN ('queued', 'running')
112
+      AND (r.need_approval = false OR r.approved_by_user_id IS NOT NULL)
108113
       AND j.cancel_requested = false
109114
       AND j.runner_id IS NULL
115
+      AND CASE
116
+          WHEN COALESCE(rp.actions_enabled, 'inherit'::actions_policy_state) = 'enabled' THEN true
117
+          WHEN COALESCE(rp.actions_enabled, 'inherit'::actions_policy_state) = 'disabled' THEN false
118
+          WHEN COALESCE(op.actions_enabled, 'inherit'::actions_policy_state) = 'enabled' THEN true
119
+          WHEN COALESCE(op.actions_enabled, 'inherit'::actions_policy_state) = 'disabled' THEN false
120
+          ELSE COALESCE(sp.actions_enabled, true)
121
+      END
122
+      AND (
123
+          SELECT COUNT(*)::integer
124
+          FROM workflow_jobs running_job
125
+          JOIN workflow_runs running_run ON running_run.id = running_job.run_id
126
+          WHERE running_job.status = 'running'
127
+            AND running_run.repo_id = r.repo_id
128
+      ) < COALESCE(rp.max_repo_concurrent_jobs, op.max_repo_concurrent_jobs, sp.max_repo_concurrent_jobs, 20)
129
+      AND (
130
+          SELECT COUNT(*)::integer
131
+          FROM workflow_jobs running_job
132
+          JOIN workflow_runs running_run ON running_run.id = running_job.run_id
133
+          JOIN repos running_repo ON running_repo.id = running_run.repo_id
134
+          WHERE running_job.status = 'running'
135
+            AND (
136
+                (repo.owner_user_id IS NOT NULL AND running_repo.owner_user_id = repo.owner_user_id)
137
+                OR (repo.owner_org_id IS NOT NULL AND running_repo.owner_org_id = repo.owner_org_id)
138
+            )
139
+      ) < COALESCE(rp.max_owner_concurrent_jobs, op.max_owner_concurrent_jobs, sp.max_owner_concurrent_jobs, 100)
110140
       AND (j.runs_on = '' OR j.runs_on = ANY(sqlc.arg(labels)::text[]))
111141
       AND NOT EXISTS (
112142
           SELECT 1
internal/actions/queries/workflow_run_approvals.sqladded
@@ -0,0 +1,108 @@
1
+-- SPDX-License-Identifier: AGPL-3.0-or-later
2
+
3
+-- name: InsertWorkflowRunApproval :one
4
+INSERT INTO workflow_run_approvals (run_id, requested_reason)
5
+VALUES ($1, $2)
6
+ON CONFLICT (run_id) DO UPDATE SET
7
+    requested_reason = EXCLUDED.requested_reason,
8
+    updated_at = now()
9
+RETURNING run_id, requested_reason, requested_at,
10
+          approved_by_user_id, approved_at,
11
+          rejected_by_user_id, rejected_at,
12
+          created_at, updated_at;
13
+
14
+-- name: GetWorkflowRunApproval :one
15
+SELECT run_id, requested_reason, requested_at,
16
+       approved_by_user_id, approved_at,
17
+       rejected_by_user_id, rejected_at,
18
+       created_at, updated_at
19
+FROM workflow_run_approvals
20
+WHERE run_id = $1;
21
+
22
+-- name: ApproveWorkflowRun :one
23
+WITH run AS (
24
+    UPDATE workflow_runs r
25
+    SET approved_by_user_id = $2,
26
+        version = version + 1,
27
+        updated_at = now()
28
+    WHERE r.id = $1
29
+      AND r.need_approval = true
30
+      AND r.approved_by_user_id IS NULL
31
+      AND r.status = 'queued'
32
+      AND EXISTS (
33
+          SELECT 1
34
+          FROM workflow_run_approvals a
35
+          WHERE a.run_id = r.id
36
+            AND a.approved_at IS NULL
37
+            AND a.rejected_at IS NULL
38
+      )
39
+    RETURNING r.id, r.repo_id, r.run_index, r.workflow_file, r.workflow_name,
40
+              r.head_sha, r.head_ref, r.event, r.event_payload,
41
+              r.actor_user_id, r.parent_run_id, r.concurrency_group,
42
+              r.status, r.conclusion, r.pinned, r.need_approval, r.approved_by_user_id,
43
+              r.started_at, r.completed_at, r.version, r.created_at, r.updated_at, r.trigger_event_id
44
+), approval AS (
45
+    UPDATE workflow_run_approvals a
46
+    SET approved_by_user_id = $2,
47
+        approved_at = now(),
48
+        updated_at = now()
49
+    FROM run r
50
+    WHERE a.run_id = r.id
51
+      AND a.approved_at IS NULL
52
+      AND a.rejected_at IS NULL
53
+    RETURNING a.run_id
54
+)
55
+SELECT r.id, r.repo_id, r.run_index, r.workflow_file, r.workflow_name,
56
+       r.head_sha, r.head_ref, r.event, r.event_payload,
57
+       r.actor_user_id, r.parent_run_id, r.concurrency_group,
58
+       r.status, r.conclusion, r.pinned, r.need_approval, r.approved_by_user_id,
59
+       r.started_at, r.completed_at, r.version, r.created_at, r.updated_at, r.trigger_event_id
60
+FROM run r
61
+JOIN approval a ON a.run_id = r.id;
62
+
63
+-- name: RejectWorkflowRunApproval :one
64
+UPDATE workflow_run_approvals
65
+SET rejected_by_user_id = $2,
66
+    rejected_at = now(),
67
+    updated_at = now()
68
+WHERE run_id = $1
69
+  AND approved_at IS NULL
70
+  AND rejected_at IS NULL
71
+RETURNING run_id, requested_reason, requested_at,
72
+          approved_by_user_id, approved_at,
73
+          rejected_by_user_id, rejected_at,
74
+          created_at, updated_at;
75
+
76
+-- name: MarkWorkflowRunRejected :one
77
+UPDATE workflow_runs
78
+SET status = 'completed',
79
+    conclusion = 'action_required',
80
+    started_at = COALESCE(started_at, now()),
81
+    completed_at = COALESCE(completed_at, now()),
82
+    version = version + 1,
83
+    updated_at = now()
84
+WHERE id = $1
85
+  AND need_approval = true
86
+  AND approved_by_user_id IS NULL
87
+  AND status = 'queued'
88
+RETURNING id, repo_id, run_index, workflow_file, workflow_name,
89
+          head_sha, head_ref, event, event_payload,
90
+          actor_user_id, parent_run_id, concurrency_group,
91
+          status, conclusion, pinned, need_approval, approved_by_user_id,
92
+          started_at, completed_at, version, created_at, updated_at, trigger_event_id;
93
+
94
+-- name: MarkWorkflowJobsRejected :many
95
+UPDATE workflow_jobs
96
+SET cancel_requested = true,
97
+    status = 'cancelled',
98
+    conclusion = 'action_required',
99
+    started_at = COALESCE(started_at, now()),
100
+    completed_at = COALESCE(completed_at, now()),
101
+    version = version + 1,
102
+    updated_at = now()
103
+WHERE run_id = $1
104
+  AND status = 'queued'
105
+RETURNING id, run_id, job_index, job_key, job_name, runs_on,
106
+          runner_id, needs_jobs, if_expr, timeout_minutes, permissions,
107
+          job_env, status, conclusion, cancel_requested,
108
+          started_at, completed_at, version, created_at, updated_at;
internal/actions/queries/workflow_runs.sqlmodified
@@ -124,6 +124,7 @@ SET status = 'running',
124124
     version = version + 1,
125125
     updated_at = now()
126126
 WHERE id = $1 AND status = 'queued'
127
+  AND (need_approval = false OR approved_by_user_id IS NOT NULL)
127128
 RETURNING id, repo_id, run_index, workflow_file, workflow_name,
128129
           head_sha, head_ref, event, event_payload,
129130
           actor_user_id, parent_run_id, concurrency_group,
internal/actions/sqlc/actions_policy.sql.goadded
@@ -0,0 +1,229 @@
1
+// Code generated by sqlc. DO NOT EDIT.
2
+// versions:
3
+//   sqlc v1.31.1
4
+// source: actions_policy.sql
5
+
6
+package actionsdb
7
+
8
+import (
9
+	"context"
10
+
11
+	"github.com/jackc/pgx/v5/pgtype"
12
+)
13
+
14
+const countQueuedWorkflowRunsForRepo = `-- name: CountQueuedWorkflowRunsForRepo :one
15
+SELECT COUNT(*)::bigint
16
+FROM workflow_runs
17
+WHERE repo_id = $1 AND status = 'queued'
18
+`
19
+
20
+func (q *Queries) CountQueuedWorkflowRunsForRepo(ctx context.Context, db DBTX, repoID int64) (int64, error) {
21
+	row := db.QueryRow(ctx, countQueuedWorkflowRunsForRepo, repoID)
22
+	var column_1 int64
23
+	err := row.Scan(&column_1)
24
+	return column_1, err
25
+}
26
+
27
+const countRecentWorkflowRunsForActor = `-- name: CountRecentWorkflowRunsForActor :one
28
+SELECT COUNT(*)::bigint
29
+FROM workflow_runs
30
+WHERE actor_user_id = $1 AND created_at >= $2::timestamptz
31
+`
32
+
33
+type CountRecentWorkflowRunsForActorParams struct {
34
+	ActorUserID pgtype.Int8
35
+	Since       pgtype.Timestamptz
36
+}
37
+
38
+func (q *Queries) CountRecentWorkflowRunsForActor(ctx context.Context, db DBTX, arg CountRecentWorkflowRunsForActorParams) (int64, error) {
39
+	row := db.QueryRow(ctx, countRecentWorkflowRunsForActor, arg.ActorUserID, arg.Since)
40
+	var column_1 int64
41
+	err := row.Scan(&column_1)
42
+	return column_1, err
43
+}
44
+
45
+const countRunningWorkflowJobsForOwner = `-- name: CountRunningWorkflowJobsForOwner :one
46
+SELECT COUNT(*)::bigint
47
+FROM workflow_jobs j
48
+JOIN workflow_runs wr ON wr.id = j.run_id
49
+JOIN repos run_repo ON run_repo.id = wr.repo_id
50
+JOIN repos anchor_repo ON anchor_repo.id = $1::bigint
51
+WHERE j.status = 'running'
52
+  AND (
53
+      (anchor_repo.owner_user_id IS NOT NULL AND run_repo.owner_user_id = anchor_repo.owner_user_id)
54
+      OR (anchor_repo.owner_org_id IS NOT NULL AND run_repo.owner_org_id = anchor_repo.owner_org_id)
55
+  )
56
+`
57
+
58
+func (q *Queries) CountRunningWorkflowJobsForOwner(ctx context.Context, db DBTX, repoID int64) (int64, error) {
59
+	row := db.QueryRow(ctx, countRunningWorkflowJobsForOwner, repoID)
60
+	var column_1 int64
61
+	err := row.Scan(&column_1)
62
+	return column_1, err
63
+}
64
+
65
+const countRunningWorkflowJobsForRepo = `-- name: CountRunningWorkflowJobsForRepo :one
66
+SELECT COUNT(*)::bigint
67
+FROM workflow_jobs j
68
+JOIN workflow_runs r ON r.id = j.run_id
69
+WHERE r.repo_id = $1 AND j.status = 'running'
70
+`
71
+
72
+func (q *Queries) CountRunningWorkflowJobsForRepo(ctx context.Context, db DBTX, repoID int64) (int64, error) {
73
+	row := db.QueryRow(ctx, countRunningWorkflowJobsForRepo, repoID)
74
+	var column_1 int64
75
+	err := row.Scan(&column_1)
76
+	return column_1, err
77
+}
78
+
79
+const getActionsRepoPolicy = `-- name: GetActionsRepoPolicy :one
80
+SELECT repo_id, actions_enabled, require_pr_approval,
81
+       max_repo_queued_runs, max_repo_concurrent_jobs,
82
+       max_owner_concurrent_jobs, actor_trigger_limit_per_hour,
83
+       updated_by_user_id, created_at, updated_at
84
+FROM actions_repo_policies
85
+WHERE repo_id = $1
86
+`
87
+
88
+func (q *Queries) GetActionsRepoPolicy(ctx context.Context, db DBTX, repoID int64) (ActionsRepoPolicy, error) {
89
+	row := db.QueryRow(ctx, getActionsRepoPolicy, repoID)
90
+	var i ActionsRepoPolicy
91
+	err := row.Scan(
92
+		&i.RepoID,
93
+		&i.ActionsEnabled,
94
+		&i.RequirePrApproval,
95
+		&i.MaxRepoQueuedRuns,
96
+		&i.MaxRepoConcurrentJobs,
97
+		&i.MaxOwnerConcurrentJobs,
98
+		&i.ActorTriggerLimitPerHour,
99
+		&i.UpdatedByUserID,
100
+		&i.CreatedAt,
101
+		&i.UpdatedAt,
102
+	)
103
+	return i, err
104
+}
105
+
106
+const getEffectiveActionsPolicyForRepo = `-- name: GetEffectiveActionsPolicyForRepo :one
107
+
108
+SELECT
109
+    r.id AS repo_id,
110
+    COALESCE(sp.actions_enabled, true)::boolean AS site_actions_enabled,
111
+    COALESCE(op.actions_enabled, 'inherit'::actions_policy_state)::actions_policy_state AS org_actions_enabled,
112
+    COALESCE(rp.actions_enabled, 'inherit'::actions_policy_state)::actions_policy_state AS repo_actions_enabled,
113
+    CASE
114
+        WHEN COALESCE(rp.actions_enabled, 'inherit'::actions_policy_state) = 'enabled' THEN true
115
+        WHEN COALESCE(rp.actions_enabled, 'inherit'::actions_policy_state) = 'disabled' THEN false
116
+        WHEN COALESCE(op.actions_enabled, 'inherit'::actions_policy_state) = 'enabled' THEN true
117
+        WHEN COALESCE(op.actions_enabled, 'inherit'::actions_policy_state) = 'disabled' THEN false
118
+        ELSE COALESCE(sp.actions_enabled, true)
119
+    END::boolean AS actions_enabled,
120
+    COALESCE(rp.require_pr_approval, op.require_pr_approval, sp.require_pr_approval, true)::boolean AS require_pr_approval,
121
+    COALESCE(rp.max_repo_queued_runs, op.max_repo_queued_runs, sp.max_repo_queued_runs, 50)::integer AS max_repo_queued_runs,
122
+    COALESCE(rp.max_repo_concurrent_jobs, op.max_repo_concurrent_jobs, sp.max_repo_concurrent_jobs, 20)::integer AS max_repo_concurrent_jobs,
123
+    COALESCE(rp.max_owner_concurrent_jobs, op.max_owner_concurrent_jobs, sp.max_owner_concurrent_jobs, 100)::integer AS max_owner_concurrent_jobs,
124
+    COALESCE(rp.actor_trigger_limit_per_hour, op.actor_trigger_limit_per_hour, sp.actor_trigger_limit_per_hour, 120)::integer AS actor_trigger_limit_per_hour
125
+FROM repos r
126
+LEFT JOIN actions_site_policy sp ON sp.id = true
127
+LEFT JOIN actions_org_policies op ON op.org_id = r.owner_org_id
128
+LEFT JOIN actions_repo_policies rp ON rp.repo_id = r.id
129
+WHERE r.id = $1
130
+`
131
+
132
+type GetEffectiveActionsPolicyForRepoRow struct {
133
+	RepoID                   int64
134
+	SiteActionsEnabled       bool
135
+	OrgActionsEnabled        ActionsPolicyState
136
+	RepoActionsEnabled       ActionsPolicyState
137
+	ActionsEnabled           bool
138
+	RequirePrApproval        bool
139
+	MaxRepoQueuedRuns        int32
140
+	MaxRepoConcurrentJobs    int32
141
+	MaxOwnerConcurrentJobs   int32
142
+	ActorTriggerLimitPerHour int32
143
+}
144
+
145
+// SPDX-License-Identifier: AGPL-3.0-or-later
146
+func (q *Queries) GetEffectiveActionsPolicyForRepo(ctx context.Context, db DBTX, id int64) (GetEffectiveActionsPolicyForRepoRow, error) {
147
+	row := db.QueryRow(ctx, getEffectiveActionsPolicyForRepo, id)
148
+	var i GetEffectiveActionsPolicyForRepoRow
149
+	err := row.Scan(
150
+		&i.RepoID,
151
+		&i.SiteActionsEnabled,
152
+		&i.OrgActionsEnabled,
153
+		&i.RepoActionsEnabled,
154
+		&i.ActionsEnabled,
155
+		&i.RequirePrApproval,
156
+		&i.MaxRepoQueuedRuns,
157
+		&i.MaxRepoConcurrentJobs,
158
+		&i.MaxOwnerConcurrentJobs,
159
+		&i.ActorTriggerLimitPerHour,
160
+	)
161
+	return i, err
162
+}
163
+
164
+const upsertActionsRepoPolicy = `-- name: UpsertActionsRepoPolicy :one
165
+INSERT INTO actions_repo_policies (
166
+    repo_id, actions_enabled, require_pr_approval,
167
+    max_repo_queued_runs, max_repo_concurrent_jobs,
168
+    max_owner_concurrent_jobs, actor_trigger_limit_per_hour,
169
+    updated_by_user_id
170
+) VALUES (
171
+    $1, $2, $3::boolean,
172
+    $4::integer,
173
+    $5::integer,
174
+    $6::integer,
175
+    $7::integer,
176
+    $8::bigint
177
+)
178
+ON CONFLICT (repo_id) DO UPDATE SET
179
+    actions_enabled = EXCLUDED.actions_enabled,
180
+    require_pr_approval = EXCLUDED.require_pr_approval,
181
+    max_repo_queued_runs = EXCLUDED.max_repo_queued_runs,
182
+    max_repo_concurrent_jobs = EXCLUDED.max_repo_concurrent_jobs,
183
+    max_owner_concurrent_jobs = EXCLUDED.max_owner_concurrent_jobs,
184
+    actor_trigger_limit_per_hour = EXCLUDED.actor_trigger_limit_per_hour,
185
+    updated_by_user_id = EXCLUDED.updated_by_user_id,
186
+    updated_at = now()
187
+RETURNING repo_id, actions_enabled, require_pr_approval,
188
+          max_repo_queued_runs, max_repo_concurrent_jobs,
189
+          max_owner_concurrent_jobs, actor_trigger_limit_per_hour,
190
+          updated_by_user_id, created_at, updated_at
191
+`
192
+
193
+type UpsertActionsRepoPolicyParams struct {
194
+	RepoID                   int64
195
+	ActionsEnabled           ActionsPolicyState
196
+	RequirePrApproval        pgtype.Bool
197
+	MaxRepoQueuedRuns        pgtype.Int4
198
+	MaxRepoConcurrentJobs    pgtype.Int4
199
+	MaxOwnerConcurrentJobs   pgtype.Int4
200
+	ActorTriggerLimitPerHour pgtype.Int4
201
+	UpdatedByUserID          pgtype.Int8
202
+}
203
+
204
+func (q *Queries) UpsertActionsRepoPolicy(ctx context.Context, db DBTX, arg UpsertActionsRepoPolicyParams) (ActionsRepoPolicy, error) {
205
+	row := db.QueryRow(ctx, upsertActionsRepoPolicy,
206
+		arg.RepoID,
207
+		arg.ActionsEnabled,
208
+		arg.RequirePrApproval,
209
+		arg.MaxRepoQueuedRuns,
210
+		arg.MaxRepoConcurrentJobs,
211
+		arg.MaxOwnerConcurrentJobs,
212
+		arg.ActorTriggerLimitPerHour,
213
+		arg.UpdatedByUserID,
214
+	)
215
+	var i ActionsRepoPolicy
216
+	err := row.Scan(
217
+		&i.RepoID,
218
+		&i.ActionsEnabled,
219
+		&i.RequirePrApproval,
220
+		&i.MaxRepoQueuedRuns,
221
+		&i.MaxRepoConcurrentJobs,
222
+		&i.MaxOwnerConcurrentJobs,
223
+		&i.ActorTriggerLimitPerHour,
224
+		&i.UpdatedByUserID,
225
+		&i.CreatedAt,
226
+		&i.UpdatedAt,
227
+	)
228
+	return i, err
229
+}
internal/actions/sqlc/models.gomodified
@@ -12,6 +12,49 @@ import (
1212
 	"github.com/jackc/pgx/v5/pgtype"
1313
 )
1414
 
15
+type ActionsPolicyState string
16
+
17
+const (
18
+	ActionsPolicyStateInherit  ActionsPolicyState = "inherit"
19
+	ActionsPolicyStateEnabled  ActionsPolicyState = "enabled"
20
+	ActionsPolicyStateDisabled ActionsPolicyState = "disabled"
21
+)
22
+
23
+func (e *ActionsPolicyState) Scan(src interface{}) error {
24
+	switch s := src.(type) {
25
+	case []byte:
26
+		*e = ActionsPolicyState(s)
27
+	case string:
28
+		*e = ActionsPolicyState(s)
29
+	default:
30
+		return fmt.Errorf("unsupported scan type for ActionsPolicyState: %T", src)
31
+	}
32
+	return nil
33
+}
34
+
35
+type NullActionsPolicyState struct {
36
+	ActionsPolicyState ActionsPolicyState
37
+	Valid              bool // Valid is true if ActionsPolicyState is not NULL
38
+}
39
+
40
+// Scan implements the Scanner interface.
41
+func (ns *NullActionsPolicyState) Scan(value interface{}) error {
42
+	if value == nil {
43
+		ns.ActionsPolicyState, ns.Valid = "", false
44
+		return nil
45
+	}
46
+	ns.Valid = true
47
+	return ns.ActionsPolicyState.Scan(value)
48
+}
49
+
50
+// Value implements the driver Valuer interface.
51
+func (ns NullActionsPolicyState) Value() (driver.Value, error) {
52
+	if !ns.Valid {
53
+		return nil, nil
54
+	}
55
+	return string(ns.ActionsPolicyState), nil
56
+}
57
+
1558
 type BillingInvoiceStatus string
1659
 
1760
 const (
@@ -1750,6 +1793,45 @@ func (ns NullWorkflowStepStatus) Value() (driver.Value, error) {
17501793
 	return string(ns.WorkflowStepStatus), nil
17511794
 }
17521795
 
1796
+type ActionsOrgPolicy struct {
1797
+	OrgID                    int64
1798
+	ActionsEnabled           ActionsPolicyState
1799
+	RequirePrApproval        pgtype.Bool
1800
+	MaxRepoQueuedRuns        pgtype.Int4
1801
+	MaxRepoConcurrentJobs    pgtype.Int4
1802
+	MaxOwnerConcurrentJobs   pgtype.Int4
1803
+	ActorTriggerLimitPerHour pgtype.Int4
1804
+	UpdatedByUserID          pgtype.Int8
1805
+	CreatedAt                pgtype.Timestamptz
1806
+	UpdatedAt                pgtype.Timestamptz
1807
+}
1808
+
1809
+type ActionsRepoPolicy struct {
1810
+	RepoID                   int64
1811
+	ActionsEnabled           ActionsPolicyState
1812
+	RequirePrApproval        pgtype.Bool
1813
+	MaxRepoQueuedRuns        pgtype.Int4
1814
+	MaxRepoConcurrentJobs    pgtype.Int4
1815
+	MaxOwnerConcurrentJobs   pgtype.Int4
1816
+	ActorTriggerLimitPerHour pgtype.Int4
1817
+	UpdatedByUserID          pgtype.Int8
1818
+	CreatedAt                pgtype.Timestamptz
1819
+	UpdatedAt                pgtype.Timestamptz
1820
+}
1821
+
1822
+type ActionsSitePolicy struct {
1823
+	ID                       bool
1824
+	ActionsEnabled           bool
1825
+	RequirePrApproval        bool
1826
+	MaxRepoQueuedRuns        int32
1827
+	MaxRepoConcurrentJobs    int32
1828
+	MaxOwnerConcurrentJobs   int32
1829
+	ActorTriggerLimitPerHour int32
1830
+	UpdatedByUserID          pgtype.Int8
1831
+	CreatedAt                pgtype.Timestamptz
1832
+	UpdatedAt                pgtype.Timestamptz
1833
+}
1834
+
17531835
 type ActionsVariable struct {
17541836
 	ID              int64
17551837
 	RepoID          pgtype.Int8
@@ -2757,6 +2839,18 @@ type WorkflowRun struct {
27572839
 	TriggerEventID   string
27582840
 }
27592841
 
2842
+type WorkflowRunApproval struct {
2843
+	RunID            int64
2844
+	RequestedReason  string
2845
+	RequestedAt      pgtype.Timestamptz
2846
+	ApprovedByUserID pgtype.Int8
2847
+	ApprovedAt       pgtype.Timestamptz
2848
+	RejectedByUserID pgtype.Int8
2849
+	RejectedAt       pgtype.Timestamptz
2850
+	CreatedAt        pgtype.Timestamptz
2851
+	UpdatedAt        pgtype.Timestamptz
2852
+}
2853
+
27602854
 type WorkflowRunner struct {
27612855
 	ID                 int64
27622856
 	Name               string
internal/actions/sqlc/querier.gomodified
@@ -13,10 +13,15 @@ import (
1313
 type Querier interface {
1414
 	// SPDX-License-Identifier: AGPL-3.0-or-later
1515
 	AppendStepLogChunk(ctx context.Context, db DBTX, arg AppendStepLogChunkParams) (AppendStepLogChunkRow, error)
16
+	ApproveWorkflowRun(ctx context.Context, db DBTX, arg ApproveWorkflowRunParams) (ApproveWorkflowRunRow, error)
1617
 	CancelOpenWorkflowStepsForJob(ctx context.Context, db DBTX, jobID int64) ([]WorkflowStep, error)
1718
 	ClaimQueuedWorkflowJob(ctx context.Context, db DBTX, arg ClaimQueuedWorkflowJobParams) (ClaimQueuedWorkflowJobRow, error)
1819
 	CompleteWorkflowRun(ctx context.Context, db DBTX, arg CompleteWorkflowRunParams) (WorkflowRun, error)
20
+	CountQueuedWorkflowRunsForRepo(ctx context.Context, db DBTX, repoID int64) (int64, error)
21
+	CountRecentWorkflowRunsForActor(ctx context.Context, db DBTX, arg CountRecentWorkflowRunsForActorParams) (int64, error)
1922
 	CountRunningJobsForRunner(ctx context.Context, db DBTX, runnerID int64) (int32, error)
23
+	CountRunningWorkflowJobsForOwner(ctx context.Context, db DBTX, repoID int64) (int64, error)
24
+	CountRunningWorkflowJobsForRepo(ctx context.Context, db DBTX, repoID int64) (int64, error)
2025
 	CountWorkflowCachesForRepo(ctx context.Context, db DBTX, arg CountWorkflowCachesForRepoParams) (int64, error)
2126
 	CountWorkflowRunsForRepo(ctx context.Context, db DBTX, arg CountWorkflowRunsForRepoParams) (int64, error)
2227
 	DeleteOldRunnerJWTUsesForCleanup(ctx context.Context, db DBTX, expiresAt pgtype.Timestamptz) (int64, error)
@@ -55,7 +60,10 @@ type Querier interface {
5560
 	// in migration 0051; both must agree for postgres to infer the
5661
 	// target.
5762
 	EnqueueWorkflowRun(ctx context.Context, db DBTX, arg EnqueueWorkflowRunParams) (WorkflowRun, error)
63
+	GetActionsRepoPolicy(ctx context.Context, db DBTX, repoID int64) (ActionsRepoPolicy, error)
5864
 	GetArtifactByID(ctx context.Context, db DBTX, id int64) (WorkflowArtifact, error)
65
+	// SPDX-License-Identifier: AGPL-3.0-or-later
66
+	GetEffectiveActionsPolicyForRepo(ctx context.Context, db DBTX, id int64) (GetEffectiveActionsPolicyForRepoRow, error)
5967
 	GetFirstStepForJob(ctx context.Context, db DBTX, jobID int64) (WorkflowStep, error)
6068
 	GetOrgSecret(ctx context.Context, db DBTX, arg GetOrgSecretParams) (GetOrgSecretRow, error)
6169
 	GetOrgVariable(ctx context.Context, db DBTX, arg GetOrgVariableParams) (GetOrgVariableRow, error)
@@ -69,6 +77,7 @@ type Querier interface {
6977
 	GetWorkflowCacheByID(ctx context.Context, db DBTX, id int64) (WorkflowCache, error)
7078
 	GetWorkflowJobByID(ctx context.Context, db DBTX, id int64) (WorkflowJob, error)
7179
 	GetWorkflowJobSecretMask(ctx context.Context, db DBTX, jobID int64) (WorkflowJobSecretMask, error)
80
+	GetWorkflowRunApproval(ctx context.Context, db DBTX, runID int64) (WorkflowRunApproval, error)
7281
 	GetWorkflowRunByID(ctx context.Context, db DBTX, id int64) (WorkflowRun, error)
7382
 	GetWorkflowRunForRepoByIndex(ctx context.Context, db DBTX, arg GetWorkflowRunForRepoByIndexParams) (GetWorkflowRunForRepoByIndexRow, error)
7483
 	GetWorkflowStepByID(ctx context.Context, db DBTX, id int64) (WorkflowStep, error)
@@ -89,6 +98,8 @@ type Querier interface {
8998
 	// SPDX-License-Identifier: AGPL-3.0-or-later
9099
 	InsertWorkflowRun(ctx context.Context, db DBTX, arg InsertWorkflowRunParams) (WorkflowRun, error)
91100
 	// SPDX-License-Identifier: AGPL-3.0-or-later
101
+	InsertWorkflowRunApproval(ctx context.Context, db DBTX, arg InsertWorkflowRunApprovalParams) (WorkflowRunApproval, error)
102
+	// SPDX-License-Identifier: AGPL-3.0-or-later
92103
 	InsertWorkflowStep(ctx context.Context, db DBTX, arg InsertWorkflowStepParams) (WorkflowStep, error)
93104
 	// SPDX-License-Identifier: AGPL-3.0-or-later
94105
 	// Hot path for trigger.Enqueue: skip enqueueing when the row exists.
@@ -133,6 +144,8 @@ type Querier interface {
133144
 	LookupWorkflowRunByTriggerEvent(ctx context.Context, db DBTX, arg LookupWorkflowRunByTriggerEventParams) (WorkflowRun, error)
134145
 	// SPDX-License-Identifier: AGPL-3.0-or-later
135146
 	MarkRunnerJWTUsed(ctx context.Context, db DBTX, arg MarkRunnerJWTUsedParams) (RunnerJwtUsed, error)
147
+	MarkWorkflowJobsRejected(ctx context.Context, db DBTX, runID int64) ([]WorkflowJob, error)
148
+	MarkWorkflowRunRejected(ctx context.Context, db DBTX, id int64) (WorkflowRun, error)
136149
 	MarkWorkflowRunRunning(ctx context.Context, db DBTX, id int64) error
137150
 	// Atomic next-index emitter: take the max + 1 for this repo. Pairs
138151
 	// with the (repo_id, run_index) UNIQUE so concurrent inserts that
@@ -140,6 +153,7 @@ type Querier interface {
140153
 	// Cast to bigint so sqlc generates int64 (the column type) rather
141154
 	// than int32 (the type the +1 literal would default to).
142155
 	NextRunIndexForRepo(ctx context.Context, db DBTX, repoID int64) (int64, error)
156
+	RejectWorkflowRunApproval(ctx context.Context, db DBTX, arg RejectWorkflowRunApprovalParams) (WorkflowRunApproval, error)
143157
 	RequestWorkflowJobCancel(ctx context.Context, db DBTX, id int64) (WorkflowJob, error)
144158
 	RequestWorkflowRunCancel(ctx context.Context, db DBTX, runID int64) ([]WorkflowJob, error)
145159
 	RevokeAllTokensForRunner(ctx context.Context, db DBTX, runnerID int64) error
@@ -152,6 +166,7 @@ type Querier interface {
152166
 	UpdateWorkflowJobStatus(ctx context.Context, db DBTX, arg UpdateWorkflowJobStatusParams) (WorkflowJob, error)
153167
 	UpdateWorkflowStepLogObject(ctx context.Context, db DBTX, arg UpdateWorkflowStepLogObjectParams) (WorkflowStep, error)
154168
 	UpdateWorkflowStepStatus(ctx context.Context, db DBTX, arg UpdateWorkflowStepStatusParams) (WorkflowStep, error)
169
+	UpsertActionsRepoPolicy(ctx context.Context, db DBTX, arg UpsertActionsRepoPolicyParams) (ActionsRepoPolicy, error)
155170
 	UpsertOrgSecret(ctx context.Context, db DBTX, arg UpsertOrgSecretParams) (WorkflowSecret, error)
156171
 	UpsertOrgVariable(ctx context.Context, db DBTX, arg UpsertOrgVariableParams) (ActionsVariable, error)
157172
 	// SPDX-License-Identifier: AGPL-3.0-or-later
internal/actions/sqlc/workflow_jobs.sql.gomodified
@@ -16,10 +16,40 @@ WITH candidate AS (
1616
     SELECT j.id
1717
     FROM workflow_jobs j
1818
     JOIN workflow_runs r ON r.id = j.run_id
19
+    JOIN repos repo ON repo.id = r.repo_id
20
+    LEFT JOIN actions_site_policy sp ON sp.id = true
21
+    LEFT JOIN actions_org_policies op ON op.org_id = repo.owner_org_id
22
+    LEFT JOIN actions_repo_policies rp ON rp.repo_id = r.repo_id
1923
     WHERE j.status = 'queued'
2024
       AND r.status IN ('queued', 'running')
25
+      AND (r.need_approval = false OR r.approved_by_user_id IS NOT NULL)
2126
       AND j.cancel_requested = false
2227
       AND j.runner_id IS NULL
28
+      AND CASE
29
+          WHEN COALESCE(rp.actions_enabled, 'inherit'::actions_policy_state) = 'enabled' THEN true
30
+          WHEN COALESCE(rp.actions_enabled, 'inherit'::actions_policy_state) = 'disabled' THEN false
31
+          WHEN COALESCE(op.actions_enabled, 'inherit'::actions_policy_state) = 'enabled' THEN true
32
+          WHEN COALESCE(op.actions_enabled, 'inherit'::actions_policy_state) = 'disabled' THEN false
33
+          ELSE COALESCE(sp.actions_enabled, true)
34
+      END
35
+      AND (
36
+          SELECT COUNT(*)::integer
37
+          FROM workflow_jobs running_job
38
+          JOIN workflow_runs running_run ON running_run.id = running_job.run_id
39
+          WHERE running_job.status = 'running'
40
+            AND running_run.repo_id = r.repo_id
41
+      ) < COALESCE(rp.max_repo_concurrent_jobs, op.max_repo_concurrent_jobs, sp.max_repo_concurrent_jobs, 20)
42
+      AND (
43
+          SELECT COUNT(*)::integer
44
+          FROM workflow_jobs running_job
45
+          JOIN workflow_runs running_run ON running_run.id = running_job.run_id
46
+          JOIN repos running_repo ON running_repo.id = running_run.repo_id
47
+          WHERE running_job.status = 'running'
48
+            AND (
49
+                (repo.owner_user_id IS NOT NULL AND running_repo.owner_user_id = repo.owner_user_id)
50
+                OR (repo.owner_org_id IS NOT NULL AND running_repo.owner_org_id = repo.owner_org_id)
51
+            )
52
+      ) < COALESCE(rp.max_owner_concurrent_jobs, op.max_owner_concurrent_jobs, sp.max_owner_concurrent_jobs, 100)
2353
       AND (j.runs_on = '' OR j.runs_on = ANY($1::text[]))
2454
       AND NOT EXISTS (
2555
           SELECT 1
internal/actions/sqlc/workflow_run_approvals.sql.goadded
@@ -0,0 +1,322 @@
1
+// Code generated by sqlc. DO NOT EDIT.
2
+// versions:
3
+//   sqlc v1.31.1
4
+// source: workflow_run_approvals.sql
5
+
6
+package actionsdb
7
+
8
+import (
9
+	"context"
10
+
11
+	"github.com/jackc/pgx/v5/pgtype"
12
+)
13
+
14
+const approveWorkflowRun = `-- name: ApproveWorkflowRun :one
15
+WITH run AS (
16
+    UPDATE workflow_runs r
17
+    SET approved_by_user_id = $2,
18
+        version = version + 1,
19
+        updated_at = now()
20
+    WHERE r.id = $1
21
+      AND r.need_approval = true
22
+      AND r.approved_by_user_id IS NULL
23
+      AND r.status = 'queued'
24
+      AND EXISTS (
25
+          SELECT 1
26
+          FROM workflow_run_approvals a
27
+          WHERE a.run_id = r.id
28
+            AND a.approved_at IS NULL
29
+            AND a.rejected_at IS NULL
30
+      )
31
+    RETURNING r.id, r.repo_id, r.run_index, r.workflow_file, r.workflow_name,
32
+              r.head_sha, r.head_ref, r.event, r.event_payload,
33
+              r.actor_user_id, r.parent_run_id, r.concurrency_group,
34
+              r.status, r.conclusion, r.pinned, r.need_approval, r.approved_by_user_id,
35
+              r.started_at, r.completed_at, r.version, r.created_at, r.updated_at, r.trigger_event_id
36
+), approval AS (
37
+    UPDATE workflow_run_approvals a
38
+    SET approved_by_user_id = $2,
39
+        approved_at = now(),
40
+        updated_at = now()
41
+    FROM run r
42
+    WHERE a.run_id = r.id
43
+      AND a.approved_at IS NULL
44
+      AND a.rejected_at IS NULL
45
+    RETURNING a.run_id
46
+)
47
+SELECT r.id, r.repo_id, r.run_index, r.workflow_file, r.workflow_name,
48
+       r.head_sha, r.head_ref, r.event, r.event_payload,
49
+       r.actor_user_id, r.parent_run_id, r.concurrency_group,
50
+       r.status, r.conclusion, r.pinned, r.need_approval, r.approved_by_user_id,
51
+       r.started_at, r.completed_at, r.version, r.created_at, r.updated_at, r.trigger_event_id
52
+FROM run r
53
+JOIN approval a ON a.run_id = r.id
54
+`
55
+
56
+type ApproveWorkflowRunParams struct {
57
+	ID               int64
58
+	ApprovedByUserID pgtype.Int8
59
+}
60
+
61
+type ApproveWorkflowRunRow struct {
62
+	ID               int64
63
+	RepoID           int64
64
+	RunIndex         int64
65
+	WorkflowFile     string
66
+	WorkflowName     string
67
+	HeadSha          string
68
+	HeadRef          string
69
+	Event            WorkflowRunEvent
70
+	EventPayload     []byte
71
+	ActorUserID      pgtype.Int8
72
+	ParentRunID      pgtype.Int8
73
+	ConcurrencyGroup string
74
+	Status           WorkflowRunStatus
75
+	Conclusion       NullCheckConclusion
76
+	Pinned           bool
77
+	NeedApproval     bool
78
+	ApprovedByUserID pgtype.Int8
79
+	StartedAt        pgtype.Timestamptz
80
+	CompletedAt      pgtype.Timestamptz
81
+	Version          int32
82
+	CreatedAt        pgtype.Timestamptz
83
+	UpdatedAt        pgtype.Timestamptz
84
+	TriggerEventID   string
85
+}
86
+
87
+func (q *Queries) ApproveWorkflowRun(ctx context.Context, db DBTX, arg ApproveWorkflowRunParams) (ApproveWorkflowRunRow, error) {
88
+	row := db.QueryRow(ctx, approveWorkflowRun, arg.ID, arg.ApprovedByUserID)
89
+	var i ApproveWorkflowRunRow
90
+	err := row.Scan(
91
+		&i.ID,
92
+		&i.RepoID,
93
+		&i.RunIndex,
94
+		&i.WorkflowFile,
95
+		&i.WorkflowName,
96
+		&i.HeadSha,
97
+		&i.HeadRef,
98
+		&i.Event,
99
+		&i.EventPayload,
100
+		&i.ActorUserID,
101
+		&i.ParentRunID,
102
+		&i.ConcurrencyGroup,
103
+		&i.Status,
104
+		&i.Conclusion,
105
+		&i.Pinned,
106
+		&i.NeedApproval,
107
+		&i.ApprovedByUserID,
108
+		&i.StartedAt,
109
+		&i.CompletedAt,
110
+		&i.Version,
111
+		&i.CreatedAt,
112
+		&i.UpdatedAt,
113
+		&i.TriggerEventID,
114
+	)
115
+	return i, err
116
+}
117
+
118
+const getWorkflowRunApproval = `-- name: GetWorkflowRunApproval :one
119
+SELECT run_id, requested_reason, requested_at,
120
+       approved_by_user_id, approved_at,
121
+       rejected_by_user_id, rejected_at,
122
+       created_at, updated_at
123
+FROM workflow_run_approvals
124
+WHERE run_id = $1
125
+`
126
+
127
+func (q *Queries) GetWorkflowRunApproval(ctx context.Context, db DBTX, runID int64) (WorkflowRunApproval, error) {
128
+	row := db.QueryRow(ctx, getWorkflowRunApproval, runID)
129
+	var i WorkflowRunApproval
130
+	err := row.Scan(
131
+		&i.RunID,
132
+		&i.RequestedReason,
133
+		&i.RequestedAt,
134
+		&i.ApprovedByUserID,
135
+		&i.ApprovedAt,
136
+		&i.RejectedByUserID,
137
+		&i.RejectedAt,
138
+		&i.CreatedAt,
139
+		&i.UpdatedAt,
140
+	)
141
+	return i, err
142
+}
143
+
144
+const insertWorkflowRunApproval = `-- name: InsertWorkflowRunApproval :one
145
+
146
+INSERT INTO workflow_run_approvals (run_id, requested_reason)
147
+VALUES ($1, $2)
148
+ON CONFLICT (run_id) DO UPDATE SET
149
+    requested_reason = EXCLUDED.requested_reason,
150
+    updated_at = now()
151
+RETURNING run_id, requested_reason, requested_at,
152
+          approved_by_user_id, approved_at,
153
+          rejected_by_user_id, rejected_at,
154
+          created_at, updated_at
155
+`
156
+
157
+type InsertWorkflowRunApprovalParams struct {
158
+	RunID           int64
159
+	RequestedReason string
160
+}
161
+
162
+// SPDX-License-Identifier: AGPL-3.0-or-later
163
+func (q *Queries) InsertWorkflowRunApproval(ctx context.Context, db DBTX, arg InsertWorkflowRunApprovalParams) (WorkflowRunApproval, error) {
164
+	row := db.QueryRow(ctx, insertWorkflowRunApproval, arg.RunID, arg.RequestedReason)
165
+	var i WorkflowRunApproval
166
+	err := row.Scan(
167
+		&i.RunID,
168
+		&i.RequestedReason,
169
+		&i.RequestedAt,
170
+		&i.ApprovedByUserID,
171
+		&i.ApprovedAt,
172
+		&i.RejectedByUserID,
173
+		&i.RejectedAt,
174
+		&i.CreatedAt,
175
+		&i.UpdatedAt,
176
+	)
177
+	return i, err
178
+}
179
+
180
+const markWorkflowJobsRejected = `-- name: MarkWorkflowJobsRejected :many
181
+UPDATE workflow_jobs
182
+SET cancel_requested = true,
183
+    status = 'cancelled',
184
+    conclusion = 'action_required',
185
+    started_at = COALESCE(started_at, now()),
186
+    completed_at = COALESCE(completed_at, now()),
187
+    version = version + 1,
188
+    updated_at = now()
189
+WHERE run_id = $1
190
+  AND status = 'queued'
191
+RETURNING id, run_id, job_index, job_key, job_name, runs_on,
192
+          runner_id, needs_jobs, if_expr, timeout_minutes, permissions,
193
+          job_env, status, conclusion, cancel_requested,
194
+          started_at, completed_at, version, created_at, updated_at
195
+`
196
+
197
+func (q *Queries) MarkWorkflowJobsRejected(ctx context.Context, db DBTX, runID int64) ([]WorkflowJob, error) {
198
+	rows, err := db.Query(ctx, markWorkflowJobsRejected, runID)
199
+	if err != nil {
200
+		return nil, err
201
+	}
202
+	defer rows.Close()
203
+	items := []WorkflowJob{}
204
+	for rows.Next() {
205
+		var i WorkflowJob
206
+		if err := rows.Scan(
207
+			&i.ID,
208
+			&i.RunID,
209
+			&i.JobIndex,
210
+			&i.JobKey,
211
+			&i.JobName,
212
+			&i.RunsOn,
213
+			&i.RunnerID,
214
+			&i.NeedsJobs,
215
+			&i.IfExpr,
216
+			&i.TimeoutMinutes,
217
+			&i.Permissions,
218
+			&i.JobEnv,
219
+			&i.Status,
220
+			&i.Conclusion,
221
+			&i.CancelRequested,
222
+			&i.StartedAt,
223
+			&i.CompletedAt,
224
+			&i.Version,
225
+			&i.CreatedAt,
226
+			&i.UpdatedAt,
227
+		); err != nil {
228
+			return nil, err
229
+		}
230
+		items = append(items, i)
231
+	}
232
+	if err := rows.Err(); err != nil {
233
+		return nil, err
234
+	}
235
+	return items, nil
236
+}
237
+
238
+const markWorkflowRunRejected = `-- name: MarkWorkflowRunRejected :one
239
+UPDATE workflow_runs
240
+SET status = 'completed',
241
+    conclusion = 'action_required',
242
+    started_at = COALESCE(started_at, now()),
243
+    completed_at = COALESCE(completed_at, now()),
244
+    version = version + 1,
245
+    updated_at = now()
246
+WHERE id = $1
247
+  AND need_approval = true
248
+  AND approved_by_user_id IS NULL
249
+  AND status = 'queued'
250
+RETURNING id, repo_id, run_index, workflow_file, workflow_name,
251
+          head_sha, head_ref, event, event_payload,
252
+          actor_user_id, parent_run_id, concurrency_group,
253
+          status, conclusion, pinned, need_approval, approved_by_user_id,
254
+          started_at, completed_at, version, created_at, updated_at, trigger_event_id
255
+`
256
+
257
+func (q *Queries) MarkWorkflowRunRejected(ctx context.Context, db DBTX, id int64) (WorkflowRun, error) {
258
+	row := db.QueryRow(ctx, markWorkflowRunRejected, id)
259
+	var i WorkflowRun
260
+	err := row.Scan(
261
+		&i.ID,
262
+		&i.RepoID,
263
+		&i.RunIndex,
264
+		&i.WorkflowFile,
265
+		&i.WorkflowName,
266
+		&i.HeadSha,
267
+		&i.HeadRef,
268
+		&i.Event,
269
+		&i.EventPayload,
270
+		&i.ActorUserID,
271
+		&i.ParentRunID,
272
+		&i.ConcurrencyGroup,
273
+		&i.Status,
274
+		&i.Conclusion,
275
+		&i.Pinned,
276
+		&i.NeedApproval,
277
+		&i.ApprovedByUserID,
278
+		&i.StartedAt,
279
+		&i.CompletedAt,
280
+		&i.Version,
281
+		&i.CreatedAt,
282
+		&i.UpdatedAt,
283
+		&i.TriggerEventID,
284
+	)
285
+	return i, err
286
+}
287
+
288
+const rejectWorkflowRunApproval = `-- name: RejectWorkflowRunApproval :one
289
+UPDATE workflow_run_approvals
290
+SET rejected_by_user_id = $2,
291
+    rejected_at = now(),
292
+    updated_at = now()
293
+WHERE run_id = $1
294
+  AND approved_at IS NULL
295
+  AND rejected_at IS NULL
296
+RETURNING run_id, requested_reason, requested_at,
297
+          approved_by_user_id, approved_at,
298
+          rejected_by_user_id, rejected_at,
299
+          created_at, updated_at
300
+`
301
+
302
+type RejectWorkflowRunApprovalParams struct {
303
+	RunID            int64
304
+	RejectedByUserID pgtype.Int8
305
+}
306
+
307
+func (q *Queries) RejectWorkflowRunApproval(ctx context.Context, db DBTX, arg RejectWorkflowRunApprovalParams) (WorkflowRunApproval, error) {
308
+	row := db.QueryRow(ctx, rejectWorkflowRunApproval, arg.RunID, arg.RejectedByUserID)
309
+	var i WorkflowRunApproval
310
+	err := row.Scan(
311
+		&i.RunID,
312
+		&i.RequestedReason,
313
+		&i.RequestedAt,
314
+		&i.ApprovedByUserID,
315
+		&i.ApprovedAt,
316
+		&i.RejectedByUserID,
317
+		&i.RejectedAt,
318
+		&i.CreatedAt,
319
+		&i.UpdatedAt,
320
+	)
321
+	return i, err
322
+}
internal/actions/sqlc/workflow_runs.sql.gomodified
@@ -785,6 +785,7 @@ SET status = 'running',
785785
     version = version + 1,
786786
     updated_at = now()
787787
 WHERE id = $1 AND status = 'queued'
788
+  AND (need_approval = false OR approved_by_user_id IS NOT NULL)
788789
 RETURNING id, repo_id, run_index, workflow_file, workflow_name,
789790
           head_sha, head_ref, event, event_payload,
790791
           actor_user_id, parent_run_id, concurrency_group,
internal/admin/sqlc/models.gomodified
@@ -12,6 +12,49 @@ import (
1212
 	"github.com/jackc/pgx/v5/pgtype"
1313
 )
1414
 
15
+type ActionsPolicyState string
16
+
17
+const (
18
+	ActionsPolicyStateInherit  ActionsPolicyState = "inherit"
19
+	ActionsPolicyStateEnabled  ActionsPolicyState = "enabled"
20
+	ActionsPolicyStateDisabled ActionsPolicyState = "disabled"
21
+)
22
+
23
+func (e *ActionsPolicyState) Scan(src interface{}) error {
24
+	switch s := src.(type) {
25
+	case []byte:
26
+		*e = ActionsPolicyState(s)
27
+	case string:
28
+		*e = ActionsPolicyState(s)
29
+	default:
30
+		return fmt.Errorf("unsupported scan type for ActionsPolicyState: %T", src)
31
+	}
32
+	return nil
33
+}
34
+
35
+type NullActionsPolicyState struct {
36
+	ActionsPolicyState ActionsPolicyState
37
+	Valid              bool // Valid is true if ActionsPolicyState is not NULL
38
+}
39
+
40
+// Scan implements the Scanner interface.
41
+func (ns *NullActionsPolicyState) Scan(value interface{}) error {
42
+	if value == nil {
43
+		ns.ActionsPolicyState, ns.Valid = "", false
44
+		return nil
45
+	}
46
+	ns.Valid = true
47
+	return ns.ActionsPolicyState.Scan(value)
48
+}
49
+
50
+// Value implements the driver Valuer interface.
51
+func (ns NullActionsPolicyState) Value() (driver.Value, error) {
52
+	if !ns.Valid {
53
+		return nil, nil
54
+	}
55
+	return string(ns.ActionsPolicyState), nil
56
+}
57
+
1558
 type BillingInvoiceStatus string
1659
 
1760
 const (
@@ -1750,6 +1793,45 @@ func (ns NullWorkflowStepStatus) Value() (driver.Value, error) {
17501793
 	return string(ns.WorkflowStepStatus), nil
17511794
 }
17521795
 
1796
+type ActionsOrgPolicy struct {
1797
+	OrgID                    int64
1798
+	ActionsEnabled           ActionsPolicyState
1799
+	RequirePrApproval        pgtype.Bool
1800
+	MaxRepoQueuedRuns        pgtype.Int4
1801
+	MaxRepoConcurrentJobs    pgtype.Int4
1802
+	MaxOwnerConcurrentJobs   pgtype.Int4
1803
+	ActorTriggerLimitPerHour pgtype.Int4
1804
+	UpdatedByUserID          pgtype.Int8
1805
+	CreatedAt                pgtype.Timestamptz
1806
+	UpdatedAt                pgtype.Timestamptz
1807
+}
1808
+
1809
+type ActionsRepoPolicy struct {
1810
+	RepoID                   int64
1811
+	ActionsEnabled           ActionsPolicyState
1812
+	RequirePrApproval        pgtype.Bool
1813
+	MaxRepoQueuedRuns        pgtype.Int4
1814
+	MaxRepoConcurrentJobs    pgtype.Int4
1815
+	MaxOwnerConcurrentJobs   pgtype.Int4
1816
+	ActorTriggerLimitPerHour pgtype.Int4
1817
+	UpdatedByUserID          pgtype.Int8
1818
+	CreatedAt                pgtype.Timestamptz
1819
+	UpdatedAt                pgtype.Timestamptz
1820
+}
1821
+
1822
+type ActionsSitePolicy struct {
1823
+	ID                       bool
1824
+	ActionsEnabled           bool
1825
+	RequirePrApproval        bool
1826
+	MaxRepoQueuedRuns        int32
1827
+	MaxRepoConcurrentJobs    int32
1828
+	MaxOwnerConcurrentJobs   int32
1829
+	ActorTriggerLimitPerHour int32
1830
+	UpdatedByUserID          pgtype.Int8
1831
+	CreatedAt                pgtype.Timestamptz
1832
+	UpdatedAt                pgtype.Timestamptz
1833
+}
1834
+
17531835
 type ActionsVariable struct {
17541836
 	ID              int64
17551837
 	RepoID          pgtype.Int8
@@ -2757,6 +2839,18 @@ type WorkflowRun struct {
27572839
 	TriggerEventID   string
27582840
 }
27592841
 
2842
+type WorkflowRunApproval struct {
2843
+	RunID            int64
2844
+	RequestedReason  string
2845
+	RequestedAt      pgtype.Timestamptz
2846
+	ApprovedByUserID pgtype.Int8
2847
+	ApprovedAt       pgtype.Timestamptz
2848
+	RejectedByUserID pgtype.Int8
2849
+	RejectedAt       pgtype.Timestamptz
2850
+	CreatedAt        pgtype.Timestamptz
2851
+	UpdatedAt        pgtype.Timestamptz
2852
+}
2853
+
27602854
 type WorkflowRunner struct {
27612855
 	ID                 int64
27622856
 	Name               string
internal/auth/policy/sqlc/models.gomodified
@@ -12,6 +12,49 @@ import (
1212
 	"github.com/jackc/pgx/v5/pgtype"
1313
 )
1414
 
15
+type ActionsPolicyState string
16
+
17
+const (
18
+	ActionsPolicyStateInherit  ActionsPolicyState = "inherit"
19
+	ActionsPolicyStateEnabled  ActionsPolicyState = "enabled"
20
+	ActionsPolicyStateDisabled ActionsPolicyState = "disabled"
21
+)
22
+
23
+func (e *ActionsPolicyState) Scan(src interface{}) error {
24
+	switch s := src.(type) {
25
+	case []byte:
26
+		*e = ActionsPolicyState(s)
27
+	case string:
28
+		*e = ActionsPolicyState(s)
29
+	default:
30
+		return fmt.Errorf("unsupported scan type for ActionsPolicyState: %T", src)
31
+	}
32
+	return nil
33
+}
34
+
35
+type NullActionsPolicyState struct {
36
+	ActionsPolicyState ActionsPolicyState
37
+	Valid              bool // Valid is true if ActionsPolicyState is not NULL
38
+}
39
+
40
+// Scan implements the Scanner interface.
41
+func (ns *NullActionsPolicyState) Scan(value interface{}) error {
42
+	if value == nil {
43
+		ns.ActionsPolicyState, ns.Valid = "", false
44
+		return nil
45
+	}
46
+	ns.Valid = true
47
+	return ns.ActionsPolicyState.Scan(value)
48
+}
49
+
50
+// Value implements the driver Valuer interface.
51
+func (ns NullActionsPolicyState) Value() (driver.Value, error) {
52
+	if !ns.Valid {
53
+		return nil, nil
54
+	}
55
+	return string(ns.ActionsPolicyState), nil
56
+}
57
+
1558
 type BillingInvoiceStatus string
1659
 
1760
 const (
@@ -1750,6 +1793,45 @@ func (ns NullWorkflowStepStatus) Value() (driver.Value, error) {
17501793
 	return string(ns.WorkflowStepStatus), nil
17511794
 }
17521795
 
1796
+type ActionsOrgPolicy struct {
1797
+	OrgID                    int64
1798
+	ActionsEnabled           ActionsPolicyState
1799
+	RequirePrApproval        pgtype.Bool
1800
+	MaxRepoQueuedRuns        pgtype.Int4
1801
+	MaxRepoConcurrentJobs    pgtype.Int4
1802
+	MaxOwnerConcurrentJobs   pgtype.Int4
1803
+	ActorTriggerLimitPerHour pgtype.Int4
1804
+	UpdatedByUserID          pgtype.Int8
1805
+	CreatedAt                pgtype.Timestamptz
1806
+	UpdatedAt                pgtype.Timestamptz
1807
+}
1808
+
1809
+type ActionsRepoPolicy struct {
1810
+	RepoID                   int64
1811
+	ActionsEnabled           ActionsPolicyState
1812
+	RequirePrApproval        pgtype.Bool
1813
+	MaxRepoQueuedRuns        pgtype.Int4
1814
+	MaxRepoConcurrentJobs    pgtype.Int4
1815
+	MaxOwnerConcurrentJobs   pgtype.Int4
1816
+	ActorTriggerLimitPerHour pgtype.Int4
1817
+	UpdatedByUserID          pgtype.Int8
1818
+	CreatedAt                pgtype.Timestamptz
1819
+	UpdatedAt                pgtype.Timestamptz
1820
+}
1821
+
1822
+type ActionsSitePolicy struct {
1823
+	ID                       bool
1824
+	ActionsEnabled           bool
1825
+	RequirePrApproval        bool
1826
+	MaxRepoQueuedRuns        int32
1827
+	MaxRepoConcurrentJobs    int32
1828
+	MaxOwnerConcurrentJobs   int32
1829
+	ActorTriggerLimitPerHour int32
1830
+	UpdatedByUserID          pgtype.Int8
1831
+	CreatedAt                pgtype.Timestamptz
1832
+	UpdatedAt                pgtype.Timestamptz
1833
+}
1834
+
17531835
 type ActionsVariable struct {
17541836
 	ID              int64
17551837
 	RepoID          pgtype.Int8
@@ -1889,6 +1971,22 @@ type CodeSearchPath struct {
18891971
 	Tsv     interface{}
18901972
 }
18911973
 
1974
+type DeviceAuthorization struct {
1975
+	ID              int64
1976
+	DeviceCodeHash  []byte
1977
+	UserCode        string
1978
+	ClientID        string
1979
+	Scopes          []string
1980
+	UserID          pgtype.Int8
1981
+	ApprovedAt      pgtype.Timestamptz
1982
+	DeniedAt        pgtype.Timestamptz
1983
+	IssuedTokenID   pgtype.Int8
1984
+	IntervalSeconds int32
1985
+	ExpiresAt       pgtype.Timestamptz
1986
+	LastPolledAt    pgtype.Timestamptz
1987
+	CreatedAt       pgtype.Timestamptz
1988
+}
1989
+
18921990
 type DomainEvent struct {
18931991
 	ID          int64
18941992
 	ActorUserID pgtype.Int8
@@ -2666,6 +2764,25 @@ type WorkflowArtifact struct {
26662764
 	CreatedAt pgtype.Timestamptz
26672765
 }
26682766
 
2767
+type WorkflowCach struct {
2768
+	ID             int64
2769
+	RepoID         int64
2770
+	CacheKey       string
2771
+	CacheVersion   string
2772
+	GitRef         string
2773
+	ObjectKey      string
2774
+	SizeBytes      int64
2775
+	LastAccessedAt pgtype.Timestamptz
2776
+	CreatedAt      pgtype.Timestamptz
2777
+}
2778
+
2779
+type WorkflowDisabled struct {
2780
+	RepoID           int64
2781
+	WorkflowFile     string
2782
+	DisabledByUserID pgtype.Int8
2783
+	DisabledAt       pgtype.Timestamptz
2784
+}
2785
+
26692786
 type WorkflowJob struct {
26702787
 	ID              int64
26712788
 	RunID           int64
@@ -2722,6 +2839,18 @@ type WorkflowRun struct {
27222839
 	TriggerEventID   string
27232840
 }
27242841
 
2842
+type WorkflowRunApproval struct {
2843
+	RunID            int64
2844
+	RequestedReason  string
2845
+	RequestedAt      pgtype.Timestamptz
2846
+	ApprovedByUserID pgtype.Int8
2847
+	ApprovedAt       pgtype.Timestamptz
2848
+	RejectedByUserID pgtype.Int8
2849
+	RejectedAt       pgtype.Timestamptz
2850
+	CreatedAt        pgtype.Timestamptz
2851
+	UpdatedAt        pgtype.Timestamptz
2852
+}
2853
+
27252854
 type WorkflowRunner struct {
27262855
 	ID                 int64
27272856
 	Name               string
internal/billing/sqlc/models.gomodified
@@ -12,6 +12,49 @@ import (
1212
 	"github.com/jackc/pgx/v5/pgtype"
1313
 )
1414
 
15
+type ActionsPolicyState string
16
+
17
+const (
18
+	ActionsPolicyStateInherit  ActionsPolicyState = "inherit"
19
+	ActionsPolicyStateEnabled  ActionsPolicyState = "enabled"
20
+	ActionsPolicyStateDisabled ActionsPolicyState = "disabled"
21
+)
22
+
23
+func (e *ActionsPolicyState) Scan(src interface{}) error {
24
+	switch s := src.(type) {
25
+	case []byte:
26
+		*e = ActionsPolicyState(s)
27
+	case string:
28
+		*e = ActionsPolicyState(s)
29
+	default:
30
+		return fmt.Errorf("unsupported scan type for ActionsPolicyState: %T", src)
31
+	}
32
+	return nil
33
+}
34
+
35
+type NullActionsPolicyState struct {
36
+	ActionsPolicyState ActionsPolicyState
37
+	Valid              bool // Valid is true if ActionsPolicyState is not NULL
38
+}
39
+
40
+// Scan implements the Scanner interface.
41
+func (ns *NullActionsPolicyState) Scan(value interface{}) error {
42
+	if value == nil {
43
+		ns.ActionsPolicyState, ns.Valid = "", false
44
+		return nil
45
+	}
46
+	ns.Valid = true
47
+	return ns.ActionsPolicyState.Scan(value)
48
+}
49
+
50
+// Value implements the driver Valuer interface.
51
+func (ns NullActionsPolicyState) Value() (driver.Value, error) {
52
+	if !ns.Valid {
53
+		return nil, nil
54
+	}
55
+	return string(ns.ActionsPolicyState), nil
56
+}
57
+
1558
 type BillingInvoiceStatus string
1659
 
1760
 const (
@@ -1750,6 +1793,45 @@ func (ns NullWorkflowStepStatus) Value() (driver.Value, error) {
17501793
 	return string(ns.WorkflowStepStatus), nil
17511794
 }
17521795
 
1796
+type ActionsOrgPolicy struct {
1797
+	OrgID                    int64
1798
+	ActionsEnabled           ActionsPolicyState
1799
+	RequirePrApproval        pgtype.Bool
1800
+	MaxRepoQueuedRuns        pgtype.Int4
1801
+	MaxRepoConcurrentJobs    pgtype.Int4
1802
+	MaxOwnerConcurrentJobs   pgtype.Int4
1803
+	ActorTriggerLimitPerHour pgtype.Int4
1804
+	UpdatedByUserID          pgtype.Int8
1805
+	CreatedAt                pgtype.Timestamptz
1806
+	UpdatedAt                pgtype.Timestamptz
1807
+}
1808
+
1809
+type ActionsRepoPolicy struct {
1810
+	RepoID                   int64
1811
+	ActionsEnabled           ActionsPolicyState
1812
+	RequirePrApproval        pgtype.Bool
1813
+	MaxRepoQueuedRuns        pgtype.Int4
1814
+	MaxRepoConcurrentJobs    pgtype.Int4
1815
+	MaxOwnerConcurrentJobs   pgtype.Int4
1816
+	ActorTriggerLimitPerHour pgtype.Int4
1817
+	UpdatedByUserID          pgtype.Int8
1818
+	CreatedAt                pgtype.Timestamptz
1819
+	UpdatedAt                pgtype.Timestamptz
1820
+}
1821
+
1822
+type ActionsSitePolicy struct {
1823
+	ID                       bool
1824
+	ActionsEnabled           bool
1825
+	RequirePrApproval        bool
1826
+	MaxRepoQueuedRuns        int32
1827
+	MaxRepoConcurrentJobs    int32
1828
+	MaxOwnerConcurrentJobs   int32
1829
+	ActorTriggerLimitPerHour int32
1830
+	UpdatedByUserID          pgtype.Int8
1831
+	CreatedAt                pgtype.Timestamptz
1832
+	UpdatedAt                pgtype.Timestamptz
1833
+}
1834
+
17531835
 type ActionsVariable struct {
17541836
 	ID              int64
17551837
 	RepoID          pgtype.Int8
@@ -2757,6 +2839,18 @@ type WorkflowRun struct {
27572839
 	TriggerEventID   string
27582840
 }
27592841
 
2842
+type WorkflowRunApproval struct {
2843
+	RunID            int64
2844
+	RequestedReason  string
2845
+	RequestedAt      pgtype.Timestamptz
2846
+	ApprovedByUserID pgtype.Int8
2847
+	ApprovedAt       pgtype.Timestamptz
2848
+	RejectedByUserID pgtype.Int8
2849
+	RejectedAt       pgtype.Timestamptz
2850
+	CreatedAt        pgtype.Timestamptz
2851
+	UpdatedAt        pgtype.Timestamptz
2852
+}
2853
+
27602854
 type WorkflowRunner struct {
27612855
 	ID                 int64
27622856
 	Name               string
internal/checks/sqlc/models.gomodified
@@ -12,6 +12,49 @@ import (
1212
 	"github.com/jackc/pgx/v5/pgtype"
1313
 )
1414
 
15
+type ActionsPolicyState string
16
+
17
+const (
18
+	ActionsPolicyStateInherit  ActionsPolicyState = "inherit"
19
+	ActionsPolicyStateEnabled  ActionsPolicyState = "enabled"
20
+	ActionsPolicyStateDisabled ActionsPolicyState = "disabled"
21
+)
22
+
23
+func (e *ActionsPolicyState) Scan(src interface{}) error {
24
+	switch s := src.(type) {
25
+	case []byte:
26
+		*e = ActionsPolicyState(s)
27
+	case string:
28
+		*e = ActionsPolicyState(s)
29
+	default:
30
+		return fmt.Errorf("unsupported scan type for ActionsPolicyState: %T", src)
31
+	}
32
+	return nil
33
+}
34
+
35
+type NullActionsPolicyState struct {
36
+	ActionsPolicyState ActionsPolicyState
37
+	Valid              bool // Valid is true if ActionsPolicyState is not NULL
38
+}
39
+
40
+// Scan implements the Scanner interface.
41
+func (ns *NullActionsPolicyState) Scan(value interface{}) error {
42
+	if value == nil {
43
+		ns.ActionsPolicyState, ns.Valid = "", false
44
+		return nil
45
+	}
46
+	ns.Valid = true
47
+	return ns.ActionsPolicyState.Scan(value)
48
+}
49
+
50
+// Value implements the driver Valuer interface.
51
+func (ns NullActionsPolicyState) Value() (driver.Value, error) {
52
+	if !ns.Valid {
53
+		return nil, nil
54
+	}
55
+	return string(ns.ActionsPolicyState), nil
56
+}
57
+
1558
 type BillingInvoiceStatus string
1659
 
1760
 const (
@@ -1750,6 +1793,45 @@ func (ns NullWorkflowStepStatus) Value() (driver.Value, error) {
17501793
 	return string(ns.WorkflowStepStatus), nil
17511794
 }
17521795
 
1796
+type ActionsOrgPolicy struct {
1797
+	OrgID                    int64
1798
+	ActionsEnabled           ActionsPolicyState
1799
+	RequirePrApproval        pgtype.Bool
1800
+	MaxRepoQueuedRuns        pgtype.Int4
1801
+	MaxRepoConcurrentJobs    pgtype.Int4
1802
+	MaxOwnerConcurrentJobs   pgtype.Int4
1803
+	ActorTriggerLimitPerHour pgtype.Int4
1804
+	UpdatedByUserID          pgtype.Int8
1805
+	CreatedAt                pgtype.Timestamptz
1806
+	UpdatedAt                pgtype.Timestamptz
1807
+}
1808
+
1809
+type ActionsRepoPolicy struct {
1810
+	RepoID                   int64
1811
+	ActionsEnabled           ActionsPolicyState
1812
+	RequirePrApproval        pgtype.Bool
1813
+	MaxRepoQueuedRuns        pgtype.Int4
1814
+	MaxRepoConcurrentJobs    pgtype.Int4
1815
+	MaxOwnerConcurrentJobs   pgtype.Int4
1816
+	ActorTriggerLimitPerHour pgtype.Int4
1817
+	UpdatedByUserID          pgtype.Int8
1818
+	CreatedAt                pgtype.Timestamptz
1819
+	UpdatedAt                pgtype.Timestamptz
1820
+}
1821
+
1822
+type ActionsSitePolicy struct {
1823
+	ID                       bool
1824
+	ActionsEnabled           bool
1825
+	RequirePrApproval        bool
1826
+	MaxRepoQueuedRuns        int32
1827
+	MaxRepoConcurrentJobs    int32
1828
+	MaxOwnerConcurrentJobs   int32
1829
+	ActorTriggerLimitPerHour int32
1830
+	UpdatedByUserID          pgtype.Int8
1831
+	CreatedAt                pgtype.Timestamptz
1832
+	UpdatedAt                pgtype.Timestamptz
1833
+}
1834
+
17531835
 type ActionsVariable struct {
17541836
 	ID              int64
17551837
 	RepoID          pgtype.Int8
@@ -2757,6 +2839,18 @@ type WorkflowRun struct {
27572839
 	TriggerEventID   string
27582840
 }
27592841
 
2842
+type WorkflowRunApproval struct {
2843
+	RunID            int64
2844
+	RequestedReason  string
2845
+	RequestedAt      pgtype.Timestamptz
2846
+	ApprovedByUserID pgtype.Int8
2847
+	ApprovedAt       pgtype.Timestamptz
2848
+	RejectedByUserID pgtype.Int8
2849
+	RejectedAt       pgtype.Timestamptz
2850
+	CreatedAt        pgtype.Timestamptz
2851
+	UpdatedAt        pgtype.Timestamptz
2852
+}
2853
+
27602854
 type WorkflowRunner struct {
27612855
 	ID                 int64
27622856
 	Name               string
internal/issues/sqlc/models.gomodified
@@ -12,6 +12,49 @@ import (
1212
 	"github.com/jackc/pgx/v5/pgtype"
1313
 )
1414
 
15
+type ActionsPolicyState string
16
+
17
+const (
18
+	ActionsPolicyStateInherit  ActionsPolicyState = "inherit"
19
+	ActionsPolicyStateEnabled  ActionsPolicyState = "enabled"
20
+	ActionsPolicyStateDisabled ActionsPolicyState = "disabled"
21
+)
22
+
23
+func (e *ActionsPolicyState) Scan(src interface{}) error {
24
+	switch s := src.(type) {
25
+	case []byte:
26
+		*e = ActionsPolicyState(s)
27
+	case string:
28
+		*e = ActionsPolicyState(s)
29
+	default:
30
+		return fmt.Errorf("unsupported scan type for ActionsPolicyState: %T", src)
31
+	}
32
+	return nil
33
+}
34
+
35
+type NullActionsPolicyState struct {
36
+	ActionsPolicyState ActionsPolicyState
37
+	Valid              bool // Valid is true if ActionsPolicyState is not NULL
38
+}
39
+
40
+// Scan implements the Scanner interface.
41
+func (ns *NullActionsPolicyState) Scan(value interface{}) error {
42
+	if value == nil {
43
+		ns.ActionsPolicyState, ns.Valid = "", false
44
+		return nil
45
+	}
46
+	ns.Valid = true
47
+	return ns.ActionsPolicyState.Scan(value)
48
+}
49
+
50
+// Value implements the driver Valuer interface.
51
+func (ns NullActionsPolicyState) Value() (driver.Value, error) {
52
+	if !ns.Valid {
53
+		return nil, nil
54
+	}
55
+	return string(ns.ActionsPolicyState), nil
56
+}
57
+
1558
 type BillingInvoiceStatus string
1659
 
1760
 const (
@@ -1750,6 +1793,45 @@ func (ns NullWorkflowStepStatus) Value() (driver.Value, error) {
17501793
 	return string(ns.WorkflowStepStatus), nil
17511794
 }
17521795
 
1796
+type ActionsOrgPolicy struct {
1797
+	OrgID                    int64
1798
+	ActionsEnabled           ActionsPolicyState
1799
+	RequirePrApproval        pgtype.Bool
1800
+	MaxRepoQueuedRuns        pgtype.Int4
1801
+	MaxRepoConcurrentJobs    pgtype.Int4
1802
+	MaxOwnerConcurrentJobs   pgtype.Int4
1803
+	ActorTriggerLimitPerHour pgtype.Int4
1804
+	UpdatedByUserID          pgtype.Int8
1805
+	CreatedAt                pgtype.Timestamptz
1806
+	UpdatedAt                pgtype.Timestamptz
1807
+}
1808
+
1809
+type ActionsRepoPolicy struct {
1810
+	RepoID                   int64
1811
+	ActionsEnabled           ActionsPolicyState
1812
+	RequirePrApproval        pgtype.Bool
1813
+	MaxRepoQueuedRuns        pgtype.Int4
1814
+	MaxRepoConcurrentJobs    pgtype.Int4
1815
+	MaxOwnerConcurrentJobs   pgtype.Int4
1816
+	ActorTriggerLimitPerHour pgtype.Int4
1817
+	UpdatedByUserID          pgtype.Int8
1818
+	CreatedAt                pgtype.Timestamptz
1819
+	UpdatedAt                pgtype.Timestamptz
1820
+}
1821
+
1822
+type ActionsSitePolicy struct {
1823
+	ID                       bool
1824
+	ActionsEnabled           bool
1825
+	RequirePrApproval        bool
1826
+	MaxRepoQueuedRuns        int32
1827
+	MaxRepoConcurrentJobs    int32
1828
+	MaxOwnerConcurrentJobs   int32
1829
+	ActorTriggerLimitPerHour int32
1830
+	UpdatedByUserID          pgtype.Int8
1831
+	CreatedAt                pgtype.Timestamptz
1832
+	UpdatedAt                pgtype.Timestamptz
1833
+}
1834
+
17531835
 type ActionsVariable struct {
17541836
 	ID              int64
17551837
 	RepoID          pgtype.Int8
@@ -2757,6 +2839,18 @@ type WorkflowRun struct {
27572839
 	TriggerEventID   string
27582840
 }
27592841
 
2842
+type WorkflowRunApproval struct {
2843
+	RunID            int64
2844
+	RequestedReason  string
2845
+	RequestedAt      pgtype.Timestamptz
2846
+	ApprovedByUserID pgtype.Int8
2847
+	ApprovedAt       pgtype.Timestamptz
2848
+	RejectedByUserID pgtype.Int8
2849
+	RejectedAt       pgtype.Timestamptz
2850
+	CreatedAt        pgtype.Timestamptz
2851
+	UpdatedAt        pgtype.Timestamptz
2852
+}
2853
+
27602854
 type WorkflowRunner struct {
27612855
 	ID                 int64
27622856
 	Name               string
internal/meta/sqlc/models.gomodified
@@ -12,6 +12,49 @@ import (
1212
 	"github.com/jackc/pgx/v5/pgtype"
1313
 )
1414
 
15
+type ActionsPolicyState string
16
+
17
+const (
18
+	ActionsPolicyStateInherit  ActionsPolicyState = "inherit"
19
+	ActionsPolicyStateEnabled  ActionsPolicyState = "enabled"
20
+	ActionsPolicyStateDisabled ActionsPolicyState = "disabled"
21
+)
22
+
23
+func (e *ActionsPolicyState) Scan(src interface{}) error {
24
+	switch s := src.(type) {
25
+	case []byte:
26
+		*e = ActionsPolicyState(s)
27
+	case string:
28
+		*e = ActionsPolicyState(s)
29
+	default:
30
+		return fmt.Errorf("unsupported scan type for ActionsPolicyState: %T", src)
31
+	}
32
+	return nil
33
+}
34
+
35
+type NullActionsPolicyState struct {
36
+	ActionsPolicyState ActionsPolicyState
37
+	Valid              bool // Valid is true if ActionsPolicyState is not NULL
38
+}
39
+
40
+// Scan implements the Scanner interface.
41
+func (ns *NullActionsPolicyState) Scan(value interface{}) error {
42
+	if value == nil {
43
+		ns.ActionsPolicyState, ns.Valid = "", false
44
+		return nil
45
+	}
46
+	ns.Valid = true
47
+	return ns.ActionsPolicyState.Scan(value)
48
+}
49
+
50
+// Value implements the driver Valuer interface.
51
+func (ns NullActionsPolicyState) Value() (driver.Value, error) {
52
+	if !ns.Valid {
53
+		return nil, nil
54
+	}
55
+	return string(ns.ActionsPolicyState), nil
56
+}
57
+
1558
 type BillingInvoiceStatus string
1659
 
1760
 const (
@@ -1750,6 +1793,45 @@ func (ns NullWorkflowStepStatus) Value() (driver.Value, error) {
17501793
 	return string(ns.WorkflowStepStatus), nil
17511794
 }
17521795
 
1796
+type ActionsOrgPolicy struct {
1797
+	OrgID                    int64
1798
+	ActionsEnabled           ActionsPolicyState
1799
+	RequirePrApproval        pgtype.Bool
1800
+	MaxRepoQueuedRuns        pgtype.Int4
1801
+	MaxRepoConcurrentJobs    pgtype.Int4
1802
+	MaxOwnerConcurrentJobs   pgtype.Int4
1803
+	ActorTriggerLimitPerHour pgtype.Int4
1804
+	UpdatedByUserID          pgtype.Int8
1805
+	CreatedAt                pgtype.Timestamptz
1806
+	UpdatedAt                pgtype.Timestamptz
1807
+}
1808
+
1809
+type ActionsRepoPolicy struct {
1810
+	RepoID                   int64
1811
+	ActionsEnabled           ActionsPolicyState
1812
+	RequirePrApproval        pgtype.Bool
1813
+	MaxRepoQueuedRuns        pgtype.Int4
1814
+	MaxRepoConcurrentJobs    pgtype.Int4
1815
+	MaxOwnerConcurrentJobs   pgtype.Int4
1816
+	ActorTriggerLimitPerHour pgtype.Int4
1817
+	UpdatedByUserID          pgtype.Int8
1818
+	CreatedAt                pgtype.Timestamptz
1819
+	UpdatedAt                pgtype.Timestamptz
1820
+}
1821
+
1822
+type ActionsSitePolicy struct {
1823
+	ID                       bool
1824
+	ActionsEnabled           bool
1825
+	RequirePrApproval        bool
1826
+	MaxRepoQueuedRuns        int32
1827
+	MaxRepoConcurrentJobs    int32
1828
+	MaxOwnerConcurrentJobs   int32
1829
+	ActorTriggerLimitPerHour int32
1830
+	UpdatedByUserID          pgtype.Int8
1831
+	CreatedAt                pgtype.Timestamptz
1832
+	UpdatedAt                pgtype.Timestamptz
1833
+}
1834
+
17531835
 type ActionsVariable struct {
17541836
 	ID              int64
17551837
 	RepoID          pgtype.Int8
@@ -2757,6 +2839,18 @@ type WorkflowRun struct {
27572839
 	TriggerEventID   string
27582840
 }
27592841
 
2842
+type WorkflowRunApproval struct {
2843
+	RunID            int64
2844
+	RequestedReason  string
2845
+	RequestedAt      pgtype.Timestamptz
2846
+	ApprovedByUserID pgtype.Int8
2847
+	ApprovedAt       pgtype.Timestamptz
2848
+	RejectedByUserID pgtype.Int8
2849
+	RejectedAt       pgtype.Timestamptz
2850
+	CreatedAt        pgtype.Timestamptz
2851
+	UpdatedAt        pgtype.Timestamptz
2852
+}
2853
+
27602854
 type WorkflowRunner struct {
27612855
 	ID                 int64
27622856
 	Name               string
internal/migrationsfs/migrations/0066_actions_policy_approvals.sqladded
@@ -0,0 +1,118 @@
1
+-- SPDX-License-Identifier: AGPL-3.0-or-later
2
+--
3
+-- S41j-3 Actions policy, abuse caps, and approval decisions.
4
+--
5
+-- The existing workflow_runs.need_approval / approved_by_user_id columns remain
6
+-- the fast path for runner dispatch. The policy tables below hold durable
7
+-- site/org/repo defaults, and workflow_run_approvals records the explicit
8
+-- approval/rejection decision without overloading run status fields.
9
+
10
+-- +goose Up
11
+
12
+CREATE TYPE actions_policy_state AS ENUM ('inherit', 'enabled', 'disabled');
13
+
14
+CREATE TABLE actions_site_policy (
15
+    id                                boolean PRIMARY KEY DEFAULT true CHECK (id),
16
+    actions_enabled                   boolean NOT NULL DEFAULT true,
17
+    require_pr_approval               boolean NOT NULL DEFAULT true,
18
+    max_repo_queued_runs              integer NOT NULL DEFAULT 50,
19
+    max_repo_concurrent_jobs          integer NOT NULL DEFAULT 20,
20
+    max_owner_concurrent_jobs         integer NOT NULL DEFAULT 100,
21
+    actor_trigger_limit_per_hour      integer NOT NULL DEFAULT 120,
22
+    updated_by_user_id                bigint REFERENCES users(id) ON DELETE SET NULL,
23
+    created_at                        timestamptz NOT NULL DEFAULT now(),
24
+    updated_at                        timestamptz NOT NULL DEFAULT now(),
25
+
26
+    CONSTRAINT actions_site_policy_caps_nonnegative CHECK (
27
+        max_repo_queued_runs >= 0
28
+        AND max_repo_concurrent_jobs >= 0
29
+        AND max_owner_concurrent_jobs >= 0
30
+        AND actor_trigger_limit_per_hour >= 0
31
+    )
32
+);
33
+
34
+INSERT INTO actions_site_policy (id) VALUES (true);
35
+
36
+CREATE TABLE actions_org_policies (
37
+    org_id                            bigint PRIMARY KEY REFERENCES orgs(id) ON DELETE CASCADE,
38
+    actions_enabled                   actions_policy_state NOT NULL DEFAULT 'inherit',
39
+    require_pr_approval               boolean,
40
+    max_repo_queued_runs              integer,
41
+    max_repo_concurrent_jobs          integer,
42
+    max_owner_concurrent_jobs         integer,
43
+    actor_trigger_limit_per_hour      integer,
44
+    updated_by_user_id                bigint REFERENCES users(id) ON DELETE SET NULL,
45
+    created_at                        timestamptz NOT NULL DEFAULT now(),
46
+    updated_at                        timestamptz NOT NULL DEFAULT now(),
47
+
48
+    CONSTRAINT actions_org_policies_caps_nonnegative CHECK (
49
+        (max_repo_queued_runs IS NULL OR max_repo_queued_runs >= 0)
50
+        AND (max_repo_concurrent_jobs IS NULL OR max_repo_concurrent_jobs >= 0)
51
+        AND (max_owner_concurrent_jobs IS NULL OR max_owner_concurrent_jobs >= 0)
52
+        AND (actor_trigger_limit_per_hour IS NULL OR actor_trigger_limit_per_hour >= 0)
53
+    )
54
+);
55
+
56
+CREATE TABLE actions_repo_policies (
57
+    repo_id                           bigint PRIMARY KEY REFERENCES repos(id) ON DELETE CASCADE,
58
+    actions_enabled                   actions_policy_state NOT NULL DEFAULT 'inherit',
59
+    require_pr_approval               boolean,
60
+    max_repo_queued_runs              integer,
61
+    max_repo_concurrent_jobs          integer,
62
+    max_owner_concurrent_jobs         integer,
63
+    actor_trigger_limit_per_hour      integer,
64
+    updated_by_user_id                bigint REFERENCES users(id) ON DELETE SET NULL,
65
+    created_at                        timestamptz NOT NULL DEFAULT now(),
66
+    updated_at                        timestamptz NOT NULL DEFAULT now(),
67
+
68
+    CONSTRAINT actions_repo_policies_caps_nonnegative CHECK (
69
+        (max_repo_queued_runs IS NULL OR max_repo_queued_runs >= 0)
70
+        AND (max_repo_concurrent_jobs IS NULL OR max_repo_concurrent_jobs >= 0)
71
+        AND (max_owner_concurrent_jobs IS NULL OR max_owner_concurrent_jobs >= 0)
72
+        AND (actor_trigger_limit_per_hour IS NULL OR actor_trigger_limit_per_hour >= 0)
73
+    )
74
+);
75
+
76
+CREATE TABLE workflow_run_approvals (
77
+    run_id              bigint PRIMARY KEY REFERENCES workflow_runs(id) ON DELETE CASCADE,
78
+    requested_reason    text NOT NULL DEFAULT '',
79
+    requested_at        timestamptz NOT NULL DEFAULT now(),
80
+    approved_by_user_id bigint REFERENCES users(id) ON DELETE SET NULL,
81
+    approved_at         timestamptz,
82
+    rejected_by_user_id bigint REFERENCES users(id) ON DELETE SET NULL,
83
+    rejected_at         timestamptz,
84
+    created_at          timestamptz NOT NULL DEFAULT now(),
85
+    updated_at          timestamptz NOT NULL DEFAULT now(),
86
+
87
+    CONSTRAINT workflow_run_approvals_one_terminal_decision CHECK (
88
+        NOT (approved_at IS NOT NULL AND rejected_at IS NOT NULL)
89
+    ),
90
+    CONSTRAINT workflow_run_approvals_approved_actor CHECK (
91
+        (approved_at IS NULL AND approved_by_user_id IS NULL)
92
+        OR (approved_at IS NOT NULL AND approved_by_user_id IS NOT NULL)
93
+    ),
94
+    CONSTRAINT workflow_run_approvals_rejected_actor CHECK (
95
+        (rejected_at IS NULL AND rejected_by_user_id IS NULL)
96
+        OR (rejected_at IS NOT NULL AND rejected_by_user_id IS NOT NULL)
97
+    )
98
+);
99
+
100
+CREATE INDEX workflow_run_approvals_pending_idx
101
+    ON workflow_run_approvals (requested_at)
102
+    WHERE approved_at IS NULL AND rejected_at IS NULL;
103
+
104
+CREATE TRIGGER set_updated_at BEFORE UPDATE ON actions_site_policy
105
+    FOR EACH ROW EXECUTE FUNCTION tg_set_updated_at();
106
+CREATE TRIGGER set_updated_at BEFORE UPDATE ON actions_org_policies
107
+    FOR EACH ROW EXECUTE FUNCTION tg_set_updated_at();
108
+CREATE TRIGGER set_updated_at BEFORE UPDATE ON actions_repo_policies
109
+    FOR EACH ROW EXECUTE FUNCTION tg_set_updated_at();
110
+CREATE TRIGGER set_updated_at BEFORE UPDATE ON workflow_run_approvals
111
+    FOR EACH ROW EXECUTE FUNCTION tg_set_updated_at();
112
+
113
+-- +goose Down
114
+DROP TABLE IF EXISTS workflow_run_approvals;
115
+DROP TABLE IF EXISTS actions_repo_policies;
116
+DROP TABLE IF EXISTS actions_org_policies;
117
+DROP TABLE IF EXISTS actions_site_policy;
118
+DROP TYPE IF EXISTS actions_policy_state;
internal/notif/sqlc/models.gomodified
@@ -12,6 +12,49 @@ import (
1212
 	"github.com/jackc/pgx/v5/pgtype"
1313
 )
1414
 
15
+type ActionsPolicyState string
16
+
17
+const (
18
+	ActionsPolicyStateInherit  ActionsPolicyState = "inherit"
19
+	ActionsPolicyStateEnabled  ActionsPolicyState = "enabled"
20
+	ActionsPolicyStateDisabled ActionsPolicyState = "disabled"
21
+)
22
+
23
+func (e *ActionsPolicyState) Scan(src interface{}) error {
24
+	switch s := src.(type) {
25
+	case []byte:
26
+		*e = ActionsPolicyState(s)
27
+	case string:
28
+		*e = ActionsPolicyState(s)
29
+	default:
30
+		return fmt.Errorf("unsupported scan type for ActionsPolicyState: %T", src)
31
+	}
32
+	return nil
33
+}
34
+
35
+type NullActionsPolicyState struct {
36
+	ActionsPolicyState ActionsPolicyState
37
+	Valid              bool // Valid is true if ActionsPolicyState is not NULL
38
+}
39
+
40
+// Scan implements the Scanner interface.
41
+func (ns *NullActionsPolicyState) Scan(value interface{}) error {
42
+	if value == nil {
43
+		ns.ActionsPolicyState, ns.Valid = "", false
44
+		return nil
45
+	}
46
+	ns.Valid = true
47
+	return ns.ActionsPolicyState.Scan(value)
48
+}
49
+
50
+// Value implements the driver Valuer interface.
51
+func (ns NullActionsPolicyState) Value() (driver.Value, error) {
52
+	if !ns.Valid {
53
+		return nil, nil
54
+	}
55
+	return string(ns.ActionsPolicyState), nil
56
+}
57
+
1558
 type BillingInvoiceStatus string
1659
 
1760
 const (
@@ -1750,6 +1793,45 @@ func (ns NullWorkflowStepStatus) Value() (driver.Value, error) {
17501793
 	return string(ns.WorkflowStepStatus), nil
17511794
 }
17521795
 
1796
+type ActionsOrgPolicy struct {
1797
+	OrgID                    int64
1798
+	ActionsEnabled           ActionsPolicyState
1799
+	RequirePrApproval        pgtype.Bool
1800
+	MaxRepoQueuedRuns        pgtype.Int4
1801
+	MaxRepoConcurrentJobs    pgtype.Int4
1802
+	MaxOwnerConcurrentJobs   pgtype.Int4
1803
+	ActorTriggerLimitPerHour pgtype.Int4
1804
+	UpdatedByUserID          pgtype.Int8
1805
+	CreatedAt                pgtype.Timestamptz
1806
+	UpdatedAt                pgtype.Timestamptz
1807
+}
1808
+
1809
+type ActionsRepoPolicy struct {
1810
+	RepoID                   int64
1811
+	ActionsEnabled           ActionsPolicyState
1812
+	RequirePrApproval        pgtype.Bool
1813
+	MaxRepoQueuedRuns        pgtype.Int4
1814
+	MaxRepoConcurrentJobs    pgtype.Int4
1815
+	MaxOwnerConcurrentJobs   pgtype.Int4
1816
+	ActorTriggerLimitPerHour pgtype.Int4
1817
+	UpdatedByUserID          pgtype.Int8
1818
+	CreatedAt                pgtype.Timestamptz
1819
+	UpdatedAt                pgtype.Timestamptz
1820
+}
1821
+
1822
+type ActionsSitePolicy struct {
1823
+	ID                       bool
1824
+	ActionsEnabled           bool
1825
+	RequirePrApproval        bool
1826
+	MaxRepoQueuedRuns        int32
1827
+	MaxRepoConcurrentJobs    int32
1828
+	MaxOwnerConcurrentJobs   int32
1829
+	ActorTriggerLimitPerHour int32
1830
+	UpdatedByUserID          pgtype.Int8
1831
+	CreatedAt                pgtype.Timestamptz
1832
+	UpdatedAt                pgtype.Timestamptz
1833
+}
1834
+
17531835
 type ActionsVariable struct {
17541836
 	ID              int64
17551837
 	RepoID          pgtype.Int8
@@ -2757,6 +2839,18 @@ type WorkflowRun struct {
27572839
 	TriggerEventID   string
27582840
 }
27592841
 
2842
+type WorkflowRunApproval struct {
2843
+	RunID            int64
2844
+	RequestedReason  string
2845
+	RequestedAt      pgtype.Timestamptz
2846
+	ApprovedByUserID pgtype.Int8
2847
+	ApprovedAt       pgtype.Timestamptz
2848
+	RejectedByUserID pgtype.Int8
2849
+	RejectedAt       pgtype.Timestamptz
2850
+	CreatedAt        pgtype.Timestamptz
2851
+	UpdatedAt        pgtype.Timestamptz
2852
+}
2853
+
27602854
 type WorkflowRunner struct {
27612855
 	ID                 int64
27622856
 	Name               string
internal/orgs/sqlc/models.gomodified
@@ -12,6 +12,49 @@ import (
1212
 	"github.com/jackc/pgx/v5/pgtype"
1313
 )
1414
 
15
+type ActionsPolicyState string
16
+
17
+const (
18
+	ActionsPolicyStateInherit  ActionsPolicyState = "inherit"
19
+	ActionsPolicyStateEnabled  ActionsPolicyState = "enabled"
20
+	ActionsPolicyStateDisabled ActionsPolicyState = "disabled"
21
+)
22
+
23
+func (e *ActionsPolicyState) Scan(src interface{}) error {
24
+	switch s := src.(type) {
25
+	case []byte:
26
+		*e = ActionsPolicyState(s)
27
+	case string:
28
+		*e = ActionsPolicyState(s)
29
+	default:
30
+		return fmt.Errorf("unsupported scan type for ActionsPolicyState: %T", src)
31
+	}
32
+	return nil
33
+}
34
+
35
+type NullActionsPolicyState struct {
36
+	ActionsPolicyState ActionsPolicyState
37
+	Valid              bool // Valid is true if ActionsPolicyState is not NULL
38
+}
39
+
40
+// Scan implements the Scanner interface.
41
+func (ns *NullActionsPolicyState) Scan(value interface{}) error {
42
+	if value == nil {
43
+		ns.ActionsPolicyState, ns.Valid = "", false
44
+		return nil
45
+	}
46
+	ns.Valid = true
47
+	return ns.ActionsPolicyState.Scan(value)
48
+}
49
+
50
+// Value implements the driver Valuer interface.
51
+func (ns NullActionsPolicyState) Value() (driver.Value, error) {
52
+	if !ns.Valid {
53
+		return nil, nil
54
+	}
55
+	return string(ns.ActionsPolicyState), nil
56
+}
57
+
1558
 type BillingInvoiceStatus string
1659
 
1760
 const (
@@ -1750,6 +1793,45 @@ func (ns NullWorkflowStepStatus) Value() (driver.Value, error) {
17501793
 	return string(ns.WorkflowStepStatus), nil
17511794
 }
17521795
 
1796
+type ActionsOrgPolicy struct {
1797
+	OrgID                    int64
1798
+	ActionsEnabled           ActionsPolicyState
1799
+	RequirePrApproval        pgtype.Bool
1800
+	MaxRepoQueuedRuns        pgtype.Int4
1801
+	MaxRepoConcurrentJobs    pgtype.Int4
1802
+	MaxOwnerConcurrentJobs   pgtype.Int4
1803
+	ActorTriggerLimitPerHour pgtype.Int4
1804
+	UpdatedByUserID          pgtype.Int8
1805
+	CreatedAt                pgtype.Timestamptz
1806
+	UpdatedAt                pgtype.Timestamptz
1807
+}
1808
+
1809
+type ActionsRepoPolicy struct {
1810
+	RepoID                   int64
1811
+	ActionsEnabled           ActionsPolicyState
1812
+	RequirePrApproval        pgtype.Bool
1813
+	MaxRepoQueuedRuns        pgtype.Int4
1814
+	MaxRepoConcurrentJobs    pgtype.Int4
1815
+	MaxOwnerConcurrentJobs   pgtype.Int4
1816
+	ActorTriggerLimitPerHour pgtype.Int4
1817
+	UpdatedByUserID          pgtype.Int8
1818
+	CreatedAt                pgtype.Timestamptz
1819
+	UpdatedAt                pgtype.Timestamptz
1820
+}
1821
+
1822
+type ActionsSitePolicy struct {
1823
+	ID                       bool
1824
+	ActionsEnabled           bool
1825
+	RequirePrApproval        bool
1826
+	MaxRepoQueuedRuns        int32
1827
+	MaxRepoConcurrentJobs    int32
1828
+	MaxOwnerConcurrentJobs   int32
1829
+	ActorTriggerLimitPerHour int32
1830
+	UpdatedByUserID          pgtype.Int8
1831
+	CreatedAt                pgtype.Timestamptz
1832
+	UpdatedAt                pgtype.Timestamptz
1833
+}
1834
+
17531835
 type ActionsVariable struct {
17541836
 	ID              int64
17551837
 	RepoID          pgtype.Int8
@@ -2757,6 +2839,18 @@ type WorkflowRun struct {
27572839
 	TriggerEventID   string
27582840
 }
27592841
 
2842
+type WorkflowRunApproval struct {
2843
+	RunID            int64
2844
+	RequestedReason  string
2845
+	RequestedAt      pgtype.Timestamptz
2846
+	ApprovedByUserID pgtype.Int8
2847
+	ApprovedAt       pgtype.Timestamptz
2848
+	RejectedByUserID pgtype.Int8
2849
+	RejectedAt       pgtype.Timestamptz
2850
+	CreatedAt        pgtype.Timestamptz
2851
+	UpdatedAt        pgtype.Timestamptz
2852
+}
2853
+
27602854
 type WorkflowRunner struct {
27612855
 	ID                 int64
27622856
 	Name               string
internal/pulls/sqlc/models.gomodified
@@ -12,6 +12,49 @@ import (
1212
 	"github.com/jackc/pgx/v5/pgtype"
1313
 )
1414
 
15
+type ActionsPolicyState string
16
+
17
+const (
18
+	ActionsPolicyStateInherit  ActionsPolicyState = "inherit"
19
+	ActionsPolicyStateEnabled  ActionsPolicyState = "enabled"
20
+	ActionsPolicyStateDisabled ActionsPolicyState = "disabled"
21
+)
22
+
23
+func (e *ActionsPolicyState) Scan(src interface{}) error {
24
+	switch s := src.(type) {
25
+	case []byte:
26
+		*e = ActionsPolicyState(s)
27
+	case string:
28
+		*e = ActionsPolicyState(s)
29
+	default:
30
+		return fmt.Errorf("unsupported scan type for ActionsPolicyState: %T", src)
31
+	}
32
+	return nil
33
+}
34
+
35
+type NullActionsPolicyState struct {
36
+	ActionsPolicyState ActionsPolicyState
37
+	Valid              bool // Valid is true if ActionsPolicyState is not NULL
38
+}
39
+
40
+// Scan implements the Scanner interface.
41
+func (ns *NullActionsPolicyState) Scan(value interface{}) error {
42
+	if value == nil {
43
+		ns.ActionsPolicyState, ns.Valid = "", false
44
+		return nil
45
+	}
46
+	ns.Valid = true
47
+	return ns.ActionsPolicyState.Scan(value)
48
+}
49
+
50
+// Value implements the driver Valuer interface.
51
+func (ns NullActionsPolicyState) Value() (driver.Value, error) {
52
+	if !ns.Valid {
53
+		return nil, nil
54
+	}
55
+	return string(ns.ActionsPolicyState), nil
56
+}
57
+
1558
 type BillingInvoiceStatus string
1659
 
1760
 const (
@@ -1750,6 +1793,45 @@ func (ns NullWorkflowStepStatus) Value() (driver.Value, error) {
17501793
 	return string(ns.WorkflowStepStatus), nil
17511794
 }
17521795
 
1796
+type ActionsOrgPolicy struct {
1797
+	OrgID                    int64
1798
+	ActionsEnabled           ActionsPolicyState
1799
+	RequirePrApproval        pgtype.Bool
1800
+	MaxRepoQueuedRuns        pgtype.Int4
1801
+	MaxRepoConcurrentJobs    pgtype.Int4
1802
+	MaxOwnerConcurrentJobs   pgtype.Int4
1803
+	ActorTriggerLimitPerHour pgtype.Int4
1804
+	UpdatedByUserID          pgtype.Int8
1805
+	CreatedAt                pgtype.Timestamptz
1806
+	UpdatedAt                pgtype.Timestamptz
1807
+}
1808
+
1809
+type ActionsRepoPolicy struct {
1810
+	RepoID                   int64
1811
+	ActionsEnabled           ActionsPolicyState
1812
+	RequirePrApproval        pgtype.Bool
1813
+	MaxRepoQueuedRuns        pgtype.Int4
1814
+	MaxRepoConcurrentJobs    pgtype.Int4
1815
+	MaxOwnerConcurrentJobs   pgtype.Int4
1816
+	ActorTriggerLimitPerHour pgtype.Int4
1817
+	UpdatedByUserID          pgtype.Int8
1818
+	CreatedAt                pgtype.Timestamptz
1819
+	UpdatedAt                pgtype.Timestamptz
1820
+}
1821
+
1822
+type ActionsSitePolicy struct {
1823
+	ID                       bool
1824
+	ActionsEnabled           bool
1825
+	RequirePrApproval        bool
1826
+	MaxRepoQueuedRuns        int32
1827
+	MaxRepoConcurrentJobs    int32
1828
+	MaxOwnerConcurrentJobs   int32
1829
+	ActorTriggerLimitPerHour int32
1830
+	UpdatedByUserID          pgtype.Int8
1831
+	CreatedAt                pgtype.Timestamptz
1832
+	UpdatedAt                pgtype.Timestamptz
1833
+}
1834
+
17531835
 type ActionsVariable struct {
17541836
 	ID              int64
17551837
 	RepoID          pgtype.Int8
@@ -2757,6 +2839,18 @@ type WorkflowRun struct {
27572839
 	TriggerEventID   string
27582840
 }
27592841
 
2842
+type WorkflowRunApproval struct {
2843
+	RunID            int64
2844
+	RequestedReason  string
2845
+	RequestedAt      pgtype.Timestamptz
2846
+	ApprovedByUserID pgtype.Int8
2847
+	ApprovedAt       pgtype.Timestamptz
2848
+	RejectedByUserID pgtype.Int8
2849
+	RejectedAt       pgtype.Timestamptz
2850
+	CreatedAt        pgtype.Timestamptz
2851
+	UpdatedAt        pgtype.Timestamptz
2852
+}
2853
+
27602854
 type WorkflowRunner struct {
27612855
 	ID                 int64
27622856
 	Name               string
internal/ratelimit/sqlc/models.gomodified
@@ -12,6 +12,49 @@ import (
1212
 	"github.com/jackc/pgx/v5/pgtype"
1313
 )
1414
 
15
+type ActionsPolicyState string
16
+
17
+const (
18
+	ActionsPolicyStateInherit  ActionsPolicyState = "inherit"
19
+	ActionsPolicyStateEnabled  ActionsPolicyState = "enabled"
20
+	ActionsPolicyStateDisabled ActionsPolicyState = "disabled"
21
+)
22
+
23
+func (e *ActionsPolicyState) Scan(src interface{}) error {
24
+	switch s := src.(type) {
25
+	case []byte:
26
+		*e = ActionsPolicyState(s)
27
+	case string:
28
+		*e = ActionsPolicyState(s)
29
+	default:
30
+		return fmt.Errorf("unsupported scan type for ActionsPolicyState: %T", src)
31
+	}
32
+	return nil
33
+}
34
+
35
+type NullActionsPolicyState struct {
36
+	ActionsPolicyState ActionsPolicyState
37
+	Valid              bool // Valid is true if ActionsPolicyState is not NULL
38
+}
39
+
40
+// Scan implements the Scanner interface.
41
+func (ns *NullActionsPolicyState) Scan(value interface{}) error {
42
+	if value == nil {
43
+		ns.ActionsPolicyState, ns.Valid = "", false
44
+		return nil
45
+	}
46
+	ns.Valid = true
47
+	return ns.ActionsPolicyState.Scan(value)
48
+}
49
+
50
+// Value implements the driver Valuer interface.
51
+func (ns NullActionsPolicyState) Value() (driver.Value, error) {
52
+	if !ns.Valid {
53
+		return nil, nil
54
+	}
55
+	return string(ns.ActionsPolicyState), nil
56
+}
57
+
1558
 type BillingInvoiceStatus string
1659
 
1760
 const (
@@ -1750,6 +1793,45 @@ func (ns NullWorkflowStepStatus) Value() (driver.Value, error) {
17501793
 	return string(ns.WorkflowStepStatus), nil
17511794
 }
17521795
 
1796
+type ActionsOrgPolicy struct {
1797
+	OrgID                    int64
1798
+	ActionsEnabled           ActionsPolicyState
1799
+	RequirePrApproval        pgtype.Bool
1800
+	MaxRepoQueuedRuns        pgtype.Int4
1801
+	MaxRepoConcurrentJobs    pgtype.Int4
1802
+	MaxOwnerConcurrentJobs   pgtype.Int4
1803
+	ActorTriggerLimitPerHour pgtype.Int4
1804
+	UpdatedByUserID          pgtype.Int8
1805
+	CreatedAt                pgtype.Timestamptz
1806
+	UpdatedAt                pgtype.Timestamptz
1807
+}
1808
+
1809
+type ActionsRepoPolicy struct {
1810
+	RepoID                   int64
1811
+	ActionsEnabled           ActionsPolicyState
1812
+	RequirePrApproval        pgtype.Bool
1813
+	MaxRepoQueuedRuns        pgtype.Int4
1814
+	MaxRepoConcurrentJobs    pgtype.Int4
1815
+	MaxOwnerConcurrentJobs   pgtype.Int4
1816
+	ActorTriggerLimitPerHour pgtype.Int4
1817
+	UpdatedByUserID          pgtype.Int8
1818
+	CreatedAt                pgtype.Timestamptz
1819
+	UpdatedAt                pgtype.Timestamptz
1820
+}
1821
+
1822
+type ActionsSitePolicy struct {
1823
+	ID                       bool
1824
+	ActionsEnabled           bool
1825
+	RequirePrApproval        bool
1826
+	MaxRepoQueuedRuns        int32
1827
+	MaxRepoConcurrentJobs    int32
1828
+	MaxOwnerConcurrentJobs   int32
1829
+	ActorTriggerLimitPerHour int32
1830
+	UpdatedByUserID          pgtype.Int8
1831
+	CreatedAt                pgtype.Timestamptz
1832
+	UpdatedAt                pgtype.Timestamptz
1833
+}
1834
+
17531835
 type ActionsVariable struct {
17541836
 	ID              int64
17551837
 	RepoID          pgtype.Int8
@@ -2757,6 +2839,18 @@ type WorkflowRun struct {
27572839
 	TriggerEventID   string
27582840
 }
27592841
 
2842
+type WorkflowRunApproval struct {
2843
+	RunID            int64
2844
+	RequestedReason  string
2845
+	RequestedAt      pgtype.Timestamptz
2846
+	ApprovedByUserID pgtype.Int8
2847
+	ApprovedAt       pgtype.Timestamptz
2848
+	RejectedByUserID pgtype.Int8
2849
+	RejectedAt       pgtype.Timestamptz
2850
+	CreatedAt        pgtype.Timestamptz
2851
+	UpdatedAt        pgtype.Timestamptz
2852
+}
2853
+
27602854
 type WorkflowRunner struct {
27612855
 	ID                 int64
27622856
 	Name               string
internal/repos/sqlc/models.gomodified
@@ -12,6 +12,49 @@ import (
1212
 	"github.com/jackc/pgx/v5/pgtype"
1313
 )
1414
 
15
+type ActionsPolicyState string
16
+
17
+const (
18
+	ActionsPolicyStateInherit  ActionsPolicyState = "inherit"
19
+	ActionsPolicyStateEnabled  ActionsPolicyState = "enabled"
20
+	ActionsPolicyStateDisabled ActionsPolicyState = "disabled"
21
+)
22
+
23
+func (e *ActionsPolicyState) Scan(src interface{}) error {
24
+	switch s := src.(type) {
25
+	case []byte:
26
+		*e = ActionsPolicyState(s)
27
+	case string:
28
+		*e = ActionsPolicyState(s)
29
+	default:
30
+		return fmt.Errorf("unsupported scan type for ActionsPolicyState: %T", src)
31
+	}
32
+	return nil
33
+}
34
+
35
+type NullActionsPolicyState struct {
36
+	ActionsPolicyState ActionsPolicyState
37
+	Valid              bool // Valid is true if ActionsPolicyState is not NULL
38
+}
39
+
40
+// Scan implements the Scanner interface.
41
+func (ns *NullActionsPolicyState) Scan(value interface{}) error {
42
+	if value == nil {
43
+		ns.ActionsPolicyState, ns.Valid = "", false
44
+		return nil
45
+	}
46
+	ns.Valid = true
47
+	return ns.ActionsPolicyState.Scan(value)
48
+}
49
+
50
+// Value implements the driver Valuer interface.
51
+func (ns NullActionsPolicyState) Value() (driver.Value, error) {
52
+	if !ns.Valid {
53
+		return nil, nil
54
+	}
55
+	return string(ns.ActionsPolicyState), nil
56
+}
57
+
1558
 type BillingInvoiceStatus string
1659
 
1760
 const (
@@ -1750,6 +1793,45 @@ func (ns NullWorkflowStepStatus) Value() (driver.Value, error) {
17501793
 	return string(ns.WorkflowStepStatus), nil
17511794
 }
17521795
 
1796
+type ActionsOrgPolicy struct {
1797
+	OrgID                    int64
1798
+	ActionsEnabled           ActionsPolicyState
1799
+	RequirePrApproval        pgtype.Bool
1800
+	MaxRepoQueuedRuns        pgtype.Int4
1801
+	MaxRepoConcurrentJobs    pgtype.Int4
1802
+	MaxOwnerConcurrentJobs   pgtype.Int4
1803
+	ActorTriggerLimitPerHour pgtype.Int4
1804
+	UpdatedByUserID          pgtype.Int8
1805
+	CreatedAt                pgtype.Timestamptz
1806
+	UpdatedAt                pgtype.Timestamptz
1807
+}
1808
+
1809
+type ActionsRepoPolicy struct {
1810
+	RepoID                   int64
1811
+	ActionsEnabled           ActionsPolicyState
1812
+	RequirePrApproval        pgtype.Bool
1813
+	MaxRepoQueuedRuns        pgtype.Int4
1814
+	MaxRepoConcurrentJobs    pgtype.Int4
1815
+	MaxOwnerConcurrentJobs   pgtype.Int4
1816
+	ActorTriggerLimitPerHour pgtype.Int4
1817
+	UpdatedByUserID          pgtype.Int8
1818
+	CreatedAt                pgtype.Timestamptz
1819
+	UpdatedAt                pgtype.Timestamptz
1820
+}
1821
+
1822
+type ActionsSitePolicy struct {
1823
+	ID                       bool
1824
+	ActionsEnabled           bool
1825
+	RequirePrApproval        bool
1826
+	MaxRepoQueuedRuns        int32
1827
+	MaxRepoConcurrentJobs    int32
1828
+	MaxOwnerConcurrentJobs   int32
1829
+	ActorTriggerLimitPerHour int32
1830
+	UpdatedByUserID          pgtype.Int8
1831
+	CreatedAt                pgtype.Timestamptz
1832
+	UpdatedAt                pgtype.Timestamptz
1833
+}
1834
+
17531835
 type ActionsVariable struct {
17541836
 	ID              int64
17551837
 	RepoID          pgtype.Int8
@@ -2757,6 +2839,18 @@ type WorkflowRun struct {
27572839
 	TriggerEventID   string
27582840
 }
27592841
 
2842
+type WorkflowRunApproval struct {
2843
+	RunID            int64
2844
+	RequestedReason  string
2845
+	RequestedAt      pgtype.Timestamptz
2846
+	ApprovedByUserID pgtype.Int8
2847
+	ApprovedAt       pgtype.Timestamptz
2848
+	RejectedByUserID pgtype.Int8
2849
+	RejectedAt       pgtype.Timestamptz
2850
+	CreatedAt        pgtype.Timestamptz
2851
+	UpdatedAt        pgtype.Timestamptz
2852
+}
2853
+
27602854
 type WorkflowRunner struct {
27612855
 	ID                 int64
27622856
 	Name               string
internal/social/sqlc/models.gomodified
@@ -12,6 +12,49 @@ import (
1212
 	"github.com/jackc/pgx/v5/pgtype"
1313
 )
1414
 
15
+type ActionsPolicyState string
16
+
17
+const (
18
+	ActionsPolicyStateInherit  ActionsPolicyState = "inherit"
19
+	ActionsPolicyStateEnabled  ActionsPolicyState = "enabled"
20
+	ActionsPolicyStateDisabled ActionsPolicyState = "disabled"
21
+)
22
+
23
+func (e *ActionsPolicyState) Scan(src interface{}) error {
24
+	switch s := src.(type) {
25
+	case []byte:
26
+		*e = ActionsPolicyState(s)
27
+	case string:
28
+		*e = ActionsPolicyState(s)
29
+	default:
30
+		return fmt.Errorf("unsupported scan type for ActionsPolicyState: %T", src)
31
+	}
32
+	return nil
33
+}
34
+
35
+type NullActionsPolicyState struct {
36
+	ActionsPolicyState ActionsPolicyState
37
+	Valid              bool // Valid is true if ActionsPolicyState is not NULL
38
+}
39
+
40
+// Scan implements the Scanner interface.
41
+func (ns *NullActionsPolicyState) Scan(value interface{}) error {
42
+	if value == nil {
43
+		ns.ActionsPolicyState, ns.Valid = "", false
44
+		return nil
45
+	}
46
+	ns.Valid = true
47
+	return ns.ActionsPolicyState.Scan(value)
48
+}
49
+
50
+// Value implements the driver Valuer interface.
51
+func (ns NullActionsPolicyState) Value() (driver.Value, error) {
52
+	if !ns.Valid {
53
+		return nil, nil
54
+	}
55
+	return string(ns.ActionsPolicyState), nil
56
+}
57
+
1558
 type BillingInvoiceStatus string
1659
 
1760
 const (
@@ -1750,6 +1793,45 @@ func (ns NullWorkflowStepStatus) Value() (driver.Value, error) {
17501793
 	return string(ns.WorkflowStepStatus), nil
17511794
 }
17521795
 
1796
+type ActionsOrgPolicy struct {
1797
+	OrgID                    int64
1798
+	ActionsEnabled           ActionsPolicyState
1799
+	RequirePrApproval        pgtype.Bool
1800
+	MaxRepoQueuedRuns        pgtype.Int4
1801
+	MaxRepoConcurrentJobs    pgtype.Int4
1802
+	MaxOwnerConcurrentJobs   pgtype.Int4
1803
+	ActorTriggerLimitPerHour pgtype.Int4
1804
+	UpdatedByUserID          pgtype.Int8
1805
+	CreatedAt                pgtype.Timestamptz
1806
+	UpdatedAt                pgtype.Timestamptz
1807
+}
1808
+
1809
+type ActionsRepoPolicy struct {
1810
+	RepoID                   int64
1811
+	ActionsEnabled           ActionsPolicyState
1812
+	RequirePrApproval        pgtype.Bool
1813
+	MaxRepoQueuedRuns        pgtype.Int4
1814
+	MaxRepoConcurrentJobs    pgtype.Int4
1815
+	MaxOwnerConcurrentJobs   pgtype.Int4
1816
+	ActorTriggerLimitPerHour pgtype.Int4
1817
+	UpdatedByUserID          pgtype.Int8
1818
+	CreatedAt                pgtype.Timestamptz
1819
+	UpdatedAt                pgtype.Timestamptz
1820
+}
1821
+
1822
+type ActionsSitePolicy struct {
1823
+	ID                       bool
1824
+	ActionsEnabled           bool
1825
+	RequirePrApproval        bool
1826
+	MaxRepoQueuedRuns        int32
1827
+	MaxRepoConcurrentJobs    int32
1828
+	MaxOwnerConcurrentJobs   int32
1829
+	ActorTriggerLimitPerHour int32
1830
+	UpdatedByUserID          pgtype.Int8
1831
+	CreatedAt                pgtype.Timestamptz
1832
+	UpdatedAt                pgtype.Timestamptz
1833
+}
1834
+
17531835
 type ActionsVariable struct {
17541836
 	ID              int64
17551837
 	RepoID          pgtype.Int8
@@ -2757,6 +2839,18 @@ type WorkflowRun struct {
27572839
 	TriggerEventID   string
27582840
 }
27592841
 
2842
+type WorkflowRunApproval struct {
2843
+	RunID            int64
2844
+	RequestedReason  string
2845
+	RequestedAt      pgtype.Timestamptz
2846
+	ApprovedByUserID pgtype.Int8
2847
+	ApprovedAt       pgtype.Timestamptz
2848
+	RejectedByUserID pgtype.Int8
2849
+	RejectedAt       pgtype.Timestamptz
2850
+	CreatedAt        pgtype.Timestamptz
2851
+	UpdatedAt        pgtype.Timestamptz
2852
+}
2853
+
27602854
 type WorkflowRunner struct {
27612855
 	ID                 int64
27622856
 	Name               string
internal/users/sqlc/models.gomodified
@@ -12,6 +12,49 @@ import (
1212
 	"github.com/jackc/pgx/v5/pgtype"
1313
 )
1414
 
15
+type ActionsPolicyState string
16
+
17
+const (
18
+	ActionsPolicyStateInherit  ActionsPolicyState = "inherit"
19
+	ActionsPolicyStateEnabled  ActionsPolicyState = "enabled"
20
+	ActionsPolicyStateDisabled ActionsPolicyState = "disabled"
21
+)
22
+
23
+func (e *ActionsPolicyState) Scan(src interface{}) error {
24
+	switch s := src.(type) {
25
+	case []byte:
26
+		*e = ActionsPolicyState(s)
27
+	case string:
28
+		*e = ActionsPolicyState(s)
29
+	default:
30
+		return fmt.Errorf("unsupported scan type for ActionsPolicyState: %T", src)
31
+	}
32
+	return nil
33
+}
34
+
35
+type NullActionsPolicyState struct {
36
+	ActionsPolicyState ActionsPolicyState
37
+	Valid              bool // Valid is true if ActionsPolicyState is not NULL
38
+}
39
+
40
+// Scan implements the Scanner interface.
41
+func (ns *NullActionsPolicyState) Scan(value interface{}) error {
42
+	if value == nil {
43
+		ns.ActionsPolicyState, ns.Valid = "", false
44
+		return nil
45
+	}
46
+	ns.Valid = true
47
+	return ns.ActionsPolicyState.Scan(value)
48
+}
49
+
50
+// Value implements the driver Valuer interface.
51
+func (ns NullActionsPolicyState) Value() (driver.Value, error) {
52
+	if !ns.Valid {
53
+		return nil, nil
54
+	}
55
+	return string(ns.ActionsPolicyState), nil
56
+}
57
+
1558
 type BillingInvoiceStatus string
1659
 
1760
 const (
@@ -1750,6 +1793,45 @@ func (ns NullWorkflowStepStatus) Value() (driver.Value, error) {
17501793
 	return string(ns.WorkflowStepStatus), nil
17511794
 }
17521795
 
1796
+type ActionsOrgPolicy struct {
1797
+	OrgID                    int64
1798
+	ActionsEnabled           ActionsPolicyState
1799
+	RequirePrApproval        pgtype.Bool
1800
+	MaxRepoQueuedRuns        pgtype.Int4
1801
+	MaxRepoConcurrentJobs    pgtype.Int4
1802
+	MaxOwnerConcurrentJobs   pgtype.Int4
1803
+	ActorTriggerLimitPerHour pgtype.Int4
1804
+	UpdatedByUserID          pgtype.Int8
1805
+	CreatedAt                pgtype.Timestamptz
1806
+	UpdatedAt                pgtype.Timestamptz
1807
+}
1808
+
1809
+type ActionsRepoPolicy struct {
1810
+	RepoID                   int64
1811
+	ActionsEnabled           ActionsPolicyState
1812
+	RequirePrApproval        pgtype.Bool
1813
+	MaxRepoQueuedRuns        pgtype.Int4
1814
+	MaxRepoConcurrentJobs    pgtype.Int4
1815
+	MaxOwnerConcurrentJobs   pgtype.Int4
1816
+	ActorTriggerLimitPerHour pgtype.Int4
1817
+	UpdatedByUserID          pgtype.Int8
1818
+	CreatedAt                pgtype.Timestamptz
1819
+	UpdatedAt                pgtype.Timestamptz
1820
+}
1821
+
1822
+type ActionsSitePolicy struct {
1823
+	ID                       bool
1824
+	ActionsEnabled           bool
1825
+	RequirePrApproval        bool
1826
+	MaxRepoQueuedRuns        int32
1827
+	MaxRepoConcurrentJobs    int32
1828
+	MaxOwnerConcurrentJobs   int32
1829
+	ActorTriggerLimitPerHour int32
1830
+	UpdatedByUserID          pgtype.Int8
1831
+	CreatedAt                pgtype.Timestamptz
1832
+	UpdatedAt                pgtype.Timestamptz
1833
+}
1834
+
17531835
 type ActionsVariable struct {
17541836
 	ID              int64
17551837
 	RepoID          pgtype.Int8
@@ -2757,6 +2839,18 @@ type WorkflowRun struct {
27572839
 	TriggerEventID   string
27582840
 }
27592841
 
2842
+type WorkflowRunApproval struct {
2843
+	RunID            int64
2844
+	RequestedReason  string
2845
+	RequestedAt      pgtype.Timestamptz
2846
+	ApprovedByUserID pgtype.Int8
2847
+	ApprovedAt       pgtype.Timestamptz
2848
+	RejectedByUserID pgtype.Int8
2849
+	RejectedAt       pgtype.Timestamptz
2850
+	CreatedAt        pgtype.Timestamptz
2851
+	UpdatedAt        pgtype.Timestamptz
2852
+}
2853
+
27602854
 type WorkflowRunner struct {
27612855
 	ID                 int64
27622856
 	Name               string
internal/webhook/sqlc/models.gomodified
@@ -12,6 +12,49 @@ import (
1212
 	"github.com/jackc/pgx/v5/pgtype"
1313
 )
1414
 
15
+type ActionsPolicyState string
16
+
17
+const (
18
+	ActionsPolicyStateInherit  ActionsPolicyState = "inherit"
19
+	ActionsPolicyStateEnabled  ActionsPolicyState = "enabled"
20
+	ActionsPolicyStateDisabled ActionsPolicyState = "disabled"
21
+)
22
+
23
+func (e *ActionsPolicyState) Scan(src interface{}) error {
24
+	switch s := src.(type) {
25
+	case []byte:
26
+		*e = ActionsPolicyState(s)
27
+	case string:
28
+		*e = ActionsPolicyState(s)
29
+	default:
30
+		return fmt.Errorf("unsupported scan type for ActionsPolicyState: %T", src)
31
+	}
32
+	return nil
33
+}
34
+
35
+type NullActionsPolicyState struct {
36
+	ActionsPolicyState ActionsPolicyState
37
+	Valid              bool // Valid is true if ActionsPolicyState is not NULL
38
+}
39
+
40
+// Scan implements the Scanner interface.
41
+func (ns *NullActionsPolicyState) Scan(value interface{}) error {
42
+	if value == nil {
43
+		ns.ActionsPolicyState, ns.Valid = "", false
44
+		return nil
45
+	}
46
+	ns.Valid = true
47
+	return ns.ActionsPolicyState.Scan(value)
48
+}
49
+
50
+// Value implements the driver Valuer interface.
51
+func (ns NullActionsPolicyState) Value() (driver.Value, error) {
52
+	if !ns.Valid {
53
+		return nil, nil
54
+	}
55
+	return string(ns.ActionsPolicyState), nil
56
+}
57
+
1558
 type BillingInvoiceStatus string
1659
 
1760
 const (
@@ -1750,6 +1793,45 @@ func (ns NullWorkflowStepStatus) Value() (driver.Value, error) {
17501793
 	return string(ns.WorkflowStepStatus), nil
17511794
 }
17521795
 
1796
+type ActionsOrgPolicy struct {
1797
+	OrgID                    int64
1798
+	ActionsEnabled           ActionsPolicyState
1799
+	RequirePrApproval        pgtype.Bool
1800
+	MaxRepoQueuedRuns        pgtype.Int4
1801
+	MaxRepoConcurrentJobs    pgtype.Int4
1802
+	MaxOwnerConcurrentJobs   pgtype.Int4
1803
+	ActorTriggerLimitPerHour pgtype.Int4
1804
+	UpdatedByUserID          pgtype.Int8
1805
+	CreatedAt                pgtype.Timestamptz
1806
+	UpdatedAt                pgtype.Timestamptz
1807
+}
1808
+
1809
+type ActionsRepoPolicy struct {
1810
+	RepoID                   int64
1811
+	ActionsEnabled           ActionsPolicyState
1812
+	RequirePrApproval        pgtype.Bool
1813
+	MaxRepoQueuedRuns        pgtype.Int4
1814
+	MaxRepoConcurrentJobs    pgtype.Int4
1815
+	MaxOwnerConcurrentJobs   pgtype.Int4
1816
+	ActorTriggerLimitPerHour pgtype.Int4
1817
+	UpdatedByUserID          pgtype.Int8
1818
+	CreatedAt                pgtype.Timestamptz
1819
+	UpdatedAt                pgtype.Timestamptz
1820
+}
1821
+
1822
+type ActionsSitePolicy struct {
1823
+	ID                       bool
1824
+	ActionsEnabled           bool
1825
+	RequirePrApproval        bool
1826
+	MaxRepoQueuedRuns        int32
1827
+	MaxRepoConcurrentJobs    int32
1828
+	MaxOwnerConcurrentJobs   int32
1829
+	ActorTriggerLimitPerHour int32
1830
+	UpdatedByUserID          pgtype.Int8
1831
+	CreatedAt                pgtype.Timestamptz
1832
+	UpdatedAt                pgtype.Timestamptz
1833
+}
1834
+
17531835
 type ActionsVariable struct {
17541836
 	ID              int64
17551837
 	RepoID          pgtype.Int8
@@ -2757,6 +2839,18 @@ type WorkflowRun struct {
27572839
 	TriggerEventID   string
27582840
 }
27592841
 
2842
+type WorkflowRunApproval struct {
2843
+	RunID            int64
2844
+	RequestedReason  string
2845
+	RequestedAt      pgtype.Timestamptz
2846
+	ApprovedByUserID pgtype.Int8
2847
+	ApprovedAt       pgtype.Timestamptz
2848
+	RejectedByUserID pgtype.Int8
2849
+	RejectedAt       pgtype.Timestamptz
2850
+	CreatedAt        pgtype.Timestamptz
2851
+	UpdatedAt        pgtype.Timestamptz
2852
+}
2853
+
27602854
 type WorkflowRunner struct {
27612855
 	ID                 int64
27622856
 	Name               string
internal/worker/sqlc/models.gomodified
@@ -12,6 +12,49 @@ import (
1212
 	"github.com/jackc/pgx/v5/pgtype"
1313
 )
1414
 
15
+type ActionsPolicyState string
16
+
17
+const (
18
+	ActionsPolicyStateInherit  ActionsPolicyState = "inherit"
19
+	ActionsPolicyStateEnabled  ActionsPolicyState = "enabled"
20
+	ActionsPolicyStateDisabled ActionsPolicyState = "disabled"
21
+)
22
+
23
+func (e *ActionsPolicyState) Scan(src interface{}) error {
24
+	switch s := src.(type) {
25
+	case []byte:
26
+		*e = ActionsPolicyState(s)
27
+	case string:
28
+		*e = ActionsPolicyState(s)
29
+	default:
30
+		return fmt.Errorf("unsupported scan type for ActionsPolicyState: %T", src)
31
+	}
32
+	return nil
33
+}
34
+
35
+type NullActionsPolicyState struct {
36
+	ActionsPolicyState ActionsPolicyState
37
+	Valid              bool // Valid is true if ActionsPolicyState is not NULL
38
+}
39
+
40
+// Scan implements the Scanner interface.
41
+func (ns *NullActionsPolicyState) Scan(value interface{}) error {
42
+	if value == nil {
43
+		ns.ActionsPolicyState, ns.Valid = "", false
44
+		return nil
45
+	}
46
+	ns.Valid = true
47
+	return ns.ActionsPolicyState.Scan(value)
48
+}
49
+
50
+// Value implements the driver Valuer interface.
51
+func (ns NullActionsPolicyState) Value() (driver.Value, error) {
52
+	if !ns.Valid {
53
+		return nil, nil
54
+	}
55
+	return string(ns.ActionsPolicyState), nil
56
+}
57
+
1558
 type BillingInvoiceStatus string
1659
 
1760
 const (
@@ -1750,6 +1793,45 @@ func (ns NullWorkflowStepStatus) Value() (driver.Value, error) {
17501793
 	return string(ns.WorkflowStepStatus), nil
17511794
 }
17521795
 
1796
+type ActionsOrgPolicy struct {
1797
+	OrgID                    int64
1798
+	ActionsEnabled           ActionsPolicyState
1799
+	RequirePrApproval        pgtype.Bool
1800
+	MaxRepoQueuedRuns        pgtype.Int4
1801
+	MaxRepoConcurrentJobs    pgtype.Int4
1802
+	MaxOwnerConcurrentJobs   pgtype.Int4
1803
+	ActorTriggerLimitPerHour pgtype.Int4
1804
+	UpdatedByUserID          pgtype.Int8
1805
+	CreatedAt                pgtype.Timestamptz
1806
+	UpdatedAt                pgtype.Timestamptz
1807
+}
1808
+
1809
+type ActionsRepoPolicy struct {
1810
+	RepoID                   int64
1811
+	ActionsEnabled           ActionsPolicyState
1812
+	RequirePrApproval        pgtype.Bool
1813
+	MaxRepoQueuedRuns        pgtype.Int4
1814
+	MaxRepoConcurrentJobs    pgtype.Int4
1815
+	MaxOwnerConcurrentJobs   pgtype.Int4
1816
+	ActorTriggerLimitPerHour pgtype.Int4
1817
+	UpdatedByUserID          pgtype.Int8
1818
+	CreatedAt                pgtype.Timestamptz
1819
+	UpdatedAt                pgtype.Timestamptz
1820
+}
1821
+
1822
+type ActionsSitePolicy struct {
1823
+	ID                       bool
1824
+	ActionsEnabled           bool
1825
+	RequirePrApproval        bool
1826
+	MaxRepoQueuedRuns        int32
1827
+	MaxRepoConcurrentJobs    int32
1828
+	MaxOwnerConcurrentJobs   int32
1829
+	ActorTriggerLimitPerHour int32
1830
+	UpdatedByUserID          pgtype.Int8
1831
+	CreatedAt                pgtype.Timestamptz
1832
+	UpdatedAt                pgtype.Timestamptz
1833
+}
1834
+
17531835
 type ActionsVariable struct {
17541836
 	ID              int64
17551837
 	RepoID          pgtype.Int8
@@ -2757,6 +2839,18 @@ type WorkflowRun struct {
27572839
 	TriggerEventID   string
27582840
 }
27592841
 
2842
+type WorkflowRunApproval struct {
2843
+	RunID            int64
2844
+	RequestedReason  string
2845
+	RequestedAt      pgtype.Timestamptz
2846
+	ApprovedByUserID pgtype.Int8
2847
+	ApprovedAt       pgtype.Timestamptz
2848
+	RejectedByUserID pgtype.Int8
2849
+	RejectedAt       pgtype.Timestamptz
2850
+	CreatedAt        pgtype.Timestamptz
2851
+	UpdatedAt        pgtype.Timestamptz
2852
+}
2853
+
27602854
 type WorkflowRunner struct {
27612855
 	ID                 int64
27622856
 	Name               string