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
6 changes: 6 additions & 0 deletions .github/workflows/cleanup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,11 @@ jobs:
exit 0
fi

# Safety: validate branch name matches expected Gitflow patterns
if [[ ! "$BRANCH" =~ ^(feature|release|hotfix|merge)/ ]]; then
echo "Skipping deletion — branch '$BRANCH' does not match a Gitflow pattern."
exit 0
fi

echo "Deleting branch '$BRANCH'..."
gh api -X DELETE "repos/$REPO/git/refs/heads/$BRANCH" || echo "Branch '$BRANCH' may have already been deleted."
7 changes: 6 additions & 1 deletion .github/workflows/feature.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,17 @@ jobs:
name: Run Checks
runs-on: ubuntu-latest
needs: validate
if: needs.validate.outputs.is_feature == 'true'
steps:
- name: Skip non-feature branches
if: needs.validate.outputs.is_feature != 'true'
run: echo "Not a feature branch — skipping CI checks."

- name: Checkout code
if: needs.validate.outputs.is_feature == 'true'
uses: actions/checkout@v4

- name: Placeholder - Add your build/test/lint steps here
if: needs.validate.outputs.is_feature == 'true'
run: |
echo "==========================================="
echo " Add your CI steps to this job."
Expand Down
41 changes: 30 additions & 11 deletions .github/workflows/hotfix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
BRANCH: ${{ github.head_ref }}
run: |
VERSION="${BRANCH#hotfix/}"
SEMVER_PATTERN='^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$'
SEMVER_PATTERN='^[0-9]+\.[0-9]+\.[0-9]+$'

echo "Hotfix version: $VERSION"

Expand Down Expand Up @@ -90,6 +90,7 @@ jobs:
env:
BRANCH: ${{ github.head_ref }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
run: |
VERSION="${BRANCH#hotfix/}"
TAG="v${VERSION}"
Expand All @@ -109,46 +110,64 @@ jobs:
echo "Branch '$MERGE_BRANCH_DEV' already exists, skipping."
else
echo "Creating back-merge branch '$MERGE_BRANCH_DEV'..."
git checkout -b "$MERGE_BRANCH_DEV" main
git checkout -b "$MERGE_BRANCH_DEV" origin/main
git push origin "$MERGE_BRANCH_DEV"
fi

EXISTING_PR=$(gh pr list --base develop --head "$MERGE_BRANCH_DEV" --json number --jq '.[0].number' || true)
if [[ -n "$EXISTING_PR" ]]; then
EXISTING_PR=$(gh pr list --repo "$REPO" --base develop --head "$MERGE_BRANCH_DEV" --json number --jq '.[0].number' 2>/dev/null || true)
if [[ -n "$EXISTING_PR" && "$EXISTING_PR" != "null" ]]; then
echo "Back-merge PR #$EXISTING_PR to develop already exists, skipping."
else
echo "Creating back-merge PR to develop..."
gh pr create \
if PR_URL=$(gh pr create \
--repo "$REPO" \
--base develop \
--head "$MERGE_BRANCH_DEV" \
--title "Merge hotfix $TAG into develop" \
--body "Automated back-merge of hotfix $TAG into develop. Resolve any conflicts and merge."
--body "Automated back-merge of hotfix $TAG into develop. Resolve any conflicts and merge." 2>&1); then
echo "Created back-merge PR: $PR_URL"
else
echo "::warning::Failed to create back-merge PR to develop: $PR_URL"
echo "Create it manually: https://github.com/$REPO/compare/develop...$MERGE_BRANCH_DEV"
fi
fi

# Detect active release branches and back-merge to them
RELEASE_BRANCHES=$(git for-each-ref --format='%(refname:short)' refs/remotes/origin/release/ | sed 's|^origin/||' || true)

for RELEASE in $RELEASE_BRANCHES; do
# Skip release branches that are already merged into main
if git merge-base --is-ancestor "origin/$RELEASE" origin/main 2>/dev/null; then
echo "Branch '$RELEASE' is already merged into main, skipping."
continue
fi

RELEASE_NAME=$(echo "$RELEASE" | tr '/' '-')
MERGE_BRANCH_REL="merge/hotfix-${TAG}-to-${RELEASE_NAME}"

if git ls-remote --exit-code origin "refs/heads/$MERGE_BRANCH_REL" &>/dev/null; then
echo "Branch '$MERGE_BRANCH_REL' already exists, skipping."
else
echo "Creating back-merge branch '$MERGE_BRANCH_REL' for '$RELEASE'..."
git checkout -b "$MERGE_BRANCH_REL" main
git checkout -b "$MERGE_BRANCH_REL" origin/main
git push origin "$MERGE_BRANCH_REL"
fi

EXISTING_REL_PR=$(gh pr list --base "$RELEASE" --head "$MERGE_BRANCH_REL" --json number --jq '.[0].number' || true)
if [[ -n "$EXISTING_REL_PR" ]]; then
EXISTING_REL_PR=$(gh pr list --repo "$REPO" --base "$RELEASE" --head "$MERGE_BRANCH_REL" --json number --jq '.[0].number' 2>/dev/null || true)
if [[ -n "$EXISTING_REL_PR" && "$EXISTING_REL_PR" != "null" ]]; then
echo "Back-merge PR #$EXISTING_REL_PR to '$RELEASE' already exists, skipping."
else
echo "Creating back-merge PR to '$RELEASE'..."
gh pr create \
if PR_URL=$(gh pr create \
--repo "$REPO" \
--base "$RELEASE" \
--head "$MERGE_BRANCH_REL" \
--title "Merge hotfix $TAG into $RELEASE" \
--body "Automated back-merge of hotfix $TAG into $RELEASE. Resolve any conflicts and merge."
--body "Automated back-merge of hotfix $TAG into $RELEASE. Resolve any conflicts and merge." 2>&1); then
echo "Created back-merge PR: $PR_URL"
else
echo "::warning::Failed to create back-merge PR to '$RELEASE': $PR_URL"
echo "Create it manually: https://github.com/$REPO/compare/$RELEASE...$MERGE_BRANCH_REL"
fi
fi
done
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
BRANCH: ${{ github.head_ref }}
run: |
VERSION="${BRANCH#release/}"
SEMVER_PATTERN='^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$'
SEMVER_PATTERN='^[0-9]+\.[0-9]+\.[0-9]+$'

echo "Release version: $VERSION"

Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/tag-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ jobs:
PREV_TAG: ${{ steps.meta.outputs.previous_tag }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Skip if release already exists (idempotent on re-run)
if gh release view "$TAG" &>/dev/null; then
echo "Release '$TAG' already exists, skipping."
exit 0
fi

FLAGS=(--generate-notes)
if [[ "$PRERELEASE" == "true" ]]; then
FLAGS+=(--prerelease)
Expand Down
11 changes: 9 additions & 2 deletions scripts/apply-rulesets.sh
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,15 @@ done
RELEASE_FILE="$RULESETS_DIR/release-branches.json"
if [[ -f "$RELEASE_FILE" ]]; then
echo ""
read -rp "Apply release branch protection? (recommended) [Y/n]: " APPLY_RELEASE
APPLY_RELEASE="${APPLY_RELEASE:-Y}"
if [[ -t 0 ]]; then
# Interactive mode: prompt the user
read -rp "Apply release branch protection? (recommended) [Y/n]: " APPLY_RELEASE
APPLY_RELEASE="${APPLY_RELEASE:-Y}"
else
# Non-interactive mode (piped/CI): apply by default
APPLY_RELEASE="Y"
echo "Non-interactive mode detected — applying release branch protection by default."
fi
if [[ "$APPLY_RELEASE" =~ ^[Yy]$ ]]; then
apply_ruleset "$RELEASE_FILE" || ERRORS=$((ERRORS + 1))
else
Expand Down