Git Trigger Picker
Overview
The Git step of the workflow editor lets users choose when protection fires. It defaults to a one-click "Every tagged release" trigger, with an optional advanced mode for custom Tag/Push wildcard patterns and a live preview.
How it works
- Simple mode (default): one click on Add registers
{ name: 'tag' }— match all tags. - Customize reveals the advanced picker: a Tag / Push toggle + a wildcard pattern field.
- A reserved-space preview block renders three concrete examples that update with the wildcard (no layout shift).
- The repository-events table shows each trigger with a tag/branch icon, pattern chips, and an info tooltip (summary + examples). The
ALLchip can be deleted.
How it works (data model)
ProjectFormatter (ui/src/utils/format.ts) owns the add/remove semantics:
addEvents(params, type, pattern?)— without pattern: resets to match-all; with pattern: replaces a previous ALL or appends (no dupes).removeEvent(key, type, index)— splices and drops the event entry when the last pattern is removed (no phantom "ALL")..cleanalways emits a backend-clean shape:{ name: 'tag' }for ALL,{ name: 'tag', pattern: [...] }for specifics.- Hydrate (
ProjectFormatter.for) tolerates every historical shape:{ name: 'tag' },{ pattern: [] }, legacy{ pattern: [''] }, mixed{ pattern: ['v*', ''] }.
Key files
ui/src/pages/workflows/stepForms/TriggerSelector.tsx— simple/advanced pickerui/src/utils/format.ts—ProjectFormattersemantics + legacy-tolerant hydrateui/src/utils/eventSummary.ts— single-sentence human summaryui/src/utils/triggerExamples.ts— 3-example generator with regex-safe wildcard substitution
Technical decisions
- Backward compatibility on hydrate is explicit and tested (15 → 21 cases) so updating Tower never breaks reading older configs.
- A dev-only mock for
discoverProjects(active invite dev, persisted inlocalStorage, tree-shaken from production) lets developers iterate on the editor without live provider tokens.
Next steps
- Consider preset patterns (e.g. semver-only) as quick picks in advanced mode