Powershell github branch protection rules

Goal: we want to make sure that all repositories has reasonable settings configured (at very minimum we want to protect main branch from deletion)

$ErrorActionPreference = "Stop"

$token = '***********' # GitHub App Password

$query = @"
query GetPrivateRepositoryProtectionRules(`$after: String) {
  organization(login:"rabotaua") {
    repositories(first:100, privacy: PRIVATE, after: `$after) {
      pageInfo {
        endCursor
        hasNextPage
      }
      nodes {
        name
        id
        defaultBranchRef {
          name
        }
        branchProtectionRules(first:10) {
          nodes {
            id
            pattern
            allowsDeletions
            allowsForcePushes
            requiredApprovingReviewCount
            requiresApprovingReviews
            requiresCodeOwnerReviews
            requiresStatusChecks
          }
        }
      }
    }
  }
}
"@

$createRule = @"
mutation CreateRule(`$repositoryId: ID!, `$pattern: String!) {
  createBranchProtectionRule(input:{
    repositoryId: `$repositoryId
    pattern: `$pattern
    allowsDeletions: false
    allowsForcePushes: false
    requiredApprovingReviewCount: 1
    requiresApprovingReviews: true
    requiresCodeOwnerReviews: true
    requiresStatusChecks: true
  }) {
    branchProtectionRule {
      id
      pattern
      allowsDeletions
      allowsForcePushes
      requiredApprovingReviewCount
      requiresApprovingReviews
      requiresCodeOwnerReviews
      requiresStatusChecks
    }
  }
}
"@

$updateRule = @"
mutation UpdateRule(`$ruleId: ID!, `$pattern: String!) {
  updateBranchProtectionRule(input:{
    branchProtectionRuleId: `$ruleId
    pattern: `$pattern
    allowsDeletions: false
    allowsForcePushes: false
    requiredApprovingReviewCount: 1
    requiresApprovingReviews: true
    requiresCodeOwnerReviews: true
    requiresStatusChecks: true
  }) {
    branchProtectionRule {
      id
      pattern
      allowsDeletions
      allowsForcePushes
      requiredApprovingReviewCount
      requiresApprovingReviews
      requiresCodeOwnerReviews
      requiresStatusChecks
    }
  }
}
"@

$variables = @{
    after = $null
}

$repositories = @()
do {
    $res = Invoke-RestMethod -Method Post https://api.github.com/graphql -Headers @{Authorization = "Bearer $token"} -ContentType 'application/json' -Body (@{ query = $query; variables = $variables } | ConvertTo-Json)
    $repositories += $res.data.organization.repositories.nodes
    $variables.after = $res.data.organization.repositories.pageInfo.endCursor
} while ($res.data.organization.repositories.pageInfo.hasNextPage)



$repositoriesToSkip = @(
    'alliance',
    'test-owners'
)

foreach($repository in $repositories) {
    $name = $repository.name
    if ($repositoriesToSkip.Contains($name)) {
        Write-Host $name -ForegroundColor Cyan
        continue
    }

    $defaultBranchName = $repository.defaultBranchRef.name

    $rule = $null
    foreach($node in $repository.branchProtectionRules.nodes) {
        if ($node.pattern -eq $defaultBranchName) {
            $rule = $node
            break
        }
    }

    if ($rule) {
        $shouldUpdate = $false

        if ($rule.allowsDeletions) {
            $shouldUpdate = $true
        }

        if ($rule.allowsForcePushes) {
            $shouldUpdate = $true
        }

        if ($rule.requiredApprovingReviewCount -lt 1) {
            $shouldUpdate = $true
        }

        if (-not ($rule.requiresApprovingReviews)) {
            $shouldUpdate = $true
        }

        if (-not ($rule.requiresCodeOwnerReviews)) {
            $shouldUpdate = $true
        }

        if (-not ($rule.requiresStatusChecks)) {
            $shouldUpdate = $true
        }

        if (-not ($shouldUpdate)) {
            Write-Host $name -ForegroundColor Cyan
            continue
        }

        $variables = @{
            ruleId = $rule.id
            pattern = $defaultBranchName
        }
        $res = Invoke-RestMethod -Method Post https://api.github.com/graphql -Headers @{Authorization = "Bearer $token"} -ContentType 'application/json' -Body (@{ query = $updateRule; variables = $variables } | ConvertTo-Json)
        if ($res.errors) {
            $res.errors | select -ExpandProperty message
            Write-Host $name -ForegroundColor Red
        } else {
            Write-Host $name -ForegroundColor Yellow
        }
    } else {
        $variables = @{
            repositoryId = $repository.id
            pattern = $defaultBranchName
        }
        $res = Invoke-RestMethod -Method Post https://api.github.com/graphql -Headers @{Authorization = "Bearer $token"} -ContentType 'application/json' -Body (@{ query = $createRule; variables = $variables } | ConvertTo-Json)
        if ($res.errors) {
            $res.errors | select -ExpandProperty message
            Write-Host $name -ForegroundColor Red
        } else {
            Write-Host $name -ForegroundColor Green
        }
    }

    Start-Sleep -Seconds 1
}