diff --git a/.mokogitea/workflows/auto-release.yml b/.mokogitea/workflows/auto-release.yml index ef09563..ffd47c8 100644 --- a/.mokogitea/workflows/auto-release.yml +++ b/.mokogitea/workflows/auto-release.yml @@ -456,6 +456,25 @@ jobs: echo "Dev branch reset from main (keeps dev ahead after release)" >> $GITHUB_STEP_SUMMARY + - name: "Step 12: Create version branch from main" + if: steps.version.outputs.skip != 'true' + continue-on-error: true + run: | + API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" + TOKEN="${{ secrets.GA_TOKEN }}" + VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" + BRANCH_NAME="version/${VERSION}" + MAIN_SHA=$(git rev-parse HEAD) + + # Delete old version branch if it exists (same version re-release) + curl -sf -X DELETE -H "Authorization: token ${TOKEN}" "${API_BASE}/branches/${BRANCH_NAME}" 2>/dev/null && echo "Deleted old ${BRANCH_NAME}" + + # Create version/XX.YY.ZZ from main + curl -sf -X POST -H "Authorization: token ${TOKEN}" -H "Content-Type: application/json" "${API_BASE}/branches" -d "{\"new_branch_name\":\"${BRANCH_NAME}\",\"old_branch_name\":\"main\"}" 2>/dev/null && echo "Created ${BRANCH_NAME} from main (${MAIN_SHA})" || echo "WARNING: ${BRANCH_NAME} creation failed" + + echo "Version branch created: ${BRANCH_NAME} (${MAIN_SHA})" >> $GITHUB_STEP_SUMMARY + + # -- Dolibarr post-release: Reset dev version ----------------------------- - name: "Post-release: Reset dev version" diff --git a/.mokogitea/workflows/branch-cleanup.yml b/.mokogitea/workflows/branch-cleanup.yml new file mode 100644 index 0000000..ef5feb2 --- /dev/null +++ b/.mokogitea/workflows/branch-cleanup.yml @@ -0,0 +1,48 @@ +# Copyright (C) 2026 Moko Consulting +# +# SPDX-License-Identifier: GPL-3.0-or-later +# +# FILE INFORMATION +# DEFGROUP: Gitea.Workflow +# INGROUP: MokoStandards.Universal +# REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform +# PATH: /.mokogitea/workflows/branch-cleanup.yml +# VERSION: 01.00.00 +# BRIEF: Delete feature branches after PR merge + +name: "Branch Cleanup" + +on: + pull_request: + types: [closed] + +env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true + +jobs: + cleanup: + name: Delete merged branch + runs-on: ubuntu-latest + if: >- + github.event.pull_request.merged == true && + github.event.pull_request.head.ref != 'dev' && + github.event.pull_request.head.ref != 'main' + + steps: + - name: Delete source branch + run: | + BRANCH="${{ github.event.pull_request.head.ref }}" + API="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}/api/v1/repos/${{ github.repository }}/branches" + ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('${BRANCH}', safe=''))") + + STATUS=$(curl -sf -o /dev/null -w "%{http_code}" -X DELETE \ + -H "Authorization: token ${{ secrets.GA_TOKEN }}" \ + "${API}/${ENCODED}" 2>/dev/null || true) + + if [ "$STATUS" = "204" ]; then + echo "Deleted branch: ${BRANCH}" >> $GITHUB_STEP_SUMMARY + elif [ "$STATUS" = "404" ]; then + echo "Branch already deleted: ${BRANCH}" >> $GITHUB_STEP_SUMMARY + else + echo "::warning::Failed to delete branch ${BRANCH} (HTTP ${STATUS})" + fi diff --git a/cli/version_bump.php b/cli/version_bump.php index 07c1c75..052bbcb 100644 --- a/cli/version_bump.php +++ b/cli/version_bump.php @@ -50,6 +50,7 @@ if (file_exists($readme)) { // -- 3. Fallback: Joomla manifest XML -- $manifestVersion = null; +$manifestSuffix = ''; $manifestFiles = array_merge( glob("{$root}/src/pkg_*.xml") ?: [], glob("{$root}/src/*.xml") ?: [], @@ -58,17 +59,17 @@ $manifestFiles = array_merge( glob("{$root}/*.xml") ?: [] ); -$manifestSuffix = ''; foreach ($manifestFiles as $xmlFile) { $xmlContent = file_get_contents($xmlFile); if (strpos($xmlContent, '') === false) { continue; } - if (preg_match('|(\d{2}\.\d{2}\.\d{2})(?:-([a-z]+))?|', $xmlContent, $xm)) { + if (preg_match('|(\d{2}\.\d{2}\.\d{2})(-[a-z]+)?|', $xmlContent, $xm)) { $candidate = $xm[1]; if ($manifestVersion === null || version_compare($candidate, $manifestVersion, '>')) { $manifestVersion = $candidate; - $manifestSuffix = isset($xm[2]) ? $xm[2] : ''; + // Preserve the suffix from the manifest (e.g. dev, rc) — strip leading dash + $manifestSuffix = ltrim($xm[2] ?? '', '-'); } } } @@ -128,8 +129,8 @@ if (file_exists($mokoManifest) && !empty($mokoContent)) { // -- Update README.md -- if (file_exists($readme) && !empty($readmeContent)) { $updated = preg_replace( - '/(VERSION:\s*)\d{2}\.\d{2}\.\d{2}/m', - '${1}' . $new, + '/(VERSION:\s*)\d{2}\.\d{2}\.\d{2}(?:-[a-z]+)?/m', + '${1}' . $newFull, $readmeContent, 1 ); @@ -173,8 +174,8 @@ $packageJsonFile = "{$root}/package.json"; if (file_exists($packageJsonFile)) { $pkgContent = file_get_contents($packageJsonFile); $updatedPkg = preg_replace( - '/("version"\s*:\s*")\d{2}\.\d{2}\.\d{2}(")/m', - '${1}' . $new . '${2}', + '/("version"\s*:\s*")\d{2}\.\d{2}\.\d{2}(?:-[a-z]+)?(")/m', + '${1}' . $newFull . '${2}', $pkgContent ); if ($updatedPkg !== $pkgContent) { @@ -188,8 +189,8 @@ $pyprojectFile = "{$root}/pyproject.toml"; if (file_exists($pyprojectFile)) { $pyContent = file_get_contents($pyprojectFile); $updatedPy = preg_replace( - '/^(version\s*=\s*")\d{2}\.\d{2}\.\d{2}(")/m', - '${1}' . $new . '${2}', + '/^(version\s*=\s*")\d{2}\.\d{2}\.\d{2}(?:-[a-z]+)?(")/m', + '${1}' . $newFull . '${2}', $pyContent ); if ($updatedPy !== $pyContent) { @@ -198,5 +199,6 @@ if (file_exists($pyprojectFile)) { } } -echo "{$old} -> {$newFull}\n"; +$oldFull = $suffix !== '' ? "{$old}-{$suffix}" : $old; +echo "{$oldFull} -> {$newFull}\n"; exit(0); diff --git a/cli/version_read.php b/cli/version_read.php index 4c26a10..bdc2350 100644 --- a/cli/version_read.php +++ b/cli/version_read.php @@ -54,7 +54,6 @@ if (file_exists($readme)) { // -- 3. Fallback: Joomla manifest XML -- $manifestVersion = null; -$manifestVersionSuffix = ''; $manifestFiles = array_merge( glob("{$root}/src/pkg_*.xml") ?: [], glob("{$root}/src/*.xml") ?: [], @@ -67,12 +66,12 @@ foreach ($manifestFiles as $xmlFile) { if (strpos($xmlContent, '') === false) { continue; } - if (preg_match('|(\d{2}\.\d{2}\.\d{2})(-[a-z]+)?|', $xmlContent, $xm)) { + if (preg_match('|(\d{2}\.\d{2}\.\d{2}(?:-[a-z]+)?)|', $xmlContent, $xm)) { $candidate = $xm[1]; - $candidateSuffix = isset($xm[2]) ? $xm[2] : ''; - if ($manifestVersion === null || version_compare($candidate, $manifestVersion, '>')) { + $candidateBase = preg_replace('/-[a-z]+$/', '', $candidate); + $currentBase = $manifestVersion ? preg_replace('/-[a-z]+$/', '', $manifestVersion) : null; + if ($currentBase === null || version_compare($candidateBase, $currentBase, '>')) { $manifestVersion = $candidate; - $manifestVersionSuffix = $candidateSuffix; } } } @@ -106,11 +105,9 @@ $candidates = array_filter([ ]); $version = null; -$versionSource = ''; foreach ($candidates as $candidate) { if ($version === null || version_compare($candidate, $version, '>')) { $version = $candidate; - $versionSource = ($candidate === $manifestVersion) ? 'manifest' : 'other'; } } @@ -119,11 +116,6 @@ if ($version === null) { exit(1); } -// Append suffix if the version came from a Joomla manifest with a suffix -if ($versionSource === 'manifest' && !empty($manifestVersionSuffix)) { - $version .= $manifestVersionSuffix; -} - // -- Backfill: if manifest.xml exists but lacks , insert it -- if (file_exists($mokoManifest)) { $content = file_get_contents($mokoManifest);