| 1 | -- SPDX-License-Identifier: AGPL-3.0-or-later |
| 2 | -- |
| 3 | -- Workflow caches. Records of cached workflow artifacts uploaded by |
| 4 | -- the `actions/cache@v*` workflow step. Mirrors GitHub Actions' |
| 5 | -- cache semantics: |
| 6 | -- |
| 7 | -- * cache_key: the user-supplied cache key (e.g. "node-modules-${{ hashFiles(...) }}"). |
| 8 | -- * cache_version: a content-derived version string (matches gh's |
| 9 | -- `version` field — opaque to the server). |
| 10 | -- * git_ref: the ref the cache was created against. The actions/cache |
| 11 | -- restore logic looks up caches for the current ref first, then |
| 12 | -- falls back to the repo's default branch. |
| 13 | -- * object_key: location of the tarball in the shared object store. |
| 14 | -- * size_bytes: persisted size for capacity-tracking. |
| 15 | -- |
| 16 | -- A row uniquely identifies a cache by (repo_id, cache_key, |
| 17 | -- cache_version, git_ref) — multiple refs/versions can share a key, |
| 18 | -- but a given (key, version, ref) is one tarball. |
| 19 | -- |
| 20 | -- last_accessed_at is bumped by the runner on cache restore so the |
| 21 | -- LRU eviction policy can purge oldest entries first. The §13 REST |
| 22 | -- surface exposes list + delete; the eviction sweeper runs out of |
| 23 | -- band (future sprint). |
| 24 | -- |
| 25 | -- The runner-side write path that POPULATES this table is not yet |
| 26 | -- implemented — the actions/cache toolkit's upload protocol is its |
| 27 | -- own sprint. This table + the REST surface land first so operators |
| 28 | -- have an observation seat for when caches arrive. |
| 29 | |
| 30 | -- +goose Up |
| 31 | CREATE TABLE workflow_caches ( |
| 32 | id bigserial PRIMARY KEY, |
| 33 | repo_id bigint NOT NULL REFERENCES repos(id) ON DELETE CASCADE, |
| 34 | cache_key text NOT NULL, |
| 35 | cache_version text NOT NULL, |
| 36 | git_ref text NOT NULL, |
| 37 | object_key text NOT NULL, |
| 38 | size_bytes bigint NOT NULL DEFAULT 0, |
| 39 | last_accessed_at timestamptz NOT NULL DEFAULT now(), |
| 40 | created_at timestamptz NOT NULL DEFAULT now(), |
| 41 | |
| 42 | UNIQUE (repo_id, cache_key, cache_version, git_ref), |
| 43 | CONSTRAINT workflow_caches_cache_key_length CHECK (char_length(cache_key) BETWEEN 1 AND 512), |
| 44 | CONSTRAINT workflow_caches_cache_version_length CHECK (char_length(cache_version) BETWEEN 1 AND 256), |
| 45 | CONSTRAINT workflow_caches_git_ref_length CHECK (char_length(git_ref) BETWEEN 1 AND 256), |
| 46 | CONSTRAINT workflow_caches_size_nonneg CHECK (size_bytes >= 0) |
| 47 | ); |
| 48 | |
| 49 | CREATE INDEX workflow_caches_repo_id_idx |
| 50 | ON workflow_caches (repo_id, last_accessed_at DESC); |
| 51 | |
| 52 | CREATE INDEX workflow_caches_repo_id_key_idx |
| 53 | ON workflow_caches (repo_id, cache_key); |
| 54 | |
| 55 | -- +goose Down |
| 56 | DROP TABLE IF EXISTS workflow_caches; |
| 57 |