diff --git a/.github/workflows/branch-permissions.yml b/.github/workflows/branch-permissions.yml deleted file mode 100644 index 51ca28d8c..000000000 --- a/.github/workflows/branch-permissions.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: Branch Permission Check - -on: - pull_request: - types: [opened, synchronize, reopened] - -jobs: - check-branch-permissions: - runs-on: ubuntu-latest - steps: - - name: Check branch permissions - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - BRANCH_NAME="${{ github.head_ref }}" - ACTOR="${{ github.actor }}" - REPO_OWNER="${{ github.repository_owner }}" - - echo "Checking permissions for branch: $BRANCH_NAME" - echo "PR author: $ACTOR" - - # Check if user is an organization member - MEMBERSHIP_STATUS=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ - "https://api.github.com/orgs/$REPO_OWNER/members/$ACTOR" \ - -w "%{http_code}" -o /dev/null) - - IS_ORG_MEMBER=false - if [ "$MEMBERSHIP_STATUS" = "204" ]; then - IS_ORG_MEMBER=true - echo "✅ User $ACTOR is an organization member" - else - echo "â„šī¸ User $ACTOR is not an organization member (external contributor)" - fi - - # Check if branch requires org membership - REQUIRES_ORG_MEMBERSHIP=false - if [[ $BRANCH_NAME =~ ^feature/ ]] || [[ $BRANCH_NAME =~ ^release/ ]] || [[ $BRANCH_NAME =~ ^chore/ ]] || [[ $BRANCH_NAME =~ ^hotfix/ ]]; then - REQUIRES_ORG_MEMBERSHIP=true - fi - - # Validate permissions - if [ "$REQUIRES_ORG_MEMBERSHIP" = true ] && [ "$IS_ORG_MEMBER" = false ]; then - echo "❌ ERROR: Branch '$BRANCH_NAME' can only be created by CometChat organization members." - echo "" - echo "📋 External contributors should use:" - echo "- fix/ (for bug fixes, typos, broken links)" - echo "- docs/ (for documentation improvements)" - echo "- community/ (for examples, guides, general contributions)" - echo "" - echo "🔒 Organization members can use:" - echo "- feature/ (for new product features)" - echo "- release/ (for release preparation)" - echo "- chore/ (for maintenance tasks, dependency updates)" - echo "- hotfix/ (for critical production fixes)" - echo "" - echo "Please create a new branch with an appropriate prefix." - exit 1 - else - echo "✅ Branch permissions validated successfully" - fi diff --git a/.github/workflows/branch-push-protection.yml b/.github/workflows/branch-push-protection.yml new file mode 100644 index 000000000..3b54d970d --- /dev/null +++ b/.github/workflows/branch-push-protection.yml @@ -0,0 +1,108 @@ +name: Branch Push Protection + +on: + push: + branches-ignore: + - "main" + - "master" + +jobs: + validate-branch-push: + runs-on: ubuntu-latest + steps: + - name: Validate branch naming and permissions + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + BRANCH_NAME="${{ github.ref_name }}" + ACTOR="${{ github.actor }}" + REPO_OWNER="${{ github.repository_owner }}" + REPO_NAME="${{ github.event.repository.name }}" + + echo "🔍 Validating branch: $BRANCH_NAME" + echo "👤 Push author: $ACTOR" + + # Step 1: Validate branch naming convention + VALID_NAME=false + ALLOWED_PATTERNS=( + "^feature/" # New product features or major enhancements (org members only) + "^fix/" # Bug fixes, typo corrections, broken links (anyone) + "^docs/" # Documentation improvements and updates (anyone) + "^chore/" # Maintenance tasks, dependency updates (org members only) + "^community/" # General community contributions, examples (anyone) + "^release/" # Release preparation branches (org members only) + "^hotfix/" # Critical fixes for production issues (org members only) + ) + + for pattern in "${ALLOWED_PATTERNS[@]}"; do + pattern_name=$(echo "$pattern" | sed 's/\^//g' | sed 's/\///g') + if [[ $BRANCH_NAME =~ $pattern ]]; then + VALID_NAME=true + echo "✅ Branch name follows convention: $pattern_name" + break + fi + done + + if [ "$VALID_NAME" = false ]; then + echo "❌ Branch name '$BRANCH_NAME' does not follow naming convention." + echo "" + echo "īŋŊ Allowed branch prefixes:" + echo "- feature/ (new product features - org members only)" + echo "- fix/ (bug fixes, typos - anyone)" + echo "- docs/ (documentation improvements - anyone)" + echo "- chore/ (maintenance tasks - org members only)" + echo "- community/ (community contributions - anyone)" + echo "- release/ (release preparation - org members only)" + echo "- hotfix/ (critical fixes - org members only)" + echo "" + echo "💡 Please rename your branch to follow the convention." + exit 1 + fi + fi + + # Step 2: Check permissions for restricted branches + REQUIRES_ORG_MEMBERSHIP=false + if [[ $BRANCH_NAME =~ ^feature/ ]] || [[ $BRANCH_NAME =~ ^release/ ]] || [[ $BRANCH_NAME =~ ^chore/ ]] || [[ $BRANCH_NAME =~ ^hotfix/ ]]; then + REQUIRES_ORG_MEMBERSHIP=true + echo "🔒 Branch requires organization membership or collaborator access" + else + echo "📋 Branch is available to all contributors" + fi + + if [ "$REQUIRES_ORG_MEMBERSHIP" = true ]; then + # Check if user is an organization member + MEMBERSHIP_STATUS=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/orgs/$REPO_OWNER/members/$ACTOR" \ + -w "%{http_code}" -o /dev/null) + + # Check if user is a repository collaborator + COLLABORATOR_STATUS=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/collaborators/$ACTOR" \ + -w "%{http_code}" -o /dev/null) + + IS_AUTHORIZED=false + if [ "$MEMBERSHIP_STATUS" = "204" ]; then + IS_AUTHORIZED=true + echo "✅ User $ACTOR is an organization member" + elif [ "$COLLABORATOR_STATUS" = "204" ]; then + IS_AUTHORIZED=true + echo "✅ User $ACTOR is a repository collaborator" + else + echo "❌ User $ACTOR is not authorized for restricted branches" + fi + + if [ "$IS_AUTHORIZED" = false ]; then + echo "" + echo "đŸšĢ ERROR: You cannot push to restricted branch '$BRANCH_NAME'" + echo "" + echo "📋 External contributors should use:" + echo "- fix/ (for bug fixes, typos, broken links)" + echo "- docs/ (for documentation improvements)" + echo "- community/ (for examples, guides, general contributions)" + echo "" + echo "💡 Please create a new branch with an allowed prefix and push again." + exit 1 + fi + fi + + echo "✅ Branch validation successful - push authorized" diff --git a/.gitignore b/.gitignore index e43b0f988..e6aff5167 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ .DS_Store + +