From 7c76f2c8c152530d382c70a921e241d9831c3c30 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sat, 30 May 2026 09:34:27 -0500 Subject: [PATCH 1/2] refactor(workflows): replace all inline release steps with single CLI call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The release job now calls release_publish.php --bump minor --stability stable which handles: version bump, platform set, badge update, changelog, package build, release creation, lesser stream copies, updates.xml, and sync — all in one CLI tool. Removed ~150 lines of inline bash that duplicated CLI tool logic. Authored-by: Moko Consulting Co-Authored-By: Claude Opus 4.6 (1M context) --- .mokogitea/workflows/auto-release.yml | 209 +------------------------- 1 file changed, 2 insertions(+), 207 deletions(-) diff --git a/.mokogitea/workflows/auto-release.yml b/.mokogitea/workflows/auto-release.yml index 663c4aa..1227ff8 100644 --- a/.mokogitea/workflows/auto-release.yml +++ b/.mokogitea/workflows/auto-release.yml @@ -150,215 +150,10 @@ jobs: composer install --no-dev --no-interaction --quiet - # -- PLATFORM DETECTION --------------------------------------------------- - - name: Detect platform - id: platform - run: | - php /tmp/moko-platform-api/cli/manifest_read.php --path . --github-output - MANIFEST=$(find . -maxdepth 3 -name "*.xml" ! -path "./.git/*" -exec grep -l '/dev/null | head -1 || true) - MOD_FILE=$(find . -maxdepth 4 -name "mod*.class.php" ! -path "./.git/*" -exec grep -l 'extends DolibarrModules' {} \; 2>/dev/null | head -1 || true) - echo "manifest=${MANIFEST}" >> "$GITHUB_OUTPUT" - echo "mod_file=${MOD_FILE}" >> "$GITHUB_OUTPUT" - - - name: "Step 1: Read version" - id: version - run: | - VERSION=$(php /tmp/moko-platform-api/cli/version_read.php --path .) - if [ -z "$VERSION" ]; then - echo "::error::No VERSION in README.md" - echo "skip=true" >> "$GITHUB_OUTPUT" - exit 0 - fi - # version_set_platform strips suffixes internally when --stability stable - MAJOR=$(echo "$VERSION" | cut -d. -f1 | sed 's/-.*//') - echo "version=${VERSION}" >> "$GITHUB_OUTPUT" - echo "release_tag=stable" >> "$GITHUB_OUTPUT" - echo "skip=false" >> "$GITHUB_OUTPUT" - echo "branch=main" >> "$GITHUB_OUTPUT" - - # -- CHECK FOR RC PROMOTION ------------------------------------------------ - - name: "Check for RC release" - id: rc - if: steps.version.outputs.skip != 'true' - run: | - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" - RC_JSON=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ - "${API_BASE}/releases/tags/release-candidate" 2>/dev/null || echo "{}") - RC_ID=$(echo "$RC_JSON" | php -r "\$d=json_decode(file_get_contents('php://stdin'),true); echo \$d['id'] ?? '';" 2>/dev/null || true) - - if [ -n "$RC_ID" ] && [ "$RC_ID" != "None" ] && [ "$RC_ID" != "" ]; then - echo "promote=true" >> "$GITHUB_OUTPUT" - echo "release_id=${RC_ID}" >> "$GITHUB_OUTPUT" - echo "::notice::RC release found (id: ${RC_ID}) — will promote to stable" - else - echo "promote=false" >> "$GITHUB_OUTPUT" - echo "::notice::No RC release — full build pipeline" - fi - - - name: "Step 1b: Minor bump version" - id: bump - if: >- - steps.version.outputs.skip != 'true' && - steps.rc.outputs.promote != 'true' - run: | - MOKO_API="/tmp/moko-platform-api/cli" - php ${MOKO_API}/version_bump.php --path . --minor 2>&1 || true - VERSION=$(php ${MOKO_API}/version_read.php --path .) - # version_set_platform handles suffix stripping — just pass clean base version - echo "version=${VERSION}" >> "$GITHUB_OUTPUT" - echo "Bumped to: ${VERSION}" - - - name: Check if already released - if: steps.version.outputs.skip != 'true' - id: check - run: | - TAG="${{ steps.version.outputs.release_tag }}" - BRANCH="${{ steps.version.outputs.branch }}" - - TAG_EXISTS=false - BRANCH_EXISTS=false - - git rev-parse "$TAG" >/dev/null 2>&1 && TAG_EXISTS=true - git ls-remote --heads origin "$BRANCH" 2>/dev/null | grep -q "$BRANCH" && BRANCH_EXISTS=true - - echo "tag_exists=$TAG_EXISTS" >> "$GITHUB_OUTPUT" - echo "branch_exists=$BRANCH_EXISTS" >> "$GITHUB_OUTPUT" - - # Tag and branch may persist across patch releases — never skip - echo "already_released=false" >> "$GITHUB_OUTPUT" - - # -- SANITY CHECKS ------------------------------------------------------- - - name: "Sanity: Pre-release validation" - if: >- - steps.version.outputs.skip != 'true' && - steps.check.outputs.already_released != 'true' - run: | - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" - php /tmp/moko-platform-api/cli/release_validate.php \ - --path . --version "$VERSION" --output-summary --github-output || true - - # -- STEP 2: Create or update version/XX.YY archive branch --------------- - # Always runs — every version change on main archives to version/XX.YY - - name: "Step 2: Version archive branch" - if: steps.check.outputs.already_released != 'true' - run: | - BRANCH="${{ steps.version.outputs.branch }}" - IS_MINOR="${{ steps.version.outputs.is_minor }}" - PATCH="${{ steps.bump.outputs.version || steps.version.outputs.version }}" - PATCH_NUM=$(echo "$PATCH" | awk -F. '{print $3}') - - # Check if branch exists - if git ls-remote --heads origin "$BRANCH" | grep -q "$BRANCH"; then - git push origin HEAD:"$BRANCH" --force - echo "Updated archive branch: ${BRANCH} (patch ${PATCH_NUM})" >> $GITHUB_STEP_SUMMARY - else - git checkout -b "$BRANCH" 2>/dev/null || git checkout "$BRANCH" - git push origin "$BRANCH" --force - echo "Created archive branch: ${BRANCH}" >> $GITHUB_STEP_SUMMARY - fi - - # -- STEP 3: Set platform version ---------------------------------------- - - name: "Step 3: Set platform version" - if: >- - steps.version.outputs.skip != 'true' && - steps.check.outputs.already_released != 'true' - run: | - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" - php /tmp/moko-platform-api/cli/version_set_platform.php \ - --path . --version "$VERSION" --branch main - - # -- STEP 4: Update version badges ---------------------------------------- - - name: "Step 4: Update version badges" - if: steps.version.outputs.skip != 'true' - run: | - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" - php /tmp/moko-platform-api/cli/badge_update.php --path . --version "${VERSION}" 2>/dev/null || true - php /tmp/moko-platform-api/cli/version_check.php --path . --fix 2>/dev/null || true - - # Step 5 (updates.xml) moved after Step 8 to include SHA-256 checksum - - - name: "Step 4b: Promote and prune CHANGELOG" - if: >- - steps.version.outputs.skip != 'true' && - steps.check.outputs.already_released != 'true' - run: | - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" - MOKO_API="/tmp/moko-platform-api/cli" - if [ -f "CHANGELOG.md" ]; then - php ${MOKO_API}/changelog_promote.php --path . --version "$VERSION" 2>&1 || true - php ${MOKO_API}/changelog_prune.php --path . --keep 5 2>&1 || true - fi - - - name: Commit release changes - if: >- - steps.version.outputs.skip != 'true' && - steps.check.outputs.already_released != 'true' - run: | - if git diff --quiet && git diff --cached --quiet; then - echo "No changes to commit" - exit 0 - fi - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" - git add -A - git commit -m "chore(release): build ${VERSION} [skip ci]" \ - --author="gitea-actions[bot] " - # Detached HEAD on PR merge — push explicitly to main - git push origin HEAD:refs/heads/main - - # -- STEP 6: Create tag --------------------------------------------------- - - name: "Step 6: Create git tag" - if: >- - steps.version.outputs.skip != 'true' - run: | - RELEASE_TAG="${{ steps.version.outputs.release_tag }}" - # Only create the major release tag if it doesn't exist yet - if ! git rev-parse "$RELEASE_TAG" >/dev/null 2>&1; then - git tag "$RELEASE_TAG" - git push origin "$RELEASE_TAG" - echo "Tag created: ${RELEASE_TAG}" >> $GITHUB_STEP_SUMMARY - else - echo "Tag ${RELEASE_TAG} already exists" >> $GITHUB_STEP_SUMMARY - fi - echo "Tag: ${TAG}" >> $GITHUB_STEP_SUMMARY - - # -- STEP 7a: Promote RC to stable (skip build) ---------------------------- - - name: "Step 7a: Promote RC to stable" - if: >- - steps.version.outputs.skip != 'true' && - steps.rc.outputs.promote == 'true' - run: | - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" - php /tmp/moko-platform-api/cli/release_promote.php \ - --from release-candidate --to stable \ - --token "${{ secrets.MOKOGITEA_TOKEN }}" \ - --api-base "${API_BASE}" \ - --path . --branch main - echo "Promoted RC → stable (${VERSION})" >> $GITHUB_STEP_SUMMARY - - # -- STEP 7b: Create or update Gitea Release (full build path) ------------- - - name: "Step 7b: Gitea Release" - if: >- - steps.version.outputs.skip != 'true' && - steps.rc.outputs.promote != 'true' - run: | - VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" - RELEASE_TAG="${{ steps.version.outputs.release_tag }}" - API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" - php /tmp/moko-platform-api/cli/release_create.php \ - --path . --version "$VERSION" --tag "$RELEASE_TAG" \ - --token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \ - --repo "${GITEA_REPO}" --branch main - echo "Release created: ${VERSION}" >> $GITHUB_STEP_SUMMARY - - # -- STEP 8: Build packages and upload to release ---------------------------- - - name: "Publish stable release (+ copies for all lesser streams)" - if: >- - steps.version.outputs.skip != 'true' && - steps.rc.outputs.promote != 'true' + - name: "Publish stable release" run: | php /tmp/moko-platform-api/cli/release_publish.php \ - --path . --stability stable --branch main \ + --path . --stability stable --bump minor --branch main \ --token "${{ secrets.MOKOGITEA_TOKEN }}" # -- STEP 9: Mirror to GitHub (stable only) -------------------------------- -- 2.52.0 From 7c0a587df32fe89518d2e71c95e932ff5aef66be Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sat, 30 May 2026 09:36:34 -0500 Subject: [PATCH 2/2] feat(cli): release_publish handles changelog, badges, commit, and git auth - Add badge_update, changelog_promote/prune to release_publish - Commit version changes before building packages - Auto-construct repo URL from token for git auth - Add --repo-url argument support Authored-by: Moko Consulting Co-Authored-By: Claude Opus 4.6 (1M context) --- cli/release_publish.php | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/cli/release_publish.php b/cli/release_publish.php index 73d5b0a..3656ee9 100644 --- a/cli/release_publish.php +++ b/cli/release_publish.php @@ -45,6 +45,7 @@ $giteaUrl = getenv('GITEA_URL') ?: 'https://git.mokoconsulting.tech'; $org = getenv('GITEA_ORG') ?: ''; $repo = getenv('GITEA_REPO') ?: ''; $dryRun = false; +$repoUrl = ''; foreach ($argv as $i => $arg) { if ($arg === '--path' && isset($argv[$i + 1])) $path = $argv[$i + 1]; @@ -55,6 +56,7 @@ foreach ($argv as $i => $arg) { if ($arg === '--gitea-url' && isset($argv[$i + 1])) $giteaUrl = $argv[$i + 1]; if ($arg === '--org' && isset($argv[$i + 1])) $org = $argv[$i + 1]; if ($arg === '--repo' && isset($argv[$i + 1])) $repo = $argv[$i + 1]; + if ($arg === '--repo-url' && isset($argv[$i + 1])) $repoUrl = $argv[$i + 1]; if ($arg === '--dry-run') $dryRun = true; } @@ -76,6 +78,12 @@ if (empty($org) || empty($repo)) { } } +// Auto-construct repo URL for git auth if not provided +if (empty($repoUrl) && !empty($token) && !empty($org) && !empty($repo)) { + $host = preg_replace('#^https?://#', '', $giteaUrl); + $repoUrl = "https://x-access-token:{$token}@{$host}/{$org}/{$repo}.git"; +} + // Auto-detect branch if (empty($branch)) { $branch = getenv('GITHUB_REF_NAME') ?: trim((string) @shell_exec("cd " . escapeshellarg($path) . " && git rev-parse --abbrev-ref HEAD 2>/dev/null")); @@ -144,6 +152,35 @@ if (!$dryRun) { $releaseVersion = $baseVersion . $suffixMap[$stability]; echo "Release version: {$releaseVersion}\n"; +// -- Step 2b: Update badges and changelog -- +if (!$dryRun) { + passthru("{$php} {$cli}/badge_update.php --path " . escapeshellarg($path) . " --version " . escapeshellarg($baseVersion) . " 2>/dev/null"); + + $changelogFile = realpath($path) . '/CHANGELOG.md'; + if (file_exists($changelogFile)) { + passthru("{$php} {$cli}/changelog_promote.php --path " . escapeshellarg($path) . " --version " . escapeshellarg($baseVersion) . " 2>/dev/null"); + passthru("{$php} {$cli}/changelog_prune.php --path " . escapeshellarg($path) . " --keep 5 2>/dev/null"); + } +} + +// -- Step 2c: Commit version changes before building -- +$root = realpath($path) ?: $path; +if (!$dryRun) { + $diffCheck = trim((string) @shell_exec("cd " . escapeshellarg($root) . " && git diff --quiet && git diff --cached --quiet 2>&1 && echo clean || echo dirty")); + if ($diffCheck === 'dirty') { + @shell_exec("cd " . escapeshellarg($root) . " && git config --local user.email \"gitea-actions[bot]@mokoconsulting.tech\""); + @shell_exec("cd " . escapeshellarg($root) . " && git config --local user.name \"gitea-actions[bot]\""); + if (!empty($repoUrl)) { + @shell_exec("cd " . escapeshellarg($root) . " && git remote set-url origin " . escapeshellarg($repoUrl)); + } + @shell_exec("cd " . escapeshellarg($root) . " && git add -A"); + @shell_exec("cd " . escapeshellarg($root) . " && git commit -m " . escapeshellarg("chore(release): build {$releaseVersion} [skip ci]") + . " --author=\"gitea-actions[bot] \""); + @shell_exec("cd " . escapeshellarg($root) . " && git push origin HEAD:refs/heads/" . escapeshellarg($branch) . " 2>&1"); + echo " Committed release changes\n"; + } +} + // -- Step 3: Build release package -- echo "\n--- Step 3: Build and upload release ---\n"; $releaseTag = $releaseTagMap[$stability]; -- 2.52.0