Compare commits

...

9 Commits

Author SHA1 Message Date
jmiller 2312c95dba chore: sync notify.yml from Template-Generic [skip ci] 2026-07-05 00:04:08 +00:00
jmiller 7a06bcf403 chore: sync cleanup.yml from Template-Generic [skip ci] 2026-07-05 00:04:07 +00:00
gitea-actions[bot] a8baf355c4 chore: promote changelog [Unreleased] → [09.42.00] 2026-07-04 23:27:30 +00:00
gitea-actions[bot] 9520ce3bb8 chore(release): build 09.42.00 [skip ci]
Publish to Composer / Publish Package (release) Successful in 58s
2026-07-04 23:27:15 +00:00
jmiller 120dbe3be2 Merge pull request 'fix: branch_rename force-updates target ref instead of delete+recreate' (#335) from fix/promote-rc-force-update into main
Platform: mokocli CI / Gate 1: Code Quality (push) Successful in 2m0s
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (push) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: mokocli CI / CI Summary (push) Has been cancelled
2026-07-04 23:26:39 +00:00
jmiller 657e6013de chore: sync issue-branch.yml from Template-Generic [skip ci] 2026-07-04 23:25:48 +00:00
jmiller c7a26c1ce1 fix: promote-rc force-updates target ref instead of delete+recreate
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Failing after 9s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: PR Check / Secret Scan (pull_request) Successful in 13s
Universal: PR Check / Validate PR (pull_request) Successful in 9s
Generic: Repo Health / Access control (pull_request) Successful in 3s
Generic: Repo Health / Site Health (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 3s
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 44s
Generic: Project CI / Lint & Validate (pull_request) Successful in 1m7s
Platform: mokocli CI / Gate 1: Code Quality (pull_request) Successful in 1m52s
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Failing after 8m27s
Generic: Project CI / Tests (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokocli CI / CI Summary (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
Generic: Repo Health / Scripts governance (pull_request) Has been cancelled
Generic: Repo Health / Repository health (pull_request) Has been cancelled
Generic: Repo Health / Report: Scripts Governance (pull_request) Has been cancelled
Generic: Repo Health / Report: Repository Health (pull_request) Has been cancelled
branch_rename.php deleted the target branch then recreated it. When the target (rc) is a protected branch, the delete silently fails and the recreate returns HTTP 409 'branch already exists', breaking every PR-to-main promote-rc. Force-update the ref in place via PATCH git/refs/heads/{to} (sha+force) when the target exists; still create it when it doesn't. Requires the CI token to have force-push permission on the protected rc branch.
2026-07-04 18:25:43 -05:00
jmiller bdbabd9886 chore: sync auto-release.yml from Template-Generic [skip ci] 2026-07-04 23:25:41 +00:00
gitea-actions[bot] e061537404 chore: promote changelog [Unreleased] → [09.42.00] 2026-07-04 23:23:40 +00:00
6 changed files with 85 additions and 32 deletions
+35 -7
View File
@@ -95,7 +95,7 @@ jobs:
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer > /dev/null 2>&1
fi
rm -rf /tmp/mokocli
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/MokoCLI.git
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
cd /tmp/mokocli
composer install --no-dev --no-interaction --quiet
@@ -104,11 +104,39 @@ jobs:
- name: Rename branch to rc
run: |
php ${MOKO_CLI}/branch_rename.php \
--from "${{ github.event.pull_request.head.ref || 'dev' }}" --to rc \
--token "${{ secrets.MOKOGITEA_TOKEN }}" \
--api-base "${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" \
--pr "${{ github.event.pull_request.number }}"
API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
AUTH="Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}"
FROM="${{ github.event.pull_request.head.ref || 'dev' }}"
PR="${{ github.event.pull_request.number }}"
# Resolve the source branch HEAD commit.
SRC_JSON=$(curl -sf -H "$AUTH" "${API_BASE}/branches/${FROM}") \
|| { echo "::error::Source branch ${FROM} not found"; exit 1; }
SRC_SHA=$(printf '%s' "$SRC_JSON" | python3 -c "import sys, json; print(json.load(sys.stdin)['commit']['id'])" 2>/dev/null || true)
[ -n "$SRC_SHA" ] || { echo "::error::Could not resolve HEAD of ${FROM}"; exit 1; }
# Point rc at the source commit. If rc already exists (a protected branch that
# cannot be deleted), force-update its ref in place instead of delete+recreate:
# deleting a protected branch fails, which then makes the recreate return HTTP 409.
if curl -sf -o /dev/null -H "$AUTH" "${API_BASE}/branches/rc"; then
echo "rc exists - force-updating to ${FROM} (${SRC_SHA})"
curl -sf -X PATCH -H "$AUTH" -H "Content-Type: application/json" \
"${API_BASE}/git/refs/heads/rc" -d "{\"sha\":\"${SRC_SHA}\",\"force\":true}" \
|| { echo "::error::Failed to force-update rc (CI token needs force-push on the protected rc branch)"; exit 1; }
else
echo "Creating rc from ${FROM}"
curl -sf -X POST -H "$AUTH" -H "Content-Type: application/json" \
"${API_BASE}/branches" -d "{\"new_branch_name\":\"rc\",\"old_branch_name\":\"${FROM}\"}" \
|| { echo "::error::Failed to create rc from ${FROM}"; exit 1; }
fi
# Repoint the PR at rc, then delete the old source branch (non-fatal).
if [ -n "$PR" ]; then
curl -s -X PATCH -H "$AUTH" -H "Content-Type: application/json" \
"${API_BASE}/pulls/${PR}" -d '{"head":"rc"}' >/dev/null || true
fi
curl -s -X DELETE -H "$AUTH" "${API_BASE}/branches/${FROM}" >/dev/null || true
echo "Renamed ${FROM} -> rc"
- name: Checkout rc and configure git
run: |
@@ -218,7 +246,7 @@ jobs:
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer > /dev/null 2>&1
fi
rm -rf /tmp/mokocli
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/MokoCLI.git
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
cd /tmp/mokocli
composer install --no-dev --no-interaction --quiet
+1 -1
View File
@@ -50,7 +50,7 @@ jobs:
for BRANCH in $BRANCHES; do
# Skip protected branches
case "$BRANCH" in
main|master|develop|release/*|hotfix/*) continue ;;
main|master|dev|develop|rc|beta|alpha|release|release/*|production|stable|staging|hotfix/*|version/*) continue ;;
esac
# Check if branch is merged into main
+1 -1
View File
@@ -5,7 +5,7 @@
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: mokocli.Automation
# VERSION: 09.42.00
# VERSION: 01.00.00
# BRIEF: Auto-create feature branch when an issue is opened
name: "Universal: Issue Branch"
+3 -3
View File
@@ -15,9 +15,9 @@ name: "Universal: Notifications"
on:
workflow_run:
workflows:
- "Joomla Build & Release"
- "Joomla Extension CI"
- "Deploy"
- "Universal: Build & Release"
- "Joomla: Extension CI"
- "Generic: Project CI"
types:
- completed
+9 -4
View File
@@ -14,6 +14,15 @@ BRIEF: Release changelog
## [09.42.00] --- 2026-07-04
## [09.42.00] --- 2026-07-04
### Fixed
- branch_rename.php: force-update the target branch ref in place instead of delete+recreate, so `moko repo:rename-branch` works when the target (e.g. `rc`) is a protected branch that cannot be deleted — previously the delete silently failed and the recreate returned HTTP 409
## [09.42.00] --- 2026-07-04
## [09.42.00] --- 2026-07-04
## [09.41.00] --- 2026-07-04
## [09.41.00] --- 2026-07-04
@@ -22,7 +31,3 @@ BRIEF: Release changelog
- RecoverySuggestion.php: remove stray shebang and wrap an over-length line to satisfy PSR-12 (Gate 1 phpcs)
- phpstan-baseline.neon: baseline pre-existing PHPStan level-6 findings across `cli/`, `lib/`, and `validate/` so Gate 1 static analysis passes (type-annotation debt tracked, not silently ignored)
- client_provision.php: rename private `printSummary()` (and its dispatch entry) to `printProvisioningSummary()` to stop it colliding with `CliFramework::printSummary()` — a non-baselineable PHPStan override/covariance error
## [09.41.00] --- 2026-07-04
## [09.41.00] --- 2026-07-04
+36 -16
View File
@@ -64,26 +64,46 @@ class BranchRenameCli extends CliFramework
return 1;
}
// Step 2: Delete target branch if it already exists
// Step 2: Point the target branch at the source commit.
// If the target already exists (e.g. a protected `rc` branch that cannot be
// deleted), force-update its ref in place instead of delete+recreate: deleting a
// protected branch fails, which then makes the recreate return HTTP 409.
$sourceSha = '';
if (isset($check['body']['commit']['id']) && is_string($check['body']['commit']['id'])) {
$sourceSha = $check['body']['commit']['id'];
}
$targetCheck = $this->apiRequest('GET', "{$apiBase}/branches/{$to}", $headers);
if ($targetCheck['code'] === 200) {
echo "Target branch '{$to}' already exists — deleting\n";
echo "Target branch '{$to}' already exists - force-updating to {$from}
";
if (!$this->dryRun) {
$this->apiRequest('DELETE', "{$apiBase}/branches/{$to}", $headers);
if ($sourceSha === '') {
$this->log('ERROR', "Cannot resolve HEAD commit of source '{$from}'");
return 1;
}
$ref = $this->apiRequest('PATCH', "{$apiBase}/git/refs/heads/{$to}", $headers, [
'sha' => $sourceSha,
'force' => true,
]);
if ($ref['code'] < 200 || $ref['code'] >= 300) {
$this->log('ERROR', "Failed to force-update '{$to}': HTTP {$ref['code']} (needs force-push perm)");
$this->log('ERROR', json_encode($ref['body']));
return 1;
}
}
}
// Step 3: Create new branch from source
echo "Creating branch: {$to} (from {$from})\n";
if (!$this->dryRun) {
$create = $this->apiRequest('POST', "{$apiBase}/branches", $headers, [
'new_branch_name' => $to,
'old_branch_name' => $from,
]);
if ($create['code'] < 200 || $create['code'] >= 300) {
$this->log('ERROR', "Failed to create branch '{$to}': HTTP {$create['code']}");
$this->log('ERROR', json_encode($create['body']));
return 1;
} else {
echo "Creating branch: {$to} (from {$from})
";
if (!$this->dryRun) {
$create = $this->apiRequest('POST', "{$apiBase}/branches", $headers, [
'new_branch_name' => $to,
'old_branch_name' => $from,
]);
if ($create['code'] < 200 || $create['code'] >= 300) {
$this->log('ERROR', "Failed to create branch '{$to}': HTTP {$create['code']}");
$this->log('ERROR', json_encode($create['body']));
return 1;
}
}
}