Skip to content
Merged
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
188 changes: 131 additions & 57 deletions scripts/sync.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,76 +4,158 @@ ORG="${ORG:-pheaz}"
POLICY_REPO="$ORG/.github"

WORKFLOW_PATH=".github/workflows/lint-pr.yml"
RULESET_NAME="Lint PR"
RULESET_NAME="${RULESET_NAME:-ruleset-baseline}"

API_VERSION="2026-03-10"

RULESET_ID=""
RULESET_ORIGINAL_ENFORCEMENT=""
RULESET_CHANGED=0


get_ruleset() {
RULESET_ID="$(
local matches
local match_count

matches="$(
gh api \
--paginate \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: $API_VERSION" \
"orgs/$ORG/rulesets?per_page=100" \
--jq ".[] | select(.name == \"$RULESET_NAME\") | .id" |
head -n1
--jq ".[] | select(.name == \"$RULESET_NAME\") | .id"
)" || return 1

if [ -z "$matches" ]; then
echo "Ruleset not found: $RULESET_NAME"
return 1
fi

match_count="$(
printf '%s\n' "$matches" |
awk 'NF { count++ } END { print count + 0 }'
)"

if [ -z "$RULESET_ID" ]; then
RULESET_ENFORCEMENT=""
return
if [ "$match_count" -ne 1 ]; then
echo "Expected exactly one ruleset named: $RULESET_NAME"
echo "Found: $match_count"
return 1
fi

RULESET_ENFORCEMENT="$(
RULESET_ID="$matches"

RULESET_ORIGINAL_ENFORCEMENT="$(
gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: $API_VERSION" \
"orgs/$ORG/rulesets/$RULESET_ID" \
--jq '.enforcement'
)"
)" || return 1

echo "Ruleset:"
echo " name: $RULESET_NAME"
echo " id: $RULESET_ID"
echo " enforcement: $RULESET_ORIGINAL_ENFORCEMENT"
echo
}


disable_ruleset() {
local enforcement

if [ -z "$RULESET_ID" ]; then
return
echo "Cannot disable ruleset: no ruleset ID"
return 1
fi

if [ "$RULESET_ENFORCEMENT" = "disabled" ]; then
return
if [ "$RULESET_ORIGINAL_ENFORCEMENT" = "disabled" ]; then
echo "Ruleset already disabled: $RULESET_NAME"
return 0
fi

echo "Temporarily disabling ruleset $RULESET_ID..."
echo "Temporarily disabling ruleset: $RULESET_NAME"

gh api \
--method PUT \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: $API_VERSION" \
"orgs/$ORG/rulesets/$RULESET_ID" \
-f enforcement=disabled \
>/dev/null
>/dev/null || return 1

RULESET_CHANGED=1

enforcement="$(
gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: $API_VERSION" \
"orgs/$ORG/rulesets/$RULESET_ID" \
--jq '.enforcement'
)" || return 1

if [ "$enforcement" != "disabled" ]; then
echo "Ruleset was not disabled."
return 1
fi

echo "Ruleset disabled."
echo
}


restore_ruleset() {
if [ -z "$RULESET_ID" ]; then
return
local enforcement

if [ "$RULESET_CHANGED" -ne 1 ]; then
return 0
fi

if [ -z "$RULESET_ENFORCEMENT" ]; then
return
if [ -z "$RULESET_ID" ]; then
return 0
fi

if [ "$RULESET_ENFORCEMENT" = "disabled" ]; then
return
if [ -z "$RULESET_ORIGINAL_ENFORCEMENT" ]; then
return 0
fi

echo "Restoring ruleset $RULESET_ID..."
echo
echo "Restoring ruleset: $RULESET_NAME"
echo " enforcement: $RULESET_ORIGINAL_ENFORCEMENT"

gh api \
--method PUT \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: $API_VERSION" \
"orgs/$ORG/rulesets/$RULESET_ID" \
-f enforcement="$RULESET_ENFORCEMENT" \
>/dev/null
-f enforcement="$RULESET_ORIGINAL_ENFORCEMENT" \
>/dev/null || {
echo "Failed to restore ruleset: $RULESET_NAME"
return 1
}

enforcement="$(
gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: $API_VERSION" \
"orgs/$ORG/rulesets/$RULESET_ID" \
--jq '.enforcement'
)" || return 1

if [ "$enforcement" != "$RULESET_ORIGINAL_ENFORCEMENT" ]; then
echo "Ruleset restoration could not be verified."
echo "Expected: $RULESET_ORIGINAL_ENFORCEMENT"
echo "Actual: $enforcement"
return 1
fi

RULESET_CHANGED=0

echo "Ruleset restored."
}


cleanup() {
restore_ruleset
}


Expand All @@ -92,7 +174,7 @@ sync_repository() {

if [ "$current_sha" = "$CANONICAL_SHA" ]; then
echo "Unchanged: $repo"
return
return 0
fi

if [ -n "$current_sha" ]; then
Expand All @@ -102,13 +184,13 @@ sync_repository() {
--method PUT \
-H "X-GitHub-Api-Version: $API_VERSION" \
"repos/$repo/contents/$WORKFLOW_PATH" \
-f message="ci: sync Lint PR workflow" \
-f message="ci: sync lint-pr workflow" \
-f content="$CANONICAL_CONTENT" \
-f branch="$branch" \
-f sha="$current_sha" \
>/dev/null

return
return $?
fi

echo "Creating: $repo"
Expand All @@ -117,14 +199,18 @@ sync_repository() {
--method PUT \
-H "X-GitHub-Api-Version: $API_VERSION" \
"repos/$repo/contents/$WORKFLOW_PATH" \
-f message="ci: sync Lint PR workflow" \
-f message="ci: sync lint-pr workflow" \
-f content="$CANONICAL_CONTENT" \
-f branch="$branch" \
>/dev/null
}


main() {
local failed_repos=()
local repo
local branch

command -v gh >/dev/null || {
echo "gh is required"
return 1
Expand Down Expand Up @@ -158,36 +244,29 @@ main() {
tr -d '\n'
)" || return 1

echo "Canonical:"
echo " $POLICY_REPO/$WORKFLOW_PATH"
echo " blob $CANONICAL_SHA"
echo

RULESET_ID=""
RULESET_ENFORCEMENT=""

get_ruleset || return 1
disable_ruleset || return 1

REPOSITORIES="$(
gh api \
--paginate \
-H "X-GitHub-Api-Version: $API_VERSION" \
"orgs/$ORG/repos?type=all&per_page=100" \
--jq '
.[]
| select(.archived == false)
| select(.archived == false and .fork == false)
| [.full_name, .default_branch]
| @tsv
'
)"
)" || return 1

if [ "$?" -ne 0 ]; then
restore_ruleset
return 1
fi
echo "Canonical:"
echo " $POLICY_REPO/$WORKFLOW_PATH"
echo " blob $CANONICAL_SHA"
echo

get_ruleset || return 1

FAILED_REPOS=""
trap cleanup EXIT

disable_ruleset || return 1

while IFS=$'\t' read -r repo branch; do
if [ -z "$repo" ]; then
Expand All @@ -203,24 +282,19 @@ main() {
continue
fi

sync_repository "$repo" "$branch"

if [ "$?" -ne 0 ]; then
FAILED_REPOS="$FAILED_REPOS
$repo"
if ! sync_repository "$repo" "$branch"; then
failed_repos+=("$repo")
fi
done <<< "$REPOSITORIES"

restore_ruleset
restore_ruleset || return 1

if [ "$?" -ne 0 ]; then
echo "Failed to restore ruleset $RULESET_ID"
return 1
fi
trap - EXIT

if [ -n "$FAILED_REPOS" ]; then
if [ "${#failed_repos[@]}" -gt 0 ]; then
echo
echo "Failed repositories:$FAILED_REPOS"
echo "Failed repositories:"
printf '%s\n' "${failed_repos[@]}"
return 1
fi

Expand Down
Loading