tenseleyflow/shithub / cb75271

Browse files

migration 0051: workflow_runs.trigger_event_id + partial unique index (S41b)

Idempotency on the *triggering event* — the robust pattern. Each
push, PR transition, dispatch click, or cron tick is a unique
triggering event with a stable identifier constructed by the
enqueueing site:

- push_process → &#39;push:<push_event_id>&#39;
- PR open/synchronize → &#39;pr_<action>:<pr_id>:<head_sha>&#39;
- workflow_dispatch → &#39;dispatch:<workflow_id>:<request_uuid>&#39;
- schedule sweep → &#39;schedule:<workflow_id>:<window_start_unix>&#39;

Partial UNIQUE on (repo_id, workflow_file, trigger_event_id) WHERE
trigger_event_id <> &#39;&#39; is the dedup key. Trigger handler does
INSERT ... ON CONFLICT DO NOTHING; worker retries + admin replays of
the same triggering event no-op cleanly.

Re-runs (the future Re-run button) explicitly produce a new
trigger_event_id (e.g. &#39;rerun:<original_run_id>:<request_uuid>&#39;) so
they don&#39;t collide. parent_run_id chains the new run back to its
ancestor — history preserved.

DEFAULT &#39;&#39; covers the migration-time backfill (no rows yet); the
partial UNIQUE excludes empty so backfilled rows don&#39;t constrain
each other. New code is responsible for always providing a
non-empty trigger_event_id.
Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
cb75271f5b152d4121b5ffa4c5e55d443fd3e2ff
Parents
e5f9775
Tree
ca33140

1 changed file

StatusFile+-
A internal/migrationsfs/migrations/0051_workflow_runs_trigger_event_id.sql 44 0
internal/migrationsfs/migrations/0051_workflow_runs_trigger_event_id.sqladded
@@ -0,0 +1,44 @@
1
+-- SPDX-License-Identifier: AGPL-3.0-or-later
2
+--
3
+-- S41b trigger pipeline: idempotency on the *triggering event*.
4
+--
5
+-- Each push, PR transition, dispatch click, or cron tick is a unique
6
+-- triggering event with a stable identifier constructed by the
7
+-- enqueueing site:
8
+--
9
+--   - push_process       → "push:<push_event_id>"
10
+--   - pr open/synchronize → "pr_<action>:<pr_id>:<head_sha>"
11
+--   - workflow_dispatch  → "dispatch:<workflow_id>:<request_uuid>"
12
+--   - schedule sweep     → "schedule:<workflow_id>:<window_start_unix>"
13
+--
14
+-- The trigger handler's INSERT … ON CONFLICT DO NOTHING uses the
15
+-- partial UNIQUE index below to dedupe across worker retries (e.g.,
16
+-- push_process retried after a transient error) and admin replays
17
+-- (operators using `admin run-job workflow:trigger ...`). One
18
+-- triggering event → one workflow_runs row per matched workflow file.
19
+--
20
+-- Re-runs (the future "Re-run" button) explicitly produce a NEW
21
+-- trigger_event_id (e.g. "rerun:<original_run_id>:<request_uuid>"), so
22
+-- they don't collide and `parent_run_id` chains them back. History is
23
+-- preserved.
24
+--
25
+-- DEFAULT '' on the column lets the migration apply against any
26
+-- pre-existing rows (none yet — S41a shipped the schema but nothing
27
+-- populates it). The partial UNIQUE excludes the empty string so
28
+-- those backfilled rows don't constrain each other; new code is
29
+-- responsible for always setting a non-empty value.
30
+
31
+-- +goose Up
32
+
33
+ALTER TABLE workflow_runs
34
+    ADD COLUMN trigger_event_id text NOT NULL DEFAULT '';
35
+
36
+CREATE UNIQUE INDEX workflow_runs_trigger_event_idx
37
+    ON workflow_runs (repo_id, workflow_file, trigger_event_id)
38
+    WHERE trigger_event_id <> '';
39
+
40
+
41
+-- +goose Down
42
+
43
+DROP INDEX IF EXISTS workflow_runs_trigger_event_idx;
44
+ALTER TABLE workflow_runs DROP COLUMN trigger_event_id;