Skip to content

feat(features): manual PR match tag for Jira-less PR->feature association - #3

Open
puneetadlerqa wants to merge 4 commits into
mainfrom
feat/feature-pr-match-key
Open

feat(features): manual PR match tag for Jira-less PR->feature association#3
puneetadlerqa wants to merge 4 commits into
mainfrom
feat/feature-pr-match-key

Conversation

@puneetadlerqa

Copy link
Copy Markdown
Contributor

Adds an optional per-feature [KEY] match tag so PRs auto-associate to a feature without Jira. map_pr_to_feature falls back to a bracketed-tag match; settable at create + editable on the feature. Fixes: PRs left unmapped (poller never surfaces them) when no Jira epic.

…tion

Projects without a linked Jira epic had no way to associate PRs with a feature:
map_pr_to_feature only resolved Jira-style keys, so PRs were left unmapped and the
120s poller could never surface them under the feature.

Add an optional per-feature 'match_key'. When set, a PR whose title/body contains
the bracketed tag (e.g. [HOLDS]) auto-maps to that feature — picked up by the
existing poller/webhook path with no extra wiring. Explicit [KEY] tag only (no
fuzzy/substring), so it stays precise like the Jira-key behaviour.

- store: match_key on create_feature; set_feature_match_key (all versions);
  features_with_match_key(project_id).
- coverage.map_pr_to_feature: [KEY]-tag fallback after Jira resolution (Jira epic
  still wins). Never crashes ingest.
- main: POST /api/features accepts match_key; POST /api/features/{fid}/match-key
  to set/edit it (editor+).
- UI: 'PR match tag' field on Create feature + an inline editor on the feature
  workspace.
- tests/test_pr_match_key.py: matcher unit tests (bracketed match, case-insensitive,
  unbracketed does NOT match, Jira epic precedence).
…rsion

new_version() carried the Jira epic key forward but not the manual match_key, so
re-importing a PRD (new version) reset the tag to null. Since the matcher reads the
latest version's match_key, this silently dropped PR auto-association after any
regeneration. Carry prev.match_key into the new version.
The manual PR match tag required a bracketed form ([FINES]); teams naturally
write the bare keyword (FINES / fines / FINES:). Match the tag as a whole,
case-insensitive token instead — brackets, colons and spaces all count as
boundaries — so FINES/[FINES]/FINES: all map, while REFINES/FINESSE do not.
…) matching

The matcher now treats the match tag as a whole word (brackets optional), so:
- method string is 'tag:HOLDS' (not 'tag:[HOLDS]')
- 'feat(HOLDS):' now maps (bare keyword)
- added a whole-word guard test: 'FINES' must not match REFINES/FINESSE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant