MySQL · 1918 bytes Raw Blame History
1 -- SPDX-License-Identifier: AGPL-3.0-or-later
2 --
3 -- S41a workflow artifacts — uploaded blobs from `shithub/upload-artifact`
4 -- magic step.
5 --
6 -- Each row references the run (not the job) so re-runs can produce a
7 -- fresh artifact set; (run_id, name) is unique per run. object_key is
8 -- the Spaces key (under runs/<run_id>/artifacts/<name>); the blob
9 -- itself lives in object storage, not Postgres.
10 --
11 -- expires_at defaults to 90 days from creation; the retention sweep
12 -- (S41g) deletes Spaces blobs past their expiry and prunes rows.
13 -- Per-run override is supported via the upload-artifact `retention-days`
14 -- input.
15 --
16 -- The runner uses signed S3 PUT URLs (S41c artifact upload endpoint)
17 -- to upload directly without proxying through shithubd-web. The
18 -- byte_count is reported back after upload completes (S41d).
19
20 -- +goose Up
21
22 CREATE TABLE workflow_artifacts (
23 id bigserial PRIMARY KEY,
24 run_id bigint NOT NULL REFERENCES workflow_runs(id) ON DELETE CASCADE,
25 name text NOT NULL,
26 object_key text NOT NULL,
27 byte_count bigint NOT NULL DEFAULT 0,
28 expires_at timestamptz NOT NULL DEFAULT (now() + interval '90 days'),
29 created_at timestamptz NOT NULL DEFAULT now(),
30
31 UNIQUE (run_id, name),
32
33 CONSTRAINT workflow_artifacts_name_length CHECK (char_length(name) BETWEEN 1 AND 100),
34 CONSTRAINT workflow_artifacts_name_format CHECK (
35 name ~ '^[A-Za-z0-9._-]+$' AND name NOT LIKE '..%' AND name NOT LIKE '%/%'
36 ),
37 CONSTRAINT workflow_artifacts_object_key_length CHECK (char_length(object_key) BETWEEN 1 AND 1024),
38 CONSTRAINT workflow_artifacts_byte_count_nonneg CHECK (byte_count >= 0)
39 );
40
41 CREATE INDEX workflow_artifacts_run_idx ON workflow_artifacts (run_id);
42 CREATE INDEX workflow_artifacts_expires_idx ON workflow_artifacts (expires_at);
43
44
45 -- +goose Down
46 DROP TABLE IF EXISTS workflow_artifacts;
47