TPT-4298: Added PR title checking workflow and clean up release notes workflow#223
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds GitHub Actions automation to enforce a Jira-style PR title prefix (TPT-1234:) and to post-process published release notes by removing TPT-####: prefixes from generated patch notes.
Changes:
- Added a PR-title validation workflow intended to require
TPT-1234:-style prefixes (with label-based exemptions). - Added a release-published workflow to update release bodies by stripping
TPT-####:prefixes. - Introduced workflow-level permissions appropriate for reading PR metadata and updating release content.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| .github/workflows/validate-pr-title.yml | New workflow to validate PR titles against a TPT-####: prefix rule (with exemptions). |
| .github/workflows/clean-release-notes.yml | New workflow to edit published release notes and remove TPT-####: prefixes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -0,0 +1,35 @@ | |||
| name: 'Validate PR Title' | |||
| on: | |||
| pull_request: | |||
There was a problem hiding this comment.
on: pull_request without explicit activity types does not include the edited event. That means a PR title can be changed after the initial check and this workflow won’t rerun automatically, leaving a stale green check. Add on.pull_request.types to include at least edited (and typically opened, reopened, synchronize) so title edits are revalidated.
| pull_request: | |
| pull_request: | |
| types: [opened, reopened, synchronize, edited] |
| uses: amannn/action-semantic-pull-request@v6 | ||
| with: | ||
| types: | | ||
| TPT-\d+ | ||
| requireScope: false | ||
| # Override the default header pattern to allow hyphens and digits in the type | ||
| # (e.g. "TPT-4298: Description"). The default pattern only matches word | ||
| # characters (\w) which excludes hyphens. | ||
| headerPattern: '^([\w-]+):\s?(.*)$' | ||
| headerPatternCorrespondence: type, subject | ||
| ignoreLabels: | | ||
| dependencies | ||
| hotfix | ||
| community-contribution | ||
| ignore-for-release | ||
| env: | ||
| GITHUB_TOKEN: ${{ github.token }} |
There was a problem hiding this comment.
amannn/action-semantic-pull-request treats types as a list of allowed literal types, not a regex. With types: TPT-\d+, titles like TPT-4298: ... will be parsed as type TPT-4298 and won’t match the literal TPT-\d+, causing the check to fail unexpectedly. Consider switching to a simple regex validation step against github.event.pull_request.title, or adjust the action config to validate the Jira pattern via headerPattern without relying on types matching dynamic IDs.
| uses: amannn/action-semantic-pull-request@v6 | |
| with: | |
| types: | | |
| TPT-\d+ | |
| requireScope: false | |
| # Override the default header pattern to allow hyphens and digits in the type | |
| # (e.g. "TPT-4298: Description"). The default pattern only matches word | |
| # characters (\w) which excludes hyphens. | |
| headerPattern: '^([\w-]+):\s?(.*)$' | |
| headerPatternCorrespondence: type, subject | |
| ignoreLabels: | | |
| dependencies | |
| hotfix | |
| community-contribution | |
| ignore-for-release | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| env: | |
| PR_TITLE: ${{ github.event.pull_request.title }} | |
| PR_LABELS: ${{ toJson(github.event.pull_request.labels) }} | |
| run: | | |
| echo "PR title: \"$PR_TITLE\"" | |
| echo "PR labels: $PR_LABELS" | |
| python - << 'PY' | |
| import json | |
| import os | |
| import re | |
| import sys | |
| title = os.environ.get("PR_TITLE", "") | |
| labels_raw = os.environ.get("PR_LABELS", "[]") | |
| try: | |
| labels = json.loads(labels_raw) | |
| except json.JSONDecodeError: | |
| print("::warning::Unable to parse PR labels; proceeding without exemptions.") | |
| labels = [] | |
| exempt_labels = { | |
| "dependencies", | |
| "hotfix", | |
| "community-contribution", | |
| "ignore-for-release", | |
| } | |
| label_names = {label.get("name", "") for label in labels if isinstance(label, dict)} | |
| # Skip validation if any exempting label is present. | |
| if exempt_labels & label_names: | |
| print("Exempting PR from title validation due to labels:", ", ".join(exempt_labels & label_names)) | |
| sys.exit(0) | |
| pattern = re.compile(r"^TPT-\d+:\s?.+") | |
| if not pattern.match(title): | |
| print("::error::PR title must start with 'TPT-<number>:' (e.g., 'TPT-1234: Description').") | |
| sys.exit(1) | |
| print("PR title matches required pattern.") | |
| PY |
| // Remove ticket prefixes like "TPT-1234: " or "TPT-1234:" | ||
| body = body.replace(/TPT-\d+:\s*/g, ''); |
There was a problem hiding this comment.
The replacement regex /TPT-\d+:\s*/g removes ticket IDs anywhere in the release body, including mid-sentence references (e.g., “See TPT-1234: for details”), not just leading prefixes on changelog lines. If the intent is only to strip per-entry prefixes, anchor the pattern to line starts (multiline) and optionally to list markers so other references aren’t accidentally altered.
| // Remove ticket prefixes like "TPT-1234: " or "TPT-1234:" | |
| body = body.replace(/TPT-\d+:\s*/g, ''); | |
| // Remove ticket prefixes like "TPT-1234: " or "TPT-1234:" only at the start of lines (optionally after list markers) | |
| body = body.replace(/^(\s*[-*]\s*)?TPT-\d+:\s*/gm, ''); |
📝 Description
Added a new workflow to fail if the PR title does not begin with "TPT-1234:" (works with and without a space between the colon and description).
Also added a new workflow to run upon release publish to edit the release notes to remove the Jira ticket ID prefixes from patch notes.
✔️ How to Test
To test the PR title enforcement, edit the title of this PR to remove the Jira ticket ID and rerun the pr title validation job. It should fail immediately. Then, add the Jira ticket ID back to the PR title and it should pass.
To test the release note cleanup job, check out this PR locally and merge it into your fork. Then, cut a test release to your fork. Upon generating the release notes, the TPT-**** prefix will still be there. Publish the release and verify that the new workflow is triggered. After it finishes, confirm that the release notes were correctly updated.