From 954d519bfa2f876bc1250112d8abe39209f4c765 Mon Sep 17 00:00:00 2001 From: James Maes Date: Fri, 15 Aug 2025 16:56:50 -0500 Subject: [PATCH 1/2] feat: implement Git branching model and project templates - Add CODEOWNERS file for code ownership management - Add pull request template with testing checklist - Add bug report issue template - Add create-branch.sh script for branch naming conventions - Add setup-branch-protection.sh script for GitHub branch rules - Update release.sh script for release management - Implements feature/bugfix/release/hotfix branching workflow --- .github/CODEOWNERS | 16 + .github/ISSUE_TEMPLATE/bug_report.md | 25 ++ .github/pull_request_template.md | 45 +++ scripts/create-branch.sh | 131 ++++++++ scripts/release.sh | 461 +++++++++++++-------------- scripts/setup-branch-protection.sh | 73 +++++ 6 files changed, 518 insertions(+), 233 deletions(-) create mode 100644 .github/CODEOWNERS create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/pull_request_template.md create mode 100644 scripts/create-branch.sh create mode 100644 scripts/setup-branch-protection.sh diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..9220ec0 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,16 @@ +# Core firmware +/src/ @KofTwentyTwo +/include/ @KofTwentyTwo +/test/ @KofTwentyTwo +/platformio.ini @KofTwentyTwo + +# Build system +/CMakeLists.txt @KofTwentyTwo +/CMakePresets.json @KofTwentyTwo + +# Documentation +/README.md @KofTwentyTwo +/docs/ @KofTwentyTwo + +# GitHub Actions +/.github/ @KofTwentyTwo diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..f525f96 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,25 @@ +## Bug Description + + +## Steps to Reproduce +1. +2. +3. + +## Expected Behavior + + +## Actual Behavior + + +## Environment +- **OS:** [e.g., macOS, Windows, Linux] +- **CMake Version:** [e.g., 4.1.0] +- **PlatformIO Version:** [e.g., 6.1.0] +- **Arduino IDE Version:** [if applicable] + +## Additional Context + + +## Screenshots + diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..ec7e04d --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,45 @@ +## Summary + + +## Changes + +- [ ] +- [ ] +- [ ] + +## Testing + +- [ ] Native tests pass (`ctest --preset default`) +- [ ] PIO builds: simulide / uno_hw +- [ ] CMake configuration works locally +- [ ] All linting/formatting checks pass +- [ ] Manual testing completed (if applicable) + +## Risk / Rollback + +**Risk Level:** [Low/Medium/High] + +**Rollback Strategy:** + + +## Additional Information + + +## Checklist + +- [ ] Code follows project style guidelines +- [ ] Self-review completed +- [ ] Code is documented where necessary +- [ ] Tests are included for new functionality +- [ ] All existing tests pass +- [ ] Branch follows naming convention (`feature/`, `bugfix/`, `release/`, `hotfix/`) +- [ ] Branch is up to date with base branch +- [ ] Commit messages follow conventional commit format + +## Related Issues + +Closes # +Related to # + +## Screenshots (if applicable) + diff --git a/scripts/create-branch.sh b/scripts/create-branch.sh new file mode 100644 index 0000000..afea434 --- /dev/null +++ b/scripts/create-branch.sh @@ -0,0 +1,131 @@ +#!/bin/bash + +# Create Branch Script for Git Branching Model +# Usage: ./create-branch.sh [type] [name] + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Branch types and their source branches +declare -A BRANCH_TYPES=( + ["feature"]="develop" + ["bugfix"]="main" + ["release"]="develop" + ["hotfix"]="main" +) + +# Function to show usage +show_usage() { + echo -e "${BLUE}๐Ÿš€ Create Branch Script for Git Branching Model${NC}" + echo "==================================================" + echo "" + echo "Usage: $0 [type] [name]" + echo "" + echo "Branch Types:" + echo " feature - New features (from develop)" + echo " bugfix - Bug fixes (from main)" + echo " release - Release preparation (from develop)" + echo " hotfix - Urgent fixes (from main)" + echo "" + echo "Examples:" + echo " $0 feature arming-siren" + echo " $0 bugfix serial-monitor-timeout" + echo " $0 release 1.2.0" + echo " $0 hotfix 1.2.1-watchdog-crash" + echo "" + echo "Branch Naming Convention:" + echo " feature/arming-siren" + echo " bugfix/serial-monitor-timeout" + echo " release/1.2.0" + echo " hotfix/1.2.1-watchdog-crash" +} + +# Check if we have the right number of arguments +if [ $# -ne 2 ]; then + show_usage + exit 1 +fi + +BRANCH_TYPE="$1" +BRANCH_NAME="$2" + +# Validate branch type +if [[ ! ${BRANCH_TYPES[$BRANCH_TYPE]} ]]; then + echo -e "${RED}โŒ Invalid branch type: $BRANCH_TYPE${NC}" + echo "Valid types: ${!BRANCH_TYPES[@]}" + exit 1 +fi + +# Get source branch +SOURCE_BRANCH="${BRANCH_TYPES[$BRANCH_TYPE]}" + +# Create full branch name +FULL_BRANCH_NAME="$BRANCH_TYPE/$BRANCH_NAME" + +echo -e "${BLUE}๐Ÿš€ Creating new branch: $FULL_BRANCH_NAME${NC}" +echo "==================================================" +echo "" + +# Check if we're in a git repository +if ! git rev-parse --git-dir > /dev/null 2>&1; then + echo -e "${RED}โŒ Not in a git repository${NC}" + exit 1 +fi + +# Check if source branch exists locally +if ! git show-ref --verify --quiet refs/heads/$SOURCE_BRANCH; then + echo -e "${YELLOW}โš ๏ธ Source branch '$SOURCE_BRANCH' doesn't exist locally${NC}" + echo "Fetching from remote..." + git fetch origin $SOURCE_BRANCH:$SOURCE_BRANCH +fi + +# Check if source branch exists remotely +if ! git show-ref --verify --quiet refs/remotes/origin/$SOURCE_BRANCH; then + echo -e "${RED}โŒ Source branch '$SOURCE_BRANCH' doesn't exist remotely${NC}" + echo "Please ensure the source branch exists on GitHub first." + exit 1 +fi + +# Check if branch already exists +if git show-ref --verify --quiet refs/heads/$FULL_BRANCH_NAME; then + echo -e "${RED}โŒ Branch '$FULL_BRANCH_NAME' already exists locally${NC}" + exit 1 +fi + +if git show-ref --verify --quiet refs/remotes/origin/$FULL_BRANCH_NAME; then + echo -e "${RED}โŒ Branch '$FULL_BRANCH_NAME' already exists remotely${NC}" + exit 1 +fi + +# Create and switch to new branch +echo -e "${BLUE}๐Ÿ“‹ Creating branch from $SOURCE_BRANCH...${NC}" +git checkout $SOURCE_BRANCH + +echo -e "${BLUE}๐Ÿ”„ Updating $SOURCE_BRANCH from remote...${NC}" +git pull origin $SOURCE_BRANCH + +echo -e "${BLUE}๐ŸŒฟ Creating new branch: $FULL_BRANCH_NAME${NC}" +git checkout -b $FULL_BRANCH_NAME + +echo -e "${BLUE}๐Ÿ“ค Pushing branch to remote...${NC}" +git push -u origin $FULL_BRANCH_NAME + +echo "" +echo -e "${GREEN}โœ… Successfully created branch: $FULL_BRANCH_NAME${NC}" +echo "" +echo -e "${BLUE}๐Ÿ“š Next steps:${NC}" +echo " 1. Make your changes" +echo " 2. Commit and push: git add . && git commit -m 'your message' && git push" +echo " 3. Create a Pull Request to $SOURCE_BRANCH" +echo "" +echo -e "${BLUE}๐Ÿ”„ Branch flow:${NC}" +echo " $FULL_BRANCH_NAME โ†’ $SOURCE_BRANCH โ†’ main (via PR)" +echo "" +echo -e "${YELLOW}๐Ÿ’ก Tip: Use conventional commit messages:${NC}" +echo " feat: add arming siren functionality" +echo " fix: resolve serial monitor timeout issue" +echo " docs: update README with new features" diff --git a/scripts/release.sh b/scripts/release.sh index b53bcdd..5286214 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -1,9 +1,7 @@ #!/bin/bash -# Luke's Rocket Launcher - Release Helper Script -# This script helps create semantic versioned releases - -set -e +# Release Management Script for Git Branching Model +# Usage: ./release.sh [version] [type] # Colors for output RED='\033[0;31m' @@ -12,242 +10,239 @@ YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color -# Function to print colored output -print_status() { - echo -e "${GREEN}[INFO]${NC} $1" -} - -print_warning() { - echo -e "${YELLOW}[WARNING]${NC} $1" -} - -print_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -print_header() { - echo -e "${BLUE}=== $1 ===${NC}" -} - # Function to show usage show_usage() { - echo "Usage: $0 [OPTIONS]" + echo -e "${BLUE}๐Ÿš€ Release Management Script for Git Branching Model${NC}" + echo "========================================================" echo "" - echo "Options:" - echo " -v, --version VERSION Specify exact version (e.g., 1.0.0)" - echo " -t, --type TYPE Release type: patch, minor, major (default: patch)" - echo " -m, --message MESSAGE Custom release message" - echo " -p, --pre-release Mark as pre-release (alpha/beta/rc)" - echo " -d, --dry-run Show what would be done without doing it" - echo " -w, --watch Watch the release workflow progress" - echo " -h, --help Show this help message" + echo "Usage: $0 [version] [type]" + echo "" + echo "Types:" + echo " start - Start a new release (creates release branch)" + echo " finish - Finish a release (merges to main and develop, creates tag)" + echo " hotfix - Create a hotfix release (from main)" echo "" echo "Examples:" - echo " $0 --type minor # Auto-increment minor version" - echo " $0 --version 1.0.0 # Release specific version" - echo " $0 --type patch --message 'Bug fix release'" - echo " $0 --version 0.1.0 --pre-release # Create pre-release" - echo " $0 --version 1.0.0 --watch # Create release and watch progress" + echo " $0 1.2.0 start # Start release 1.2.0" + echo " $0 1.2.0 finish # Finish release 1.2.0" + echo " $0 1.2.1 hotfix # Create hotfix 1.2.1" echo "" - echo "Conventional Commit Messages:" - echo " feat: new feature" - echo " fix: bug fix" - echo " docs: documentation changes" - echo " style: code style changes" - echo " refactor: code refactoring" - echo " test: adding or updating tests" - echo " chore: maintenance tasks" + echo "Release Flow:" + echo " 1. ./release.sh 1.2.0 start # Creates release/1.2.0 from develop" + echo " 2. Make release changes (version, docs, etc.)" + echo " 3. ./release.sh 1.2.0 finish # Merges to main and develop, creates tag" } -# Parse command line arguments -VERSION="" -RELEASE_TYPE="patch" -MESSAGE="" -PRE_RELEASE=false -DRY_RUN=false -WATCH=false - -while [[ $# -gt 0 ]]; do - case $1 in - -v|--version) - VERSION="$2" - shift 2 - ;; - -t|--type) - RELEASE_TYPE="$2" - shift 2 - ;; - -m|--message) - MESSAGE="$2" - shift 2 - ;; - -p|--pre-release) - PRE_RELEASE=true - shift - ;; - -d|--dry-run) - DRY_RUN=true - shift - ;; - -w|--watch) - WATCH=true - shift - ;; - -h|--help) - show_usage - exit 0 - ;; - *) - echo "Unknown option: $1" - show_usage - exit 1 - ;; - esac -done - -# Validate release type -if [[ ! "$RELEASE_TYPE" =~ ^(patch|minor|major)$ ]]; then - print_error "Invalid release type: $RELEASE_TYPE" - print_error "Must be one of: patch, minor, major" - exit 1 -fi - -print_header "Luke's Rocket Launcher Release Helper" - -# Get current version from git tags -CURRENT_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") -CURRENT_VERSION=${CURRENT_TAG#v} - -print_status "Current version: $CURRENT_VERSION" - -# Calculate new version -if [[ -n "$VERSION" ]]; then - NEW_VERSION="$VERSION" - print_status "Using specified version: $NEW_VERSION" -else - IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION" - - case "$RELEASE_TYPE" in - "major") - NEW_VERSION="$((MAJOR + 1)).0.0" - print_status "Incrementing major version: $CURRENT_VERSION โ†’ $NEW_VERSION" - ;; - "minor") - NEW_VERSION="$MAJOR.$((MINOR + 1)).0" - print_status "Incrementing minor version: $CURRENT_VERSION โ†’ $NEW_VERSION" - ;; - "patch") - NEW_VERSION="$MAJOR.$MINOR.$((PATCH + 1))" - print_status "Incrementing patch version: $CURRENT_VERSION โ†’ $NEW_VERSION" - ;; - esac -fi - -NEW_TAG="v$NEW_VERSION" - -print_status "New version: $NEW_VERSION" -print_status "New tag: $NEW_TAG" - -# Check if working directory is clean -if [[ -n $(git status --porcelain) ]]; then - print_warning "Working directory is not clean. Please commit or stash changes first." - git status --short - exit 1 -fi - -# Check if tag already exists -if git tag -l | grep -q "^$NEW_TAG$"; then - print_error "Tag $NEW_TAG already exists!" - exit 1 -fi - -# Show what will be done -print_header "Release Plan" -echo "1. Create tag: $NEW_TAG" -if [[ "$PRE_RELEASE" == true ]]; then - echo " โš ๏ธ This will be marked as a PRE-RELEASE" -fi -echo "2. Push tag to remote" -echo "3. Trigger GitHub Actions release workflow" -echo "4. Create GitHub release with firmware files" -echo "5. Package firmware files for download" - -if [[ "$DRY_RUN" == true ]]; then - print_status "DRY RUN - No changes will be made" - exit 0 -fi - -# Confirm release -echo "" -read -p "Proceed with release? (y/N): " -n 1 -r -echo "" -if [[ ! $REPLY =~ ^[Yy]$ ]]; then - print_status "Release cancelled" - exit 0 -fi - -# Create and push tag -print_status "Creating tag $NEW_TAG..." -if [[ "$PRE_RELEASE" == true ]]; then - TAG_MESSAGE="Pre-release $NEW_TAG - -$MESSAGE - -โš ๏ธ This is a pre-release version. Not recommended for production use." -else - TAG_MESSAGE="Release $NEW_TAG - -$MESSAGE" -fi - -git tag -a "$NEW_TAG" -m "$TAG_MESSAGE" - -print_status "Pushing tag to remote..." -git push origin "$NEW_TAG" - -print_header "Release Complete!" -if [[ "$PRE_RELEASE" == true ]]; then - print_warning "Tag $NEW_TAG has been created and pushed as a PRE-RELEASE" - print_warning "Remember to mark this as a pre-release in GitHub after the workflow completes" -else - print_status "Tag $NEW_TAG has been created and pushed" -fi -print_status "GitHub Actions will automatically:" -echo " โ€ข Build and test the firmware" -echo " โ€ข Create a GitHub release" -echo " โ€ข Package firmware files for download" -echo "" -print_status "Monitor progress at: https://github.com/KofTwentyTwo/Lukes-Rocket-Launcher/actions" -print_status "Download firmware at: https://github.com/KofTwentyTwo/Lukes-Rocket-Launcher/releases" - -# Watch workflow if requested -if [[ "$WATCH" == true ]]; then - echo "" - print_status "Watching release workflow progress..." - print_status "Looking for workflow triggered by tag $NEW_TAG..." - - # Wait a moment for the workflow to start - sleep 3 - - # Find the workflow run for this tag using JSON output for reliable parsing - WORKFLOW_RUN=$(gh run list --workflow="Build and Test Arduino Firmware" --limit 10 --json databaseId,headBranch | jq -r ".[] | select(.headBranch == \"$NEW_TAG\") | .databaseId" | head -1) - - if [[ -n "$WORKFLOW_RUN" ]]; then - print_status "Found workflow run: $WORKFLOW_RUN" - print_status "Starting workflow monitor..." - echo "" - - # Watch the workflow - gh run watch "$WORKFLOW_RUN" - - # Show final status - echo "" - print_status "Workflow completed! Final status:" - gh run view "$WORKFLOW_RUN" --json status,conclusion,url --jq '.status + " (" + .conclusion + ")"' - echo "" - print_status "View details at: $(gh run view "$WORKFLOW_RUN" --json url --jq '.url')" - else - print_warning "Could not find workflow run for tag $NEW_TAG" - print_status "You can manually check at: https://github.com/KofTwentyTwo/Lukes-Rocket-Launcher/actions" +# Function to validate version format +validate_version() { + local version=$1 + if [[ ! $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo -e "${RED}โŒ Invalid version format: $version${NC}" + echo "Version must be in format: X.Y.Z (e.g., 1.2.0)" + exit 1 fi +} + +# Function to check if we're in a git repository +check_git_repo() { + if ! git rev-parse --git-dir > /dev/null 2>&1; then + echo -e "${RED}โŒ Not in a git repository${NC}" + exit 1 + fi +} + +# Function to check if branch exists +branch_exists() { + local branch=$1 + git show-ref --verify --quiet refs/heads/$branch || \ + git show-ref --verify --quiet refs/remotes/origin/$branch +} + +# Function to start a release +start_release() { + local version=$1 + local release_branch="release/$version" + + echo -e "${BLUE}๐Ÿš€ Starting release $version${NC}" + echo "==================================" + + # Check if release branch already exists + if branch_exists $release_branch; then + echo -e "${RED}โŒ Release branch $release_branch already exists${NC}" + exit 1 + fi + + # Ensure we're on develop and it's up to date + if [[ $(git branch --show-current) != "develop" ]]; then + echo -e "${BLUE}๐Ÿ“‹ Switching to develop branch...${NC}" + git checkout develop + fi + + echo -e "${BLUE}๐Ÿ”„ Updating develop from remote...${NC}" + git pull origin develop + + echo -e "${BLUE}๐ŸŒฟ Creating release branch: $release_branch${NC}" + git checkout -b $release_branch + + echo -e "${BLUE}๐Ÿ“ค Pushing release branch to remote...${NC}" + git push -u origin $release_branch + + echo "" + echo -e "${GREEN}โœ… Release $version started successfully!${NC}" + echo "" + echo -e "${BLUE}๐Ÿ“š Next steps:${NC}" + echo " 1. Update version numbers in code" + echo " 2. Update CHANGELOG.md" + echo " 3. Update documentation" + echo " 4. Test thoroughly" + echo " 5. Run: $0 $version finish" +} + +# Function to finish a release +finish_release() { + local version=$1 + local release_branch="release/$version" + local tag="v$version" + + echo -e "${BLUE}๐ŸŽฏ Finishing release $version${NC}" + echo "==================================" + + # Check if we're on the release branch + if [[ $(git branch --show-current) != $release_branch ]]; then + echo -e "${BLUE}๐Ÿ“‹ Switching to release branch...${NC}" + git checkout $release_branch + fi + + # Ensure release branch is up to date + echo -e "${BLUE}๐Ÿ”„ Updating release branch from remote...${NC}" + git pull origin $release_branch + + # Check if there are uncommitted changes + if ! git diff-index --quiet HEAD --; then + echo -e "${YELLOW}โš ๏ธ You have uncommitted changes. Please commit or stash them first.${NC}" + git status --short + exit 1 + fi + + echo -e "${BLUE}๐Ÿ” Checking if tag already exists...${NC}" + if git tag -l | grep -q "^$tag$"; then + echo -e "${RED}โŒ Tag $tag already exists${NC}" + exit 1 + fi + + echo -e "${BLUE}๐Ÿ“‹ Switching to main branch...${NC}" + git checkout main + git pull origin main + + echo -e "${BLUE}๐Ÿ”„ Merging release branch to main...${NC}" + git merge --no-ff $release_branch -m "Release $version" + + echo -e "${BLUE}๐Ÿท๏ธ Creating tag $tag...${NC}" + git tag -a $tag -m "Release $version" + + echo -e "${BLUE}๐Ÿ“ค Pushing main and tag to remote...${NC}" + git push origin main + git push origin $tag + + echo -e "${BLUE}๐Ÿ“‹ Switching to develop branch...${NC}" + git checkout develop + git pull origin develop + + echo -e "${BLUE}๐Ÿ”„ Merging release branch to develop...${NC}" + git merge --no-ff $release_branch -m "Merge release $version into develop" + + echo -e "${BLUE}๐Ÿ“ค Pushing develop to remote...${NC}" + git push origin develop + + echo -e "${BLUE}๐Ÿงน Cleaning up release branch...${NC}" + git branch -d $release_branch + git push origin --delete $release_branch + + echo "" + echo -e "${GREEN}โœ… Release $version completed successfully!${NC}" + echo "" + echo -e "${BLUE}๐ŸŽ‰ What was accomplished:${NC}" + echo " โœ… Release branch merged to main" + echo " โœ… Tag $tag created and pushed" + echo " โœ… Release branch merged to develop" + echo " โœ… Release branch cleaned up" + echo "" + echo -e "${BLUE}๐Ÿ“š Next steps:${NC}" + echo " 1. Create GitHub Release from tag $tag" + echo " 2. Deploy to production" + echo " 3. Announce the release" +} + +# Function to create a hotfix +create_hotfix() { + local version=$1 + local hotfix_branch="hotfix/$version" + local tag="v$version" + + echo -e "${BLUE}๐Ÿšจ Creating hotfix $version${NC}" + echo "================================" + + # Check if hotfix branch already exists + if branch_exists $hotfix_branch; then + echo -e "${RED}โŒ Hotfix branch $hotfix_branch already exists${NC}" + exit 1 + fi + + # Ensure we're on main and it's up to date + if [[ $(git branch --show-current) != "main" ]]; then + echo -e "${BLUE}๐Ÿ“‹ Switching to main branch...${NC}" + git checkout main + fi + + echo -e "${BLUE}๐Ÿ”„ Updating main from remote...${NC}" + git pull origin main + + echo -e "${BLUE}๐ŸŒฟ Creating hotfix branch: $hotfix_branch${NC}" + git checkout -b $hotfix_branch + + echo -e "${BLUE}๐Ÿ“ค Pushing hotfix branch to remote...${NC}" + git push -u origin $hotfix_branch + + echo "" + echo -e "${GREEN}โœ… Hotfix $version created successfully!${NC}" + echo "" + echo -e "${BLUE}๐Ÿ“š Next steps:${NC}" + echo " 1. Fix the urgent issue" + echo " 2. Test thoroughly" + echo " 3. Commit and push changes" + echo " 4. Create PR to main" + echo " 5. After merge, run: $0 $version finish" +} + +# Main script logic +if [ $# -ne 2 ]; then + show_usage + exit 1 fi + +VERSION=$1 +TYPE=$2 + +# Validate version format +validate_version $VERSION + +# Check if we're in a git repository +check_git_repo + +# Execute based on type +case $TYPE in + "start") + start_release $VERSION + ;; + "finish") + finish_release $VERSION + ;; + "hotfix") + create_hotfix $VERSION + ;; + *) + echo -e "${RED}โŒ Invalid type: $TYPE${NC}" + echo "Valid types: start, finish, hotfix" + exit 1 + ;; +esac diff --git a/scripts/setup-branch-protection.sh b/scripts/setup-branch-protection.sh new file mode 100644 index 0000000..bc4a978 --- /dev/null +++ b/scripts/setup-branch-protection.sh @@ -0,0 +1,73 @@ +#!/bin/bash + +# Setup Branch Protection Rules for Git Branching Model +# Run this script to configure branch protection on GitHub + +echo "๐Ÿš€ Setting up Branch Protection Rules for Git Branching Model" +echo "==============================================================" +echo "" + +# Check if gh CLI is installed +if ! command -v gh &> /dev/null; then + echo "โŒ GitHub CLI (gh) is not installed. Please install it first:" + echo " https://cli.github.com/" + exit 1 +fi + +# Check if authenticated +if ! gh auth status &> /dev/null; then + echo "โŒ Not authenticated with GitHub. Please run: gh auth login" + exit 1 +fi + +REPO="KofTwentyTwo/Lukes-Rocket-Launcher" + +echo "๐Ÿ“‹ Setting up branch protection for: $REPO" +echo "" + +# Main branch protection +echo "๐Ÿ”’ Setting up MAIN branch protection..." +gh api repos/$REPO/branches/main/protection \ + --method PUT \ + --field required_status_checks='{"strict":true,"contexts":["Build and Test Arduino Firmware"]}' \ + --field enforce_admins=true \ + --field required_pull_request_reviews='{"required_approving_review_count":1,"dismiss_stale_reviews":true,"require_code_owner_reviews":false}' \ + --field restrictions=null + +if [ $? -eq 0 ]; then + echo "โœ… MAIN branch protection configured" +else + echo "โŒ Failed to configure MAIN branch protection" +fi + +echo "" + +# Develop branch protection (optional, but recommended) +echo "๐Ÿ”’ Setting up DEVELOP branch protection..." +gh api repos/$REPO/branches/develop/protection \ + --method PUT \ + --field required_status_checks='{"strict":true,"contexts":["Build and Test Arduino Firmware"]}' \ + --field enforce_admins=false \ + --field required_pull_request_reviews='{"required_approving_review_count":1,"dismiss_stale_reviews":true,"require_code_owner_reviews":false}' \ + --field restrictions=null + +if [ $? -eq 0 ]; then + echo "โœ… DEVELOP branch protection configured" +else + echo "โŒ Failed to configure DEVELOP branch protection" +fi + +echo "" +echo "๐ŸŽฏ Branch Protection Setup Complete!" +echo "" +echo "๐Ÿ“š Next steps:" +echo " 1. Create feature branches from develop: git checkout -b feature/your-feature develop" +echo " 2. Create bugfix branches from main: git checkout -b bugfix/your-bug main" +echo " 3. Create release branches from develop: git checkout -b release/1.0.0 develop" +echo " 4. Create hotfix branches from main: git checkout -b hotfix/1.0.1 main" +echo "" +echo "๐Ÿ”„ Workflow:" +echo " Feature โ†’ Develop โ†’ Main (via PR)" +echo " Bugfix โ†’ Main (via PR)" +echo " Release โ†’ Develop โ†’ Main (via PR)" +echo " Hotfix โ†’ Main (via PR)" -- 2.54.0 From 07adc4a0412d4901a8c6ca0d42e02db0dadf4702 Mon Sep 17 00:00:00 2001 From: James Maes Date: Fri, 15 Aug 2025 17:00:15 -0500 Subject: [PATCH 2/2] fix: correct GitHub API JSON formatting in branch protection script --- scripts/setup-branch-protection.sh | 38 +++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 8 deletions(-) mode change 100644 => 100755 scripts/setup-branch-protection.sh diff --git a/scripts/setup-branch-protection.sh b/scripts/setup-branch-protection.sh old mode 100644 new mode 100755 index bc4a978..8a631b6 --- a/scripts/setup-branch-protection.sh +++ b/scripts/setup-branch-protection.sh @@ -29,10 +29,21 @@ echo "" echo "๐Ÿ”’ Setting up MAIN branch protection..." gh api repos/$REPO/branches/main/protection \ --method PUT \ - --field required_status_checks='{"strict":true,"contexts":["Build and Test Arduino Firmware"]}' \ - --field enforce_admins=true \ - --field required_pull_request_reviews='{"required_approving_review_count":1,"dismiss_stale_reviews":true,"require_code_owner_reviews":false}' \ - --field restrictions=null + --input - << EOF +{ + "required_status_checks": { + "strict": true, + "contexts": ["Build and Test Arduino Firmware"] + }, + "enforce_admins": true, + "required_pull_request_reviews": { + "required_approving_review_count": 1, + "dismiss_stale_reviews": true, + "require_code_owner_reviews": false + }, + "restrictions": null +} +EOF if [ $? -eq 0 ]; then echo "โœ… MAIN branch protection configured" @@ -46,10 +57,21 @@ echo "" echo "๐Ÿ”’ Setting up DEVELOP branch protection..." gh api repos/$REPO/branches/develop/protection \ --method PUT \ - --field required_status_checks='{"strict":true,"contexts":["Build and Test Arduino Firmware"]}' \ - --field enforce_admins=false \ - --field required_pull_request_reviews='{"required_approving_review_count":1,"dismiss_stale_reviews":true,"require_code_owner_reviews":false}' \ - --field restrictions=null + --input - << EOF +{ + "required_status_checks": { + "strict": true, + "contexts": ["Build and Test Arduino Firmware"] + }, + "enforce_admins": false, + "required_pull_request_reviews": { + "required_approving_review_count": 1, + "dismiss_stale_reviews": true, + "require_code_owner_reviews": false + }, + "restrictions": null +} +EOF if [ $? -eq 0 ]; then echo "โœ… DEVELOP branch protection configured" -- 2.54.0