# Branch protection: lock, unlock, or merge-only # lock = no push, no merge | unlock = remove protection | merge-only = no direct push, PR merge allowed param( [string]$ApiToken = $env:GITEA_TOKEN, [string]$GiteaBaseUrl = "http://afe.git:3000", [string]$Owner, [string]$Repo, [string]$BranchName, [ValidateSet("lock", "unlock", "merge-only")] [string]$Action = "lock" ) $ErrorActionPreference = "Stop" $ConfigPath = Join-Path (Split-Path -Parent $MyInvocation.MyCommand.Path) "..\config.local.json" if (-not $ApiToken -and (Test-Path $ConfigPath)) { $cfg = Get-Content $ConfigPath -Raw | ConvertFrom-Json $ApiToken = $cfg.ApiToken if ($cfg.GiteaBaseUrl) { $GiteaBaseUrl = $cfg.GiteaBaseUrl } } if (-not $ApiToken) { Write-Host "Error: ApiToken required"; exit 1 } if (-not $Owner -or -not $Repo -or -not $BranchName) { Write-Host "Error: Owner, Repo, BranchName required"; exit 1 } $ApiBase = "$GiteaBaseUrl/api/v1" $ReposPath = "repos/$Owner/$Repo" $Headers = @{ "Authorization" = "token $ApiToken"; "Content-Type" = "application/json" } # Get existing protections $Existing = @() try { $r = Invoke-RestMethod -Uri "$ApiBase/$ReposPath/branch_protections" -Headers $Headers -Method Get $Existing = if ($r -is [array]) { $r } else { @($r) } } catch { if ($_.Exception.Response.StatusCode -eq 404) { Write-Host "Repo not found"; exit 1 } throw } $Match = $Existing | Where-Object { $_.rule_name -eq $BranchName -or $_.branch_name -eq $BranchName } | Select-Object -First 1 $RuleName = if ($Match) { if ($Match.rule_name) { $Match.rule_name } else { $BranchName } } else { $BranchName } # Delete existing rule if ($Match) { try { Invoke-RestMethod -Uri "$ApiBase/$ReposPath/branch_protections/$([uri]::EscapeDataString($RuleName))" -Headers $Headers -Method Delete | Out-Null } catch { Write-Host "Warning: Delete failed: $_" } } if ($Action -eq "unlock") { Write-Host "Branch $BranchName unlocked (protection removed)" exit 0 } # Create new rule $Body = @{ branch_name = $BranchName enable_push = if ($Action -eq "merge-only") { $false } else { $false } enable_push_whitelist = $false enable_merge_whitelist = if ($Action -eq "lock") { $true } else { $false } merge_whitelist_usernames = @() merge_whitelist_teams = @() block_on_rejected_reviews = $false block_on_outdated_branch = $false dismiss_stale_approvals = $false require_signed_commits = $false } | ConvertTo-Json try { Invoke-RestMethod -Uri "$ApiBase/$ReposPath/branch_protections" -Headers $Headers -Method Post -Body $Body | Out-Null Write-Host "Branch ${BranchName}: $Action applied" } catch { Write-Host "FAIL: $($_.Exception.Message)" exit 1 }