Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .github/workflows/check-jira-link.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: 'Check Jira Link in PR'

on:
pull_request:
types: [opened, edited, reopened, synchronize]

jobs:
check_jira_link:
runs-on: linux-arm64
steps:
- name: Check for Jira link in PR description
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const prBody = context.payload.pull_request.body || '';
const prTitle = context.payload.pull_request.title || '';
const branchName = context.payload.pull_request.head.ref || '';
const prAuthor = context.payload.pull_request.user.login || '';

// Skip validation for automated PRs (Renovate, Dependabot, etc.)
const automatedBots = ['renovate[bot]', 'dependabot[bot]'];
if (automatedBots.includes(prAuthor)) {
core.info(`✅ Automated PR from ${prAuthor} - skipping Jira link validation`);
return;
}

// Check if "nojira" or "no-jira" is present in branch name, title, or description (case-insensitive)
const noJiraPattern = /no-?jira/i;
const hasNoJira = noJiraPattern.test(branchName) ||
noJiraPattern.test(prTitle) ||
noJiraPattern.test(prBody);

if (hasNoJira) {
core.info('✅ "nojira"/"no-jira" found - skipping Jira link validation');
return;
}

// Check for Jira link
const jiraLinkPattern = /https:\/\/montaapp\.atlassian\.net\/browse\/[A-Z]+-\d+/;

if (!jiraLinkPattern.test(prBody)) {
core.setFailed('❌ No Jira ticket link found in PR description.\n\n' +
'Please add a link to your Jira ticket in the format:\n' +
'https://montaapp.atlassian.net/browse/PROJECT-123\n\n' +
'Example: https://montaapp.atlassian.net/browse/CPONETOPS-568\n\n' +
'To skip this check, include "nojira" or "no-jira" in the branch name, PR title, or description.');
} else {
const match = prBody.match(jiraLinkPattern);
core.info(`✅ Found Jira ticket: ${match[0]}`);
}
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ This repository contains several reusable workflows designed to streamline the C
### `sonar-cloud.yml`
- **Purpose**: Integrates with SonarCloud for analyzing code quality and vulnerabilities.

### `check-jira-link.yml`
- **Purpose**: Validates that pull requests include a link to a Jira ticket in their description. Skips automated PRs (Renovate, Dependabot) and allows opting out by including `nojira` or `no-jira` in the branch name, PR title, or description.

### `semgrep-security-scan.yml`
- **Purpose**: Runs Semgrep static analysis to detect security vulnerabilities, hardcoded secrets, and unsafe coding patterns. Designed primarily for pull requests (PR commenting, diff-aware scanning), but can be called from other event types via `workflow_call` with limited functionality.

Expand Down
Loading