Skip to content
Merged
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
38 changes: 38 additions & 0 deletions .github/actions/validate-pr/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: 'Validate PR'
description: 'Validate PR title and branch'
inputs:
pr_title:
description: 'The title of the pull request'
required: true
type: string
pr_branch:
description: 'The branch name of the pull request'
required: true
type: string
latest_release:
description: 'The latest release version'
required: true
type: string
package_version:
description: 'The version of the package'
required: true
type: string
target_branch:
description: 'The target branch for the pull request'
required: true
type: string
runs:
using: 'composite'
steps:
- id: composite
run: |
echo "$JSON"
bash ${{ github.action_path }}/validate_pr.sh
shell: bash
env:
JSON: ${{ toJson(inputs) }}
PR_TITLE: ${{ inputs.pr_title }}
PR_BRANCH: ${{ inputs.pr_branch }}
LATEST_RELEASE: ${{ inputs.latest_release }}
PACKAGE_VERSION: ${{ inputs.package_version }}
TARGET_BRANCH: ${{ inputs.target_branch }}
63 changes: 63 additions & 0 deletions .github/actions/validate-pr/validate_pr.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/bin/bash

if [ "$PR_TITLE" == "" ]; then
echo "env variable PR_TITLE is required"
exit 1
fi
if [ "$PR_BRANCH" == "" ]; then
echo "env variable PR_BRANCH is required"
exit 1
fi
if [ "$LATEST_RELEASE" == "" ]; then
echo "env variable LATEST_RELEASE is required"
exit 1
fi
if [ "$PACKAGE_VERSION" == "" ]; then
echo "env variable PACKAGE_VERSION is required"
exit 1
fi
if [ "$TARGET_BRANCH" == "" ]; then
echo "env variable TARGET_BRANCH is required"
exit 1
fi

SEMANTIC_PREFIXES="^(feat|fix|chore|docs|style|refactor|perf|test):"
JIRA_TICKET="([A-Z]+-[0-9]+)"
VERSION_REGEX="^v([0-9]+)\.([0-9]+)\.([0-9]+)$"

if [[ "$TARGET_BRANCH" == "develop" ]] || [[ "$TARGET_BRANCH" =~ ^release/v ]] || [[ "$TARGET_BRANCH" =~ ^hotfix/v ]]; then
if [[ "$PR_BRANCH" =~ ^release/v ]] || [[ "$PR_BRANCH" =~ ^hotfix/v ]]; then
echo "PR title and branch name validation passed."
exit 0
fi
if [[ ! "$PR_TITLE" =~ $SEMANTIC_PREFIXES ]]; then
echo "PR title must start with a valid semantic prefix (e.g., feat:, fix:)."
exit 1
fi

if [[ ! "$PR_TITLE" =~ $JIRA_TICKET ]]; then
echo "PR title must contain a valid Jira ticket ID (e.g., ABC-123)."
exit 1
fi
fi

if [[ "$TARGET_BRANCH" == "main" ]]; then
if [[ "$PR_BRANCH" =~ ^release/v ]] || [[ "$PR_BRANCH" =~ ^hotfix/v ]]; then
if [[ ! "$PR_BRANCH" =~ ^release/v$PACKAGE_VERSION ]] && [[ ! "$PR_BRANCH" =~ ^hotfix/v$PACKAGE_VERSION ]]; then
echo "PR branch and package version must match"
exit 1
elif [[ "$(printf '%s\n' "$PACKAGE_VERSION" "$LATEST_RELEASE" | sort | tail -n1)" == "$LATEST_RELEASE" ]]; then
echo "Next predicted version must be higher than the latest release."
exit 1
fi
else
echo "PR branch must be release/v$PACKAGE_VERSION or hotfix/v$PACKAGE_VERSION"
exit 1
fi
if [[ ! "$PR_BRANCH" =~ ^release/v$PACKAGE_VERSION ]] && [[ ! "$PR_BRANCH" =~ ^hotfix/v$PACKAGE_VERSION ]]; then
echo "PR branch must be release/v$PACKAGE_VERSION or hotfix/v$PACKAGE_VERSION"
exit 1
fi
fi

echo "PR title and branch name validation passed."
206 changes: 206 additions & 0 deletions .github/actions/validate-pr/validate_pr_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@

#!/bin/bash

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"

function expect() {
if [ "$1" != "$2" ]; then
echo "Expected: $2"
echo "Actual: $1"
exit 1
else
echo "OK"
fi
}

beforeAll() {
export TESTING=true
}

beforeEach() {
export PR_TITLE="feat: This is a PR title (ISSUE-1234)"
export PR_BRANCH="feature/ISSUE-1234"
export LATEST_RELEASE="1.0.0"
export PACKAGE_VERSION="1.1.0"
export TARGET_BRANCH="develop"
}

beforeAll

echo Scenario: PR title missing semantic prefix for feature branch
beforeEach

# GIVEN
export PR_TITLE="This is a PR title (ISSUE-1234)"

# WHEN
ACTUAL="$($SCRIPT_DIR/validate_pr.sh)"

# THEN
expect "$?" "1"
expect "$ACTUAL" "PR title must start with a valid semantic prefix (e.g., feat:, fix:)."

echo Scenario: PR title missing Jira ticket for feature branch
beforeEach

# GIVEN
export PR_TITLE="feat: This is a PR title"

# WHEN
ACTUAL="$($SCRIPT_DIR/validate_pr.sh)"

# THEN
expect "$?" "1"
expect "$ACTUAL" "PR title must contain a valid Jira ticket ID (e.g., ABC-123)."

echo Scenario: PR title missing Jira ticket for feature branch targeting hotfix branch
beforeEach

# GIVEN
export PR_TITLE="feat: This is a PR title"

# WHEN
ACTUAL="$($SCRIPT_DIR/validate_pr.sh)"

# THEN
expect "$?" "1"
expect "$ACTUAL" "PR title must contain a valid Jira ticket ID (e.g., ABC-123)."

echo Scenario: Valid PR title for feature branch
beforeEach

# GIVEN
export PR_TITLE="feat: This is a PR title (ISSUE-1234)"

# WHEN
ACTUAL="$($SCRIPT_DIR/validate_pr.sh)"

# THEN
expect "$?" "0"
expect "PR title and branch name validation passed." "$ACTUAL"

echo Scenario: Non release or hotfix branch targeting the main branch
beforeEach

# GIVEN
export PR_BRANCH="TICKET-123"
export TARGET_BRANCH="main"

# WHEN
ACTUAL="$($SCRIPT_DIR/validate_pr.sh)"

# THEN
expect "$?" "1"
expect "$ACTUAL" "PR branch must be release/v1.1.0 or hotfix/v1.1.0"

echo Scenario: Package version and branch name mismatch
beforeEach

# GIVEN
export PR_BRANCH="release/v1.1.0"
export TARGET_BRANCH="main"
export PACKAGE_VERSION="1.0.0"

# WHEN
ACTUAL="$($SCRIPT_DIR/validate_pr.sh)"

# THEN
expect "$?" "1"
expect "$ACTUAL" "PR branch and package version must match"

echo Scenario: Next Release version is not higher than the latest version
beforeEach

# GIVEN
export PR_BRANCH="release/v1.0.0"
export TARGET_BRANCH="main"
export PACKAGE_VERSION="1.0.0"

# WHEN
ACTUAL="$($SCRIPT_DIR/validate_pr.sh)"

# THEN
expect "$?" "1"
expect "$ACTUAL" "Next predicted version must be higher than the latest release."

echo Scenario: Valid feature branch to develop branch
beforeEach

# GIVEN
export PR_BRANCH="feature/ISSUE-1234"
export TARGET_BRANCH="develop"

# WHEN
ACTUAL="$($SCRIPT_DIR/validate_pr.sh)"

# THEN
expect "$?" "0"

echo Scenario: Valid feature branch to release branch
beforeEach

# GIVEN
export PR_BRANCH="feature/ISSUE-1234"
export TARGET_BRANCH="release/v1.1.0"

# WHEN
ACTUAL="$($SCRIPT_DIR/validate_pr.sh)"

# THEN
expect "$?" "0"

echo Scenario: Valid feature branch to hotfix branch
beforeEach

# GIVEN
export PR_BRANCH="feature/ISSUE-1234"
export TARGET_BRANCH="hotfix/v1.1.0"

# WHEN
ACTUAL="$($SCRIPT_DIR/validate_pr.sh)"

# THEN
expect "$?" "0"

echo Scenario: Valid release branch to main branch
beforeEach

# GIVEN
export PR_BRANCH="release/v1.1.0"
export TARGET_BRANCH="main"
export PR_TITLE="release v1.1.0 to main"

# WHEN
ACTUAL="$($SCRIPT_DIR/validate_pr.sh)"

# THEN
expect "$?" "0"

echo Scenario: Valid hotfix branch to main branch
beforeEach

# GIVEN
export PR_BRANCH="hotfix/v1.1.0"
export TARGET_BRANCH="main"
export PR_TITLE="hotfix v1.1.0 to main"

# WHEN
ACTUAL="$($SCRIPT_DIR/validate_pr.sh)"

# THEN
expect "$?" "0"

echo Scenario: Valid release branch merging to develop
beforeEach

# GIVEN
export PR_BRANCH="release/v1.1.0"
export TARGET_BRANCH="develop"
export PR_TITLE="release v1.1.0 to develop"

# WHEN
ACTUAL="$($SCRIPT_DIR/validate_pr.sh)"

# THEN
expect "$?" "0"

2 changes: 2 additions & 0 deletions .github/workflows/tag-tickets-with-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ jobs:
else
TARGET_BRANCH="origin/main"
fi
echo "Finding the common branch between HEAD and ${TARGET_BRANCH}" >&2
COMMON_BRANCH=$(git merge-base HEAD ${TARGET_BRANCH})
echo "Retrieving the git log between ${COMMON_BRANCH} and HEAD" >&2
DIFF="$(git log --pretty=format:'%s' ${COMMON_BRANCH}..HEAD)"
LLM_PROMPT_PREFIX="Create a fun release description in 100 characters or less in one line without identifiers for the following data:
"
Expand Down
44 changes: 44 additions & 0 deletions .github/workflows/validate-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Validate PR

on:
workflow_call:
inputs:
pr_title:
description: "The title of the pull request."
type: string
required: true
pr_branch:
description: "The branch name of the pull request."
type: string
required: true
target_branch:
description: "The target branch for the pull request."
type: string
required: true

jobs:
validate:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Get Latest Release
uses: VirdocsSoftware/github-actions/.github/actions/predict-next-version@main
- name: Get Package
run: |
PACKAGE_VERSION=$(cat package.json | jq -r '.version')
echo "PACKAGE_VERSION=$PACKAGE_VERSION" >> $GITHUB_ENV
echo "LATEST_RELEASE=$(cat latest_version.txt)" >> $GITHUB_ENV
- name: Print github json
run: echo "$JSON"
env:
JSON: ${{ toJson(inputs) }}
- name: Validate PR title and branch
uses: VirdocsSoftware/github-actions/.github/actions/validate-pr@main
with:
pr_title: ${{ inputs.pr_title }}
pr_branch: ${{ inputs.pr_branch }}
latest_release: ${{ env.LATEST_RELEASE }}
package_version: ${{ env.PACKAGE_VERSION }}
target_branch: ${{ inputs.target_branch }}

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "github-actions",
"version": "2.6.0",
"version": "2.7.0",
"description": "Used to store GitHub actions for use across the enterprise",
"scripts": {
"test": "./tooling/scripts/run_tests.sh",
Expand Down
6 changes: 6 additions & 0 deletions tooling/scripts/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,10 @@ function run_tests() {
done
}

function validate_tests() {
set -e
./.github/actions/validate-pr/validate_pr_test.sh
}

validate_tests
run_tests "$FILES"
Loading