Skip to content

g1t/services/actions/migrations/0006_artifacts.sql

68 lines2,919 bytesCodeBlameRaw
1-- Artifacts of workflow runs, kept in R2 (the ACTIONS_CACHE bucket, under
2-- `a/`) rather than in KV: which there are, how big, until when, and the
3-- toolkit's protocols for them and for the cache. See
4-- services/actions/src/artifacts.rs and services/actions/src/toolkit.rs.
5--
6-- Creating a table or index that exists leaves it as it is. The ALTER at
7-- the end runs once, as D1 runs each migration once.
8
9-- One row per artifact. `id` is a number, as GitHub's artifact ids are,
10-- so actions and scripts that read them as numbers keep working.
11CREATE TABLE IF NOT EXISTS artifacts (
12 id INTEGER PRIMARY KEY AUTOINCREMENT,
13 repo_id TEXT NOT NULL,
14 -- The workspace's slug, whose storage it counts toward.
15 namespace TEXT NOT NULL,
16 run_id TEXT NOT NULL,
17 -- The job that uploaded it.
18 job_id TEXT NOT NULL,
19 name TEXT NOT NULL,
20 -- Its object in R2.
21 object TEXT NOT NULL,
22 -- zip, or tgz for one an older runner sent whole.
23 format TEXT NOT NULL DEFAULT 'zip',
24 size INTEGER NOT NULL DEFAULT 0,
25 -- sha256:<hex> of its bytes, when the uploader said.
26 digest TEXT,
27 -- pending (being uploaded), ready, or expired (its object is to be
28 -- deleted, then the row).
29 status TEXT NOT NULL,
30 created_at TEXT NOT NULL,
31 updated_at TEXT NOT NULL,
32 expires_at TEXT NOT NULL
33);
34-- A name is one artifact in a run, until it expires or is deleted.
35CREATE UNIQUE INDEX IF NOT EXISTS artifacts_by_name ON artifacts (run_id, name) WHERE status <> 'expired';
36CREATE INDEX IF NOT EXISTS artifacts_by_repo ON artifacts (repo_id, status, id);
37CREATE INDEX IF NOT EXISTS artifacts_by_expiry ON artifacts (status, expires_at);
38CREATE INDEX IF NOT EXISTS artifacts_by_namespace ON artifacts (namespace, status);
39
40-- The parts of an upload sent through the toolkit's blob protocol, which
41-- names its blocks rather than keeping their etags: R2 needs every part's
42-- etag to finish the upload. Deleted when it finishes, or by the sweep.
43CREATE TABLE IF NOT EXISTS blob_parts (
44 upload TEXT NOT NULL,
45 part INTEGER NOT NULL,
46 etag TEXT NOT NULL,
47 size INTEGER NOT NULL,
48 created_at TEXT NOT NULL,
49 PRIMARY KEY (upload, part)
50);
51CREATE INDEX IF NOT EXISTS blob_parts_by_age ON blob_parts (created_at);
52
53-- A repository's own Actions settings: how long its artifacts are kept by
54-- default, and at most.
55CREATE TABLE IF NOT EXISTS repo_settings (
56 repo_id TEXT PRIMARY KEY,
57 artifact_retention_days INTEGER NOT NULL,
58 updated_at TEXT NOT NULL,
59 updated_by TEXT
60);
61
62-- The toolkit's cache client names the version of an entry (a hash of its
63-- paths and compression): it restores only entries of the same version.
64-- Entries saved by g1t's own `actions/cache` have none.
65ALTER TABLE cache_entries ADD COLUMN version TEXT NOT NULL DEFAULT '';
66-- The R2 upload of an entry still being sent, for the toolkit's older
67-- protocol, whose requests name only the entry.
68ALTER TABLE cache_entries ADD COLUMN upload TEXT;