From 3a46a32dcae27e74bb442825923d6cb6272cc2f7 Mon Sep 17 00:00:00 2001 From: Ansel Robateau Date: Wed, 11 Dec 2024 21:45:05 -0600 Subject: [PATCH 1/3] test: add debugging --- .github/workflows/tag-tickets-with-release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tag-tickets-with-release.yml b/.github/workflows/tag-tickets-with-release.yml index f0616b9..042ce87 100644 --- a/.github/workflows/tag-tickets-with-release.yml +++ b/.github/workflows/tag-tickets-with-release.yml @@ -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: " From 4cf4e6f5c2ae522402062d6a1361b3f25d3b1c1c Mon Sep 17 00:00:00 2001 From: nastya-scherenkova-redshelf <108456718+nastya-scherenkova-redshelf@users.noreply.github.com> Date: Fri, 13 Dec 2024 08:00:54 +0300 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20gitHub=20actions=20w?= =?UTF-8?q?orkflow=20job=20to=20validate=20PR=20(#54)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 gitHub actions workflow job to validate PR ✅ Closes: CORE-1611 * test: 💍 add unit tests ✅ Closes: CORE-1611 * feat: 🎸 pr title must contain a jira ticket id ✅ Closes: CORE-1611 * feat: 🎸 a jira ticket with a semantic prefix and ticket id is valid ✅ Closes: CORE-1611 * feat: 🎸 fail on invalid release branch ✅ Closes: CORE-1611 * feat: 🎸 recognize mismatch between package.json and branch name ✅ Closes: CORE-1611 * feat: 🎸 use bash ✅ Closes: CORE-1611 * test: 💍 validate golden path ✅ Closes: CORE-1611 * feat: 🎸 check for release version greater than latest version ✅ Closes: CORE-1611 * feat: 🎸 check status when targeting release or hotfix branch ✅ Closes: CORE-1611 * feat: 🎸 add passed output ✅ Closes: CORE-1611 * ci: 🎡 use the validate-pr shared actino ✅ Closes: CORE-1611 * ci: 🎡 remove input parameter ✅ Closes: CORE-1611 * ci: 🎡 use composite action ✅ Closes: CORE-1611 * test: 💍 print all properties ✅ Closes: CORE-1611 * test: 💍 print all variables ✅ Closes: CORE-1611 * test: 💍 print all inputs ✅ Closes: CORE-1611 * ci: 🎡 change variables ✅ Closes: CORE-1611 * ci: 🎡 print the inputs ✅ Closes: CORE-1611 * ci: 🎡 use the inputs object ✅ Closes: CORE-1611 * feat: 🎸 support merging releases back to develop ✅ Closes: CORE-1611 * ci: 🎡 get action from main branch ✅ Closes: CORE-1611 --------- Co-authored-by: Ansel Robateau --- .github/actions/validate-pr/action.yml | 38 ++++ .github/actions/validate-pr/validate_pr.sh | 63 ++++++ .../actions/validate-pr/validate_pr_test.sh | 206 ++++++++++++++++++ .github/workflows/validate-pr.yml | 44 ++++ tooling/scripts/run_tests.sh | 6 + 5 files changed, 357 insertions(+) create mode 100644 .github/actions/validate-pr/action.yml create mode 100755 .github/actions/validate-pr/validate_pr.sh create mode 100755 .github/actions/validate-pr/validate_pr_test.sh create mode 100644 .github/workflows/validate-pr.yml diff --git a/.github/actions/validate-pr/action.yml b/.github/actions/validate-pr/action.yml new file mode 100644 index 0000000..f9e1157 --- /dev/null +++ b/.github/actions/validate-pr/action.yml @@ -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 }} diff --git a/.github/actions/validate-pr/validate_pr.sh b/.github/actions/validate-pr/validate_pr.sh new file mode 100755 index 0000000..ad58693 --- /dev/null +++ b/.github/actions/validate-pr/validate_pr.sh @@ -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." \ No newline at end of file diff --git a/.github/actions/validate-pr/validate_pr_test.sh b/.github/actions/validate-pr/validate_pr_test.sh new file mode 100755 index 0000000..f870655 --- /dev/null +++ b/.github/actions/validate-pr/validate_pr_test.sh @@ -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" + diff --git a/.github/workflows/validate-pr.yml b/.github/workflows/validate-pr.yml new file mode 100644 index 0000000..2949952 --- /dev/null +++ b/.github/workflows/validate-pr.yml @@ -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 }} + diff --git a/tooling/scripts/run_tests.sh b/tooling/scripts/run_tests.sh index 0e72f52..7a087d9 100755 --- a/tooling/scripts/run_tests.sh +++ b/tooling/scripts/run_tests.sh @@ -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" From f99c7838b9932f6593082def2126a3f7f7f25e91 Mon Sep 17 00:00:00 2001 From: Ansel Robateau Date: Thu, 12 Dec 2024 23:02:07 -0600 Subject: [PATCH 3/3] chore: update package version to v2.7.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e91f726..cd450b1 100644 --- a/package.json +++ b/package.json @@ -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",