tenseleyflow/shithub / ceff48e

Browse files

migration 0044: workflow_steps (S41a)

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
ceff48e6228f76efe79cb07d99ebb2d9c06b7b9c
Parents
09401b4
Tree
457a167

1 changed file

StatusFile+-
A internal/migrationsfs/migrations/0044_workflow_steps.sql 85 0
internal/migrationsfs/migrations/0044_workflow_steps.sqladded
@@ -0,0 +1,85 @@
1
+-- SPDX-License-Identifier: AGPL-3.0-or-later
2
+--
3
+-- S41a workflow steps — one row per `steps[]` entry in a job.
4
+--
5
+-- Steps execute serially within a job. status moves queued → running →
6
+-- completed | cancelled | skipped (skipped fires when an earlier
7
+-- step fails and continue-on-error wasn't set).
8
+--
9
+-- The `run` text is the shell command. The parser (S41a) tags every
10
+-- expression value carried into this string with a Tainted flag; the
11
+-- runner's exec layer (S41d) refuses to interpolate Tainted values
12
+-- into shell strings — they compile to ${SHITHUB_INPUT_*} envvar refs
13
+-- set safely by the runner. We don't need a separate "compiled"
14
+-- column; the render step happens in-runner each execution.
15
+--
16
+-- log_object_key holds the Spaces blob key after the finalize worker
17
+-- (S41d) concatenates and uploads chunks. NULL while running; chunks
18
+-- live in workflow_step_log_chunks (0047) until finalize.
19
+--
20
+-- step_index gives the dispatch order (0-based). step_id (text) is
21
+-- the optional GHA `id:` for cross-step references via
22
+-- ${{ steps.<id>.outputs.X }} (outputs are v2; the column exists now
23
+-- so the parser can carry the id without a schema change).
24
+
25
+-- +goose Up
26
+
27
+CREATE TYPE workflow_step_status AS ENUM (
28
+    'queued', 'running', 'completed', 'cancelled', 'skipped'
29
+);
30
+
31
+CREATE TABLE workflow_steps (
32
+    id                  bigserial             PRIMARY KEY,
33
+    job_id              bigint                NOT NULL REFERENCES workflow_jobs(id) ON DELETE CASCADE,
34
+    step_index          integer               NOT NULL,
35
+    step_id             text                  NOT NULL DEFAULT '',
36
+    step_name           text                  NOT NULL DEFAULT '',
37
+    if_expr             text                  NOT NULL DEFAULT '',
38
+    run_command         text                  NOT NULL DEFAULT '',
39
+    uses_alias          text                  NOT NULL DEFAULT '',
40
+    working_directory   text                  NOT NULL DEFAULT '',
41
+    step_env            jsonb                 NOT NULL DEFAULT '{}'::jsonb,
42
+    continue_on_error   boolean               NOT NULL DEFAULT false,
43
+    status              workflow_step_status  NOT NULL DEFAULT 'queued',
44
+    conclusion          check_conclusion,
45
+    log_object_key      text,
46
+    log_byte_count      bigint                NOT NULL DEFAULT 0,
47
+    started_at          timestamptz,
48
+    completed_at        timestamptz,
49
+    version             integer               NOT NULL DEFAULT 0,
50
+    created_at          timestamptz           NOT NULL DEFAULT now(),
51
+    updated_at          timestamptz           NOT NULL DEFAULT now(),
52
+
53
+    UNIQUE (job_id, step_index),
54
+
55
+    CONSTRAINT workflow_steps_step_id_format CHECK (
56
+        step_id = '' OR step_id ~ '^[A-Za-z_][A-Za-z0-9_-]*$'
57
+    ),
58
+    CONSTRAINT workflow_steps_name_length CHECK (char_length(step_name) <= 256),
59
+    CONSTRAINT workflow_steps_run_or_uses CHECK (
60
+        (run_command <> '' AND uses_alias = '') OR
61
+        (run_command = '' AND uses_alias <> '')
62
+    ),
63
+    CONSTRAINT workflow_steps_uses_alias_known CHECK (
64
+        uses_alias IN ('', 'actions/checkout@v4',
65
+                       'shithub/upload-artifact@v1',
66
+                       'shithub/download-artifact@v1')
67
+    ),
68
+    CONSTRAINT workflow_steps_working_directory_length CHECK (
69
+        char_length(working_directory) <= 1024
70
+    ),
71
+    CONSTRAINT workflow_steps_completed_has_conclusion CHECK (
72
+        status NOT IN ('completed', 'skipped') OR conclusion IS NOT NULL
73
+    ),
74
+    CONSTRAINT workflow_steps_log_byte_nonnegative CHECK (log_byte_count >= 0)
75
+);
76
+
77
+CREATE INDEX workflow_steps_job_idx ON workflow_steps (job_id);
78
+
79
+CREATE TRIGGER set_updated_at BEFORE UPDATE ON workflow_steps
80
+    FOR EACH ROW EXECUTE FUNCTION tg_set_updated_at();
81
+
82
+
83
+-- +goose Down
84
+DROP TABLE IF EXISTS workflow_steps;
85
+DROP TYPE IF EXISTS workflow_step_status;