From c066c19069de8de01750afbfeab5c60859dde191 Mon Sep 17 00:00:00 2001 From: cadywang Date: Mon, 19 Oct 2026 17:42:47 +0800 Subject: [PATCH 1/2] repo: stop sending squash settings GitHub rejects Applying governance/repository-settings.json to a repository whose squash strategy is off failed with 422 no_squash_merge_strategy: the file still carried squash_merge_commit_message, squash_merge_commit_title and merge_commit_title, and GitHub refuses to set those for a strategy that is disabled. That is how this repository's live settings drifted from the file that is supposed to describe them -- the merge methods were the only part of the payload that ever landed. Send the three fields only when the matching strategy is enabled and the file still lists them, and drop them from the file (they describe a strategy this repository no longer offers). A squash-enabled fork can put them back and the script will send them again; the guard is what makes either choice work. Verified by running the guard against the committed file (no fields sent), a synthetic squash-enabled file (both squash fields sent) and a merge-commit-enabled file (merge_commit_title sent). Signed-off-by: cadywang --- CHANGELOG.md | 4 ++++ governance/repository-settings.json | 3 --- tools/create-github-repo.ps1 | 25 +++++++++++++++++-------- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d782d9..ec0ffe7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,10 @@ 端口转发占着(Windows 上更具体的 `127.0.0.1` 监听会盖过 agent 的 `0.0.0.0`),devctl 于是 连到了陌生人身上并永远等回复。现在两套自测**默认向系统要一个空闲端口** (`-Port` / `--port` 仍可指定),指定的端口已被占用时立刻报错退出(退出码 2)。 +- `tools/create-github-repo.ps1` 在 squash 关闭时会被 GitHub 拒掉(`no_squash_merge_strategy`, + 422)——治理文件里还留着 `squash_merge_commit_message` / `squash_merge_commit_title` / + `merge_commit_title`,而 GitHub 不允许给已关闭的合并策略设置这些字段。现在只发送 + **当前启用**且有值的字段,治理文件也不再保留这三项(本次对齐线上设置时就是这么被拒的)。 - `cli/devctl.ps1` 的连接没有超时(`devctl.py` 一直是 15 秒),端口不通时脚本会一直挂着。 现在两版一致:连不上或超时在 15 秒内报错退出(退出码 1),错误信息也去掉了 .NET 包装。 diff --git a/governance/repository-settings.json b/governance/repository-settings.json index 899d2a0..24d7e2f 100644 --- a/governance/repository-settings.json +++ b/governance/repository-settings.json @@ -12,9 +12,6 @@ "allow_rebase_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, - "squash_merge_commit_message": "COMMIT_MESSAGES", - "squash_merge_commit_title": "PR_TITLE", - "merge_commit_title": "PR_TITLE", "topics": [ "serial", "uart", "embedded", "debugging", "busybox", "serial-console", "remote-debugging", "yocto", "devctl" diff --git a/tools/create-github-repo.ps1 b/tools/create-github-repo.ps1 index 058b333..c7897d6 100644 --- a/tools/create-github-repo.ps1 +++ b/tools/create-github-repo.ps1 @@ -107,6 +107,20 @@ try { $settings = Get-Content -Raw "$root\governance\repository-settings.json" | ConvertFrom-Json $protection = Get-Content -Raw "$root\governance\branch-protection.json" | ConvertFrom-Json + # GitHub refuses the squash/merge title fields while that strategy is off + # ("no_squash_merge_strategy"), so only send the ones the enabled strategies + # can carry -- and only when the settings file still lists them. + $settingsKeys = @($settings.PSObject.Properties.Name) + $mergeFields = @{} + if ($settings.allow_squash_merge) { + foreach ($k in @('squash_merge_commit_message', 'squash_merge_commit_title')) { + if ($settingsKeys -contains $k) { $mergeFields[$k] = $settings.$k } + } + } + if ($settings.allow_merge_commit -and $settingsKeys -contains 'merge_commit_title') { + $mergeFields['merge_commit_title'] = $settings.merge_commit_title + } + # ---- 1. create repository ---- Write-Host "==> repository" $existing = $null @@ -116,7 +130,7 @@ try { if ($existing) { Write-Host " exists: $($existing.full_name) (visibility=$($existing.private))" try { - Invoke-Gh 'PATCH' "$api/repos/$Owner/$Repo" @{ + Invoke-Gh 'PATCH' "$api/repos/$Owner/$Repo" (@{ description = $settings.description has_issues = [bool]$settings.has_issues has_projects = [bool]$settings.has_projects @@ -127,10 +141,7 @@ try { allow_rebase_merge = [bool]$settings.allow_rebase_merge allow_auto_merge = [bool]$settings.allow_auto_merge delete_branch_on_merge = [bool]$settings.delete_branch_on_merge - squash_merge_commit_message = $settings.squash_merge_commit_message - squash_merge_commit_title = $settings.squash_merge_commit_title - merge_commit_title = $settings.merge_commit_title - } 'patch' | Out-Null + } + $mergeFields) 'patch' | Out-Null Write-Host ' settings updated' } catch { Write-Host ' warn: this token cannot update repository settings (needs administration:write)' @@ -146,14 +157,12 @@ try { has_projects = [bool]$settings.has_projects has_wiki = [bool]$settings.has_wiki auto_init = $false - squash_merge_commit_message = $settings.squash_merge_commit_message - squash_merge_commit_title = $settings.squash_merge_commit_title - merge_commit_title = $settings.merge_commit_title allow_squash_merge = [bool]$settings.allow_squash_merge allow_merge_commit = [bool]$settings.allow_merge_commit allow_rebase_merge = [bool]$settings.allow_rebase_merge delete_branch_on_merge = [bool]$settings.delete_branch_on_merge } + $body += $mergeFields Invoke-Gh 'POST' "$api/users/$Owner/repos" $body 'create' | Out-Null Write-Host " created $Owner/$Repo" } From d4e3501e970b590ac7366687bf31aa3d9f272598 Mon Sep 17 00:00:00 2001 From: cadywang Date: Mon, 19 Oct 2026 17:43:00 +0800 Subject: [PATCH 2/2] tools: keep a dry run from touching the local checkout -DryRun promises to print the API calls without touching GitHub, but the remote add/set-url and the "git branch -M main" ran before that guard: a dry run renamed whatever branch the maintainer happened to be on -- the branch he was reviewing, not the one being published. Move both into the branch that actually pushes. A dry run now reads the settings files, prints the calls and stops. Signed-off-by: cadywang --- CHANGELOG.md | 2 ++ tools/create-github-repo.ps1 | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec0ffe7..e9ad779 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,8 @@ 422)——治理文件里还留着 `squash_merge_commit_message` / `squash_merge_commit_title` / `merge_commit_title`,而 GitHub 不允许给已关闭的合并策略设置这些字段。现在只发送 **当前启用**且有值的字段,治理文件也不再保留这三项(本次对齐线上设置时就是这么被拒的)。 +- `tools/create-github-repo.ps1 -DryRun` 不再改动本地仓库:`git remote add/set-url` 与 + `git branch -M main` 移进了真正推送的分支——以前 dry-run 也会把**当前分支**改名成 `main`。 - `cli/devctl.ps1` 的连接没有超时(`devctl.py` 一直是 15 秒),端口不通时脚本会一直挂着。 现在两版一致:连不上或超时在 15 秒内报错退出(退出码 1),错误信息也去掉了 .NET 包装。 diff --git a/tools/create-github-repo.ps1 b/tools/create-github-repo.ps1 index c7897d6..682a2c9 100644 --- a/tools/create-github-repo.ps1 +++ b/tools/create-github-repo.ps1 @@ -183,10 +183,10 @@ try { # ---- 2. push ---- Write-Host "==> push" $remoteUrl = "https://github.com/$Owner/$Repo.git" - $has = (& git remote get-url origin 2>$null) - if ($LASTEXITCODE -ne 0) { & git remote add origin $remoteUrl } else { & git remote set-url origin $remoteUrl } - & git branch -M $BaseBranch if (-not $DryRun) { + $has = (& git remote get-url origin 2>$null) + if ($LASTEXITCODE -ne 0) { & git remote add origin $remoteUrl } else { & git remote set-url origin $remoteUrl } + & git branch -M $BaseBranch & git -c "http.extraheader=AUTHORIZATION: basic $([Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$($Owner):$Token")))" ` push --quiet -u origin $BaseBranch if ($LASTEXITCODE -ne 0) {