feat: release_publish as single CLI for entire release #214
@@ -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 '<extension' {} \; 2>/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] <gitea-actions[bot]@mokoconsulting.tech>"
|
||||
# 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) --------------------------------
|
||||
|
||||
@@ -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] <gitea-actions[bot]@mokoconsulting.tech>\"");
|
||||
@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];
|
||||
|
||||
Reference in New Issue
Block a user