Skip to main content
Version: 3.1.0

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

  1. Simple mode (default): one click on Add registers { name: 'tag' } — match all tags.
  2. Customize reveals the advanced picker: a Tag / Push toggle + a wildcard pattern field.
  3. A reserved-space preview block renders three concrete examples that update with the wildcard (no layout shift).
  4. The repository-events table shows each trigger with a tag/branch icon, pattern chips, and an info tooltip (summary + examples). The ALL chip 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").
  • .clean always 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 picker
  • ui/src/utils/format.tsProjectFormatter semantics + legacy-tolerant hydrate
  • ui/src/utils/eventSummary.ts — single-sentence human summary
  • ui/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 in vite dev, persisted in localStorage, 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