Sandbox3
Jump to navigation
Jump to search
#!/bin/bash
export REPO="your-owner/your-repo"
export BRANCH="main"
export RULESET_NAME="Migrated Protection - $BRANCH"
# 1. Fetch Classic Branch Protection Rules
echo "Fetching classic branch protection for $BRANCH..."
CLASSIC_RULES=$(gh api repos/$REPO/branches/$BRANCH/protection -X GET 2>/dev/null)
if [ -z "$CLASSIC_RULES" ]; then
echo "No classic rules found or error accessing repo."
exit 1
fi
# 2. Extract and Map Protections
REQ_PR=$(echo "$CLASSIC_RULES" | jq -e '.required_pull_request_reviews' >/dev/null && echo "true" || echo "false")
REQ_APPROVALS=$(echo "$CLASSIC_RULES" | jq '.required_pull_request_reviews.required_approving_review_count // 1')
DISMISS_STALE=$(echo "$CLASSIC_RULES" | jq '.required_pull_request_reviews.dismiss_stale_reviews // false')
REQ_CODE_OWNERS=$(echo "$CLASSIC_RULES" | jq '.required_pull_request_reviews.require_code_owner_reviews // false')
REQ_CHECKS=$(echo "$CLASSIC_RULES" | jq -e '.required_status_checks' >/dev/null && echo "true" || echo "false")
REQ_STRICT=$(echo "$CLASSIC_RULES" | jq '.required_status_checks.strict // false')
CONTEXTS=$(echo "$CLASSIC_RULES" | jq '.required_status_checks.contexts // []')
ENFORCE_ADMINS=$(echo "$CLASSIC_RULES" | jq '.enforce_admins.enabled // false')
REQ_LINEAR=$(echo "$CLASSIC_RULES" | jq '.required_linear_history.enabled // false')
REQ_SIGNATURES=$(echo "$CLASSIC_RULES" | jq '.required_signatures.enabled // false')
# 3. Construct Ruleset Payload
PAYLOAD=$(jq -n \
--arg name "$RULESET_NAME" \
--arg target "$BRANCH" \
--argjson req_pr "$REQ_PR" \
--argjson approvals "$REQ_APPROVALS" \
--argjson dismiss_stale "$DISMISS_STALE" \
--argjson code_owners "$REQ_CODE_OWNERS" \
--argjson req_checks "$REQ_CHECKS" \
--argjson strict "$REQ_STRICT" \
--argjson contexts "$CONTEXTS" \
--argjson linear "$REQ_LINEAR" \
--argjson signatures "$REQ_SIGNATURES" \
'
{
"name": $name,
"target": "branch",
"enforcement": "active",
"conditions": {
"ref_name": {
"include": ["refs/heads/" + $target],
"exclude": []
}
},
"rules": [
{ "type": "deletion" },
{ "type": "non_fast_forward" }
]
}
| if $req_pr then .rules += [{
"type": "pull_request",
"parameters": {
"required_approving_review_count": $approvals,
"dismiss_stale_reviews_on_push": $dismiss_stale,
"require_code_owner_review": $code_owners,
"require_last_push_approval": false
}
}] else . end
| if $req_checks then .rules += [{
"type": "required_status_checks",
"parameters": {
"strict_required_status_checks_policy": $strict,
"required_status_checks": ($contexts | map({ context: ., integration_id: 0 }))
}
}] else . end
| if $linear then .rules += [{ "type": "required_linear_history" }] else . end
| if $signatures then .rules += [{ "type": "required_signatures" }] else . end
')
# 4. Create the New Ruleset
echo "Creating new Branch Ruleset..."
CREATE_RES=$(gh api repos/$REPO/rulesets -X POST --input - <<< "$PAYLOAD")
if [ $? -eq 0 ]; then
echo "Ruleset successfully created!"
# 5. Optional: Delete the classic rule if the ruleset succeeded
echo "To complete the migration, manually delete the classic rule or uncomment the line below:"
echo "# gh api repos/$REPO/branches/$BRANCH/protection -X DELETE"
else
echo "Failed to create ruleset."
fi