tenseleyflow/shithub / e1d20b6

Browse files

migration 0049: actions_variables (S41a)

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
e1d20b6fb15f6bd72b79540f963905cd533684c5
Parents
0d4a1fc
Tree
65db8fa

1 changed file

StatusFile+-
A internal/migrationsfs/migrations/0049_actions_variables.sql 50 0
internal/migrationsfs/migrations/0049_actions_variables.sqladded
@@ -0,0 +1,50 @@
1
+-- SPDX-License-Identifier: AGPL-3.0-or-later
2
+--
3
+-- S41a actions variables — non-secret per-repo or per-org config.
4
+--
5
+-- Mirrors GHA's `vars` namespace (and Forgejo's actions_variables).
6
+-- Distinct from workflow_secrets because:
7
+--   - Plaintext (no encryption needed; not sensitive)
8
+--   - Surfaced in workflow expressions as ${{ vars.NAME }} (vs
9
+--     ${{ secrets.NAME }})
10
+--   - NOT scrubbed from logs
11
+--
12
+-- Use cases: target image tags, environment names, feature flags,
13
+-- non-secret API endpoints. Operators set these via the same settings
14
+-- pages as secrets (S41c) but without the encryption ceremony.
15
+--
16
+-- Owner XOR + per-scope name uniqueness is identical to workflow_secrets
17
+-- (0045) so the orchestration layer can treat them symmetrically.
18
+
19
+-- +goose Up
20
+
21
+CREATE TABLE actions_variables (
22
+    id                bigserial    PRIMARY KEY,
23
+    repo_id           bigint       REFERENCES repos(id) ON DELETE CASCADE,
24
+    org_id            bigint       REFERENCES orgs(id)  ON DELETE CASCADE,
25
+    name              citext       NOT NULL,
26
+    value             text         NOT NULL DEFAULT '',
27
+    created_by_user_id bigint      REFERENCES users(id) ON DELETE SET NULL,
28
+    created_at        timestamptz  NOT NULL DEFAULT now(),
29
+    updated_at        timestamptz  NOT NULL DEFAULT now(),
30
+
31
+    CONSTRAINT actions_variables_owner_xor CHECK (
32
+        (repo_id IS NOT NULL AND org_id IS NULL) OR
33
+        (repo_id IS NULL     AND org_id IS NOT NULL)
34
+    ),
35
+    CONSTRAINT actions_variables_name_length CHECK (char_length(name::text) BETWEEN 1 AND 100),
36
+    CONSTRAINT actions_variables_name_format CHECK (name::text ~ '^[A-Za-z_][A-Za-z0-9_]*$'),
37
+    CONSTRAINT actions_variables_value_length CHECK (char_length(value) <= 4096)
38
+);
39
+
40
+CREATE UNIQUE INDEX actions_variables_repo_name_idx
41
+    ON actions_variables (repo_id, name) WHERE repo_id IS NOT NULL;
42
+CREATE UNIQUE INDEX actions_variables_org_name_idx
43
+    ON actions_variables (org_id, name)  WHERE org_id  IS NOT NULL;
44
+
45
+CREATE TRIGGER set_updated_at BEFORE UPDATE ON actions_variables
46
+    FOR EACH ROW EXECUTE FUNCTION tg_set_updated_at();
47
+
48
+
49
+-- +goose Down
50
+DROP TABLE IF EXISTS actions_variables;