Public Access
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 84259c6636 | |||
| 282a56258c | |||
| 3972b91169 | |||
| 5885797728 | |||
| 27c19ccbaa | |||
| 8dcd3a6af3 | |||
| 12779900b4 | |||
| 31d2e4939a | |||
| ad9b82cbe9 | |||
| a8769c1cdc | |||
| ccd1b23bff | |||
| 8a6f476957 | |||
| 7083ad9f9b | |||
| 660f6caaa2 | |||
| 8fef6a3ce7 | |||
| e678f31817 | |||
| 3ef651e34d | |||
| 193fa8be53 | |||
| 8a5209bf19 |
@@ -10,9 +10,9 @@
|
||||
# VERSION: 05.00.00
|
||||
# BRIEF: Universal build & release � detects platform from manifest.xml
|
||||
#
|
||||
# +========================================================================+
|
||||
# +=======================================================================+
|
||||
# | UNIVERSAL BUILD & RELEASE PIPELINE |
|
||||
# +========================================================================+
|
||||
# +=======================================================================+
|
||||
# | |
|
||||
# | Reads manifest.xml (joomla|dolibarr|generic) to branch logic. |
|
||||
# | |
|
||||
@@ -21,7 +21,7 @@
|
||||
# | dolibarr: mod*.class.php, update.txt, dev version reset |
|
||||
# | generic: README-only, no update stream |
|
||||
# | |
|
||||
# +========================================================================+
|
||||
# +=======================================================================+
|
||||
|
||||
name: "Universal: Build & Release"
|
||||
|
||||
@@ -51,7 +51,7 @@ permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
# ── PR Opened → Rename branch to RC and build RC release ─────────────────────
|
||||
# ── PR Opened → Rename branch to RC and build RC release ─────────────────────────
|
||||
promote-rc:
|
||||
name: Promote to RC
|
||||
runs-on: release
|
||||
@@ -149,7 +149,7 @@ jobs:
|
||||
echo "## Promoted to Release Candidate" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Branch renamed to rc, minor bump, RC release built" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
# ── Merged PR → Build & Release (or promote RC to stable) ────────────────────
|
||||
# ── Merged PR → Build & Release (or promote RC to stable) ─────────────────────────
|
||||
release:
|
||||
name: Build & Release Pipeline
|
||||
runs-on: release
|
||||
@@ -241,11 +241,47 @@ jobs:
|
||||
VERSION=$(echo "$VERSION" | sed 's/-\(dev\|alpha\|beta\|rc\)$//')
|
||||
[ -z "$VERSION" ] && VERSION="00.00.00" && echo "skip=true" >> "$GITHUB_OUTPUT"
|
||||
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||
echo "tag=stable" >> "$GITHUB_OUTPUT"
|
||||
echo "release_tag=stable" >> "$GITHUB_OUTPUT"
|
||||
PLATFORM="${{ steps.platform.outputs.platform }}"
|
||||
if [[ "$PLATFORM" == joomla* ]]; then
|
||||
echo "tag=stable" >> "$GITHUB_OUTPUT"
|
||||
echo "release_tag=stable" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "tag=v${VERSION}" >> "$GITHUB_OUTPUT"
|
||||
echo "release_tag=v${VERSION}" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
echo "branch=main" >> "$GITHUB_OUTPUT"
|
||||
echo "Published version: ${VERSION}"
|
||||
|
||||
- name: "Create semver tag for non-Joomla repos"
|
||||
id: semver
|
||||
if: |
|
||||
steps.version.outputs.skip != 'true' &&
|
||||
!startsWith(steps.platform.outputs.platform, 'joomla')
|
||||
run: |
|
||||
VERSION="${{ steps.version.outputs.version }}"
|
||||
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
||||
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
|
||||
SEMVER_TAG="v${VERSION}"
|
||||
|
||||
echo "Creating semver tag: ${SEMVER_TAG}"
|
||||
|
||||
# Create the git tag via API
|
||||
HTTP_CODE=$(curl -sf -o /dev/null -w "%{http_code}" \
|
||||
-X POST -H "Authorization: token ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${API_BASE}/tags" \
|
||||
-d "{\"tag_name\":\"${SEMVER_TAG}\",\"target\":\"main\",\"message\":\"Release ${VERSION}\"}" 2>/dev/null || echo "000")
|
||||
|
||||
if [ "$HTTP_CODE" = "201" ] || [ "$HTTP_CODE" = "200" ]; then
|
||||
echo "Created semver tag: ${SEMVER_TAG}"
|
||||
elif [ "$HTTP_CODE" = "409" ]; then
|
||||
echo "Semver tag ${SEMVER_TAG} already exists (skipped)"
|
||||
else
|
||||
echo "::warning::Failed to create semver tag ${SEMVER_TAG} (HTTP ${HTTP_CODE})"
|
||||
fi
|
||||
|
||||
echo "semver_tag=${SEMVER_TAG}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Update release notes and promote changelog
|
||||
run: |
|
||||
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
name: "Publish to Composer"
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
- '[0-9]*.[0-9]*.[0-9]*'
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
name: Publish Package
|
||||
runs-on: ubuntu-latest
|
||||
if: >-
|
||||
!contains(github.event.head_commit.message, '[skip ci]') &&
|
||||
!contains(github.event.head_commit.message, '[skip publish]')
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup PHP
|
||||
run: |
|
||||
if ! command -v php &> /dev/null; then
|
||||
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
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer install --no-dev --no-interaction --prefer-dist --quiet
|
||||
|
||||
- name: Determine version
|
||||
id: version
|
||||
run: |
|
||||
VERSION=$(php -r "echo json_decode(file_get_contents('composer.json'))->version;")
|
||||
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||
echo "Package version: ${VERSION}"
|
||||
|
||||
# Gitea Composer Registry — auto-publishes from tags
|
||||
# The tag push itself registers the package at:
|
||||
# https://git.mokoconsulting.tech/api/packages/MokoConsulting/composer
|
||||
- name: Verify Gitea registry
|
||||
run: |
|
||||
echo "Gitea Composer registry auto-publishes from tags."
|
||||
echo "Package available at: ${GITEA_URL}/api/packages/MokoConsulting/composer"
|
||||
echo "Install: composer require mokoconsulting/mokocli"
|
||||
|
||||
# Packagist — notify of new version
|
||||
- name: Notify Packagist
|
||||
if: secrets.PACKAGIST_TOKEN != ''
|
||||
run: |
|
||||
VERSION="${{ steps.version.outputs.version }}"
|
||||
echo "Notifying Packagist of version ${VERSION}..."
|
||||
curl -sf -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"repository":{"url":"https://git.mokoconsulting.tech/MokoConsulting/mokocli"}}' \
|
||||
"https://packagist.org/api/update-package?username=mokoconsulting&apiToken=${{ secrets.PACKAGIST_TOKEN }}" \
|
||||
&& echo "Packagist notified" \
|
||||
|| echo "::warning::Packagist notification failed (package may not be registered yet)"
|
||||
|
||||
- name: Summary
|
||||
run: |
|
||||
VERSION="${{ steps.version.outputs.version }}"
|
||||
echo "## Composer Package Published" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Registry | Status |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|----------|--------|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Gitea | \`composer require mokoconsulting/mokocli:${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Packagist | \`composer require mokoconsulting/mokocli\` |" >> $GITHUB_STEP_SUMMARY
|
||||
@@ -5,7 +5,7 @@
|
||||
# FILE INFORMATION
|
||||
# DEFGROUP: Gitea.Workflow
|
||||
# INGROUP: mokocli.Automation
|
||||
# VERSION: 09.37.06
|
||||
# VERSION: 09.38.05
|
||||
# BRIEF: Auto-create feature branch when an issue is opened
|
||||
|
||||
name: "Universal: Issue Branch"
|
||||
|
||||
@@ -88,8 +88,20 @@ jobs:
|
||||
php ${MOKO_CLI}/platform_detect.php --path . --github-output 2>/dev/null || true
|
||||
php ${MOKO_CLI}/manifest_read.php --path . --github-output
|
||||
|
||||
- name: Check platform eligibility (Joomla only)
|
||||
id: eligibility
|
||||
run: |
|
||||
PLATFORM="${{ steps.platform.outputs.platform }}"
|
||||
if [[ "$PLATFORM" == joomla* ]] || [[ "$PLATFORM" == "joomla" ]]; then
|
||||
echo "proceed=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "proceed=false" >> "$GITHUB_OUTPUT"
|
||||
echo "::notice::Platform '$PLATFORM' — non-Joomla, skipping pre-release auto-bump"
|
||||
fi
|
||||
|
||||
- name: Resolve metadata and bump version
|
||||
id: meta
|
||||
if: steps.eligibility.outputs.proceed == 'true'
|
||||
run: |
|
||||
# Auto-detect stability from branch name on push, or use input on dispatch
|
||||
if [ "${{ github.event_name }}" = "push" ]; then
|
||||
@@ -166,6 +178,7 @@ jobs:
|
||||
|
||||
- name: Create release
|
||||
id: release
|
||||
if: steps.eligibility.outputs.proceed == 'true'
|
||||
run: |
|
||||
TAG="${{ steps.meta.outputs.tag }}"
|
||||
VERSION="${{ steps.meta.outputs.version }}"
|
||||
@@ -176,6 +189,7 @@ jobs:
|
||||
--repo "${GITEA_REPO}" --branch "${{ github.ref_name }}" --prerelease
|
||||
|
||||
- name: Update release notes from CHANGELOG.md
|
||||
if: steps.eligibility.outputs.proceed == 'true'
|
||||
run: |
|
||||
TAG="${{ steps.meta.outputs.tag }}"
|
||||
VERSION="${{ steps.meta.outputs.version }}"
|
||||
@@ -212,6 +226,7 @@ jobs:
|
||||
|
||||
- name: Build package and upload
|
||||
id: package
|
||||
if: steps.eligibility.outputs.proceed == 'true'
|
||||
run: |
|
||||
VERSION="${{ steps.meta.outputs.version }}"
|
||||
TAG="${{ steps.meta.outputs.tag }}"
|
||||
@@ -225,6 +240,7 @@ jobs:
|
||||
# No need to build, commit, or sync updates.xml from workflows
|
||||
|
||||
- name: "Delete lesser pre-release channels (cascade)"
|
||||
if: steps.eligibility.outputs.proceed == 'true'
|
||||
continue-on-error: true
|
||||
run: |
|
||||
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
||||
|
||||
@@ -29,12 +29,20 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Rename branch
|
||||
env:
|
||||
BRANCH: ${{ github.event.pull_request.head.ref }}
|
||||
REPO: ${{ github.repository }}
|
||||
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
||||
TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
||||
run: |
|
||||
BRANCH="${{ github.event.pull_request.head.ref }}"
|
||||
set -euo pipefail
|
||||
# BRANCH is attacker-controlled (PR head ref). Strict allowlist before ANY use.
|
||||
if ! printf '%s' "$BRANCH" | grep -Eq '^rc/[A-Za-z0-9._/-]+$'; then
|
||||
echo "::error::Refusing unsafe branch name: $BRANCH"; exit 1
|
||||
fi
|
||||
SUFFIX="${BRANCH#rc/}"
|
||||
DEV_BRANCH="dev/${SUFFIX}"
|
||||
API="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}/api/v1/repos/${{ github.repository }}/branches"
|
||||
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
|
||||
API="${GITEA_URL}/api/v1/repos/${REPO}/branches"
|
||||
|
||||
# Create dev/ branch from rc/ branch
|
||||
STATUS=$(curl -sf -o /dev/null -w "%{http_code}" -X POST \
|
||||
@@ -42,25 +50,22 @@ jobs:
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"new_branch_name\": \"${DEV_BRANCH}\", \"old_branch_name\": \"${BRANCH}\"}" \
|
||||
"${API}" 2>/dev/null || true)
|
||||
|
||||
if [ "$STATUS" = "201" ]; then
|
||||
echo "Created branch: ${DEV_BRANCH}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Created branch: ${DEV_BRANCH}" >> "$GITHUB_STEP_SUMMARY"
|
||||
else
|
||||
echo "::error::Failed to create ${DEV_BRANCH} from ${BRANCH} (HTTP ${STATUS})"
|
||||
exit 1
|
||||
echo "::error::Failed to create ${DEV_BRANCH} from ${BRANCH} (HTTP ${STATUS})"; exit 1
|
||||
fi
|
||||
|
||||
# Delete rc/ branch
|
||||
ENCODED=$(php -r "echo rawurlencode('${BRANCH}');")
|
||||
# Read BRANCH from the environment inside PHP (getenv, no string interpolation -> no PHP injection)
|
||||
ENCODED=$(php -r 'echo rawurlencode(getenv("BRANCH"));')
|
||||
STATUS=$(curl -sf -o /dev/null -w "%{http_code}" -X DELETE \
|
||||
-H "Authorization: token ${TOKEN}" \
|
||||
"${API}/${ENCODED}" 2>/dev/null || true)
|
||||
|
||||
if [ "$STATUS" = "204" ]; then
|
||||
echo "Deleted branch: ${BRANCH}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Deleted branch: ${BRANCH}" >> "$GITHUB_STEP_SUMMARY"
|
||||
else
|
||||
echo "::warning::Failed to delete ${BRANCH} (HTTP ${STATUS})"
|
||||
fi
|
||||
|
||||
echo "### RC Reverted" >> $GITHUB_STEP_SUMMARY
|
||||
echo "${BRANCH} → ${DEV_BRANCH}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### RC Reverted" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "${BRANCH} → ${DEV_BRANCH}" >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
@@ -6,7 +6,7 @@ DEFGROUP: MokoPlatform.Root
|
||||
INGROUP: MokoPlatform
|
||||
REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
PATH: /README.md
|
||||
VERSION: 09.37.06
|
||||
VERSION: 09.38.05
|
||||
BRIEF: Project overview and documentation
|
||||
-->
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* INGROUP: MokoPlatform.Scripts
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /automation/update_dependencies.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Cross-repo dependency update automation — scan, update, PR, auto-merge
|
||||
*/
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/branch_rename.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Rename a git branch via Gitea API (create new, update PR, delete old)
|
||||
*/
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/bulk_workflow_push.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Push a workflow file to all governed repos via the Gitea Contents API
|
||||
*/
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/bulk_workflow_trigger.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Trigger a workflow across multiple repos at once
|
||||
*/
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/client_dashboard.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Generate unified client dashboard HTML
|
||||
*/
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/client_inventory.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Discover and list all client-waas repos with their server configuration status
|
||||
*/
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/client_provision.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Provision a new client environment end-to-end
|
||||
*/
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/grafana_dashboard.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Manage Grafana dashboards via API
|
||||
*/
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/joomla_build.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Build a Joomla extension ZIP from manifest — all types supported
|
||||
* NOTE: Called by pre-release and auto-release workflows.
|
||||
*/
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/joomla_metadata_validate.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Validate MokoGitea repo metadata against Joomla extension manifest XML
|
||||
*/
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/manifest_detect.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Auto-detect manifest fields from source files and optionally push to API
|
||||
*/
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/manifest_integrity.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Cross-check manifest API fields against repo contents across the org
|
||||
*/
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/manifest_licensing.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Ensure licensing tags (updateservers, dlid) in Joomla extension manifests
|
||||
*/
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/manifest_read.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Read repo metadata from Gitea manifest API, auto-detect the rest
|
||||
*/
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/platform_detect.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Auto-detect repository platform type and optionally update manifest
|
||||
*/
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/release_cascade.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Cascade release zip to all lower stability channels
|
||||
*/
|
||||
|
||||
|
||||
@@ -250,6 +250,14 @@ class ReleasePackageCli extends CliFramework
|
||||
}
|
||||
$subZipPath = "{$outputDir}/{$subName}.zip";
|
||||
|
||||
// Use pre-built ZIP if staged in the output directory
|
||||
if (file_exists($subZipPath) && filesize($subZipPath) > 0) {
|
||||
$zip->addFile($subZipPath, "packages/{$subName}.zip");
|
||||
$sizeKb = number_format(filesize($subZipPath) / 1024, 1);
|
||||
echo " Sub-package: {$subName}.zip (pre-built, {$sizeKb} KB)\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
// If sub-package is a full repo checkout (e.g. git submodule),
|
||||
// look for a source/ or src/ subdirectory containing a Joomla manifest XML
|
||||
// and zip that instead of the repo root.
|
||||
@@ -270,6 +278,16 @@ class ReleasePackageCli extends CliFramework
|
||||
}
|
||||
}
|
||||
|
||||
// If source dir has no manifest, the submodule may be empty.
|
||||
// Try to download the pre-built release from Gitea.
|
||||
$hasManifest = !empty(glob("{$subSourceDir}/*.xml") ?: []);
|
||||
if (!$hasManifest && $token !== '' && $this->downloadSubmoduleRelease($root, $subName, $subZipPath, $token)) {
|
||||
$zip->addFile($subZipPath, "packages/{$subName}.zip");
|
||||
$sizeKb = number_format(filesize($subZipPath) / 1024, 1);
|
||||
echo " Sub-package: {$subName}.zip (downloaded release, {$sizeKb} KB)\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
$subZip = new \ZipArchive();
|
||||
if ($subZip->open($subZipPath, \ZipArchive::CREATE | \ZipArchive::OVERWRITE) !== true) {
|
||||
$this->log('ERROR', "Failed to create sub-package ZIP: {$subZipPath}");
|
||||
@@ -527,6 +545,103 @@ class ReleasePackageCli extends CliFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Download a pre-built release ZIP for a sub-package that is a git submodule
|
||||
* with an empty or missing source directory.
|
||||
*
|
||||
* Reads .gitmodules to find the submodule's remote URL, derives the Gitea
|
||||
* API path, and downloads the latest stable release asset.
|
||||
*/
|
||||
private function downloadSubmoduleRelease(string $root, string $subName, string $destPath, string $token): bool
|
||||
{
|
||||
$gitmodulesPath = "{$root}/.gitmodules";
|
||||
if (!file_exists($gitmodulesPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$gitmodules = file_get_contents($gitmodulesPath);
|
||||
if ($gitmodules === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find the submodule URL by matching the subName in the path
|
||||
if (!preg_match('/\[submodule\s[^\]]*\]\s*\n\s*path\s*=\s*[^\n]*' . preg_quote($subName, '/') . '\s*\n\s*url\s*=\s*(\S+)/m', $gitmodules, $matches)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$remoteUrl = preg_replace('/\.git$/', '', $matches[1]);
|
||||
|
||||
// Extract org/repo from the URL
|
||||
if (!preg_match('#[/:]([^/]+)/([^/]+)$#', $remoteUrl, $parts)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$org = $parts[1];
|
||||
$repo = $parts[2];
|
||||
|
||||
// Derive the Gitea API base from the remote URL
|
||||
$parsed = parse_url($remoteUrl);
|
||||
$scheme = $parsed['scheme'] ?? 'https';
|
||||
$host = $parsed['host'] ?? '';
|
||||
if ($host === '') {
|
||||
return false;
|
||||
}
|
||||
$apiBase = "{$scheme}://{$host}/api/v1/repos/{$org}/{$repo}";
|
||||
|
||||
echo " Submodule {$subName}: source empty, downloading release from {$org}/{$repo}...\n";
|
||||
|
||||
// Get the stable release
|
||||
$result = $this->giteaApiRequest("{$apiBase}/releases/tags/stable", $token);
|
||||
if ($result['data'] === null || !isset($result['data']['assets'])) {
|
||||
echo " WARNING: No stable release found for {$org}/{$repo}\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find the ZIP asset (not .sha256)
|
||||
$downloadUrl = '';
|
||||
foreach ($result['data']['assets'] as $asset) {
|
||||
if (!is_array($asset)) {
|
||||
continue;
|
||||
}
|
||||
$name = $asset['name'] ?? '';
|
||||
if (str_ends_with($name, '.zip') && !str_ends_with($name, '.sha256')) {
|
||||
$downloadUrl = $asset['browser_download_url'] ?? '';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($downloadUrl === '') {
|
||||
echo " WARNING: No ZIP asset in {$org}/{$repo} stable release\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Download the ZIP
|
||||
$ch = curl_init($downloadUrl);
|
||||
if ($ch === false) {
|
||||
return false;
|
||||
}
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_HTTPHEADER => ["Authorization: token {$token}"],
|
||||
CURLOPT_TIMEOUT => 120,
|
||||
]);
|
||||
$content = curl_exec($ch);
|
||||
$httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
if ($httpCode < 200 || $httpCode >= 300 || !is_string($content) || $content === '') {
|
||||
echo " WARNING: Download failed (HTTP {$httpCode})\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file_put_contents($destPath, $content) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively add files from a directory to a ZipArchive.
|
||||
*/
|
||||
|
||||
+12
-1
@@ -10,7 +10,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/release_publish.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Publish a release and create copies for all lesser stability streams.
|
||||
*/
|
||||
|
||||
@@ -254,6 +254,17 @@ class ReleasePublishCli extends CliFramework
|
||||
// -- Step 3: Build release package --
|
||||
echo "\n--- Step 3: Build and upload release ---\n";
|
||||
$releaseTag = $releaseTagMap[$stability];
|
||||
|
||||
// For non-Joomla platforms, use semver tags instead of stream tags
|
||||
$platformOutput = [];
|
||||
exec("{$php} {$cli}/manifest_read.php --path " . escapeshellarg($resolvedPath) . " --field platform 2>/dev/null", $platformOutput);
|
||||
$platform = trim($platformOutput[0] ?? '');
|
||||
if ($platform !== '' && !str_starts_with($platform, 'joomla')) {
|
||||
$releaseTag = 'v' . $releaseVersion;
|
||||
echo " Platform: {$platform} — using semver tag: {$releaseTag}
|
||||
";
|
||||
}
|
||||
|
||||
$sha256 = '';
|
||||
|
||||
if (!$this->dryRun) {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/scaffold_client.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Scaffold a new client-waas repo from Template-Client-WaaS with pre-configured settings
|
||||
*/
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/updates_xml_sync.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Sync updates.xml to target branches via Gitea API
|
||||
* NOTE: Called by pre-release and auto-release workflows after updates.xml
|
||||
* is modified on the current branch. Pushes the file to other branches
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/version_auto_bump.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Auto patch-bump, set stability suffix, and commit — single CLI replacing inline workflow bash
|
||||
*/
|
||||
|
||||
|
||||
@@ -124,19 +124,17 @@ class VersionBumpCli extends CliFramework
|
||||
$minVersion = preg_replace('/-(?:dev|alpha|beta|rc)$/', '', $minVersion);
|
||||
if (preg_match('/^\d{2}\.\d{2}\.\d{2}$/', $minVersion)) {
|
||||
if ($baseVersion === null || version_compare($minVersion, $baseVersion, '>')) {
|
||||
$this->log('INFO', "Using --min-version {$minVersion} (higher than manifest {$baseVersion})");
|
||||
$this->log('INFO', "Using --min-version {$minVersion} (higher than manifest " . ($baseVersion ?? '(none)') . ")");
|
||||
$baseVersion = $minVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Auto-detect: scan git tags for higher versions from other channels
|
||||
if ($baseVersion !== null) {
|
||||
$gitTagVersion = $this->getHighestGitTagVersion($root);
|
||||
if ($gitTagVersion !== null && version_compare($gitTagVersion, $baseVersion, '>')) {
|
||||
$this->log('INFO', "Git tag version {$gitTagVersion} is higher than manifest {$baseVersion} — using as base");
|
||||
$baseVersion = $gitTagVersion;
|
||||
}
|
||||
$gitTagVersion = $this->getHighestGitTagVersion($root);
|
||||
if ($gitTagVersion !== null && ($baseVersion === null || version_compare($gitTagVersion, $baseVersion, '>'))) {
|
||||
$this->log('INFO', "Git tag version {$gitTagVersion} is higher than manifest " . ($baseVersion ?? '(none)') . " — using as base");
|
||||
$baseVersion = $gitTagVersion;
|
||||
}
|
||||
|
||||
if ($baseVersion === null) {
|
||||
@@ -370,7 +368,7 @@ class VersionBumpCli extends CliFramework
|
||||
/**
|
||||
* Scan git release tags for the highest version across all channels.
|
||||
*
|
||||
* Checks release names like "MokoSuiteClient (VERSION: 09.37.06)" in
|
||||
* Checks release names like "MokoSuiteClient (VERSION: 09.38.05)" in
|
||||
* git tags (stable, release-candidate, development, etc.) to find the
|
||||
* highest version that has been released on any channel.
|
||||
*/
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/version_check.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Validate version consistency across README, manifests, and sub-packages
|
||||
*/
|
||||
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/wiki_sync.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Sync select wiki pages from mokocli to all template repos
|
||||
*/
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* INGROUP: mokocli
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /cli/workflow_sync.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Sync workflows from Generic → platform templates → live repos based on manifest.platform
|
||||
*/
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* INGROUP: MokoPlatform
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /deploy/backup-before-deploy.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Snapshot Joomla directories before deployment for rollback capability
|
||||
*/
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* INGROUP: MokoPlatform
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /deploy/deploy-dolibarr.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Deploy Dolibarr module files to a remote server via SFTP/rsync
|
||||
*/
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* INGROUP: MokoPlatform
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /deploy/health-check.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Post-deploy health check — verify a Joomla site is responding correctly
|
||||
*/
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* INGROUP: MokoPlatform
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /deploy/rollback-joomla.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Rollback a Joomla deployment by restoring from a pre-deploy snapshot
|
||||
*/
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* INGROUP: MokoPlatform
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /deploy/sync-joomla.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Sync Joomla site directories between two servers via rsync over SSH
|
||||
*/
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
DEFGROUP: dolibarr-api-mcp.Documentation
|
||||
INGROUP: dolibarr-api-mcp
|
||||
REPO: https://git.mokoconsulting.tech/MokoConsulting/dolibarr-api-mcp
|
||||
VERSION: 09.37.06
|
||||
VERSION: 09.38.05
|
||||
PATH: ./CONTRIBUTING.md
|
||||
BRIEF: Contribution guidelines for the project
|
||||
-->
|
||||
|
||||
@@ -10,7 +10,7 @@ DEFGROUP: dolibarr-api-mcp.Documentation
|
||||
INGROUP: dolibarr-api-mcp
|
||||
REPO: https://git.mokoconsulting.tech/MokoConsulting/dolibarr-api-mcp
|
||||
PATH: /SECURITY.md
|
||||
VERSION: 09.37.06
|
||||
VERSION: 09.38.05
|
||||
BRIEF: Security vulnerability reporting and handling policy
|
||||
-->
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
DEFGROUP:
|
||||
INGROUP: Project.Documentation
|
||||
REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCli-Template-Generic
|
||||
VERSION: 09.37.06
|
||||
VERSION: 09.38.05
|
||||
PATH: ./CONTRIBUTING.md
|
||||
BRIEF: Contribution guidelines for the project
|
||||
-->
|
||||
|
||||
@@ -23,7 +23,7 @@ DEFGROUP: [PROJECT_NAME]
|
||||
INGROUP: [PROJECT_NAME].Documentation
|
||||
REPO: [REPOSITORY_URL]
|
||||
PATH: /SECURITY.md
|
||||
VERSION: 09.37.06
|
||||
VERSION: 09.38.05
|
||||
BRIEF: Security vulnerability reporting and handling policy
|
||||
-->
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ class VersionBumpTest extends TestCase
|
||||
{
|
||||
file_put_contents(
|
||||
"{$this->tmpDir}/README.md",
|
||||
"<!-- VERSION: 09.37.06 -->\nSome content\n"
|
||||
"<!-- VERSION: 09.38.05 -->\nSome content\n"
|
||||
);
|
||||
|
||||
$this->execute();
|
||||
|
||||
@@ -34,7 +34,7 @@ class VersionReadTest extends TestCase
|
||||
{
|
||||
file_put_contents(
|
||||
"{$this->tmpDir}/README.md",
|
||||
"# Test\n<!-- VERSION: 09.37.06 -->\n"
|
||||
"# Test\n<!-- VERSION: 09.38.05 -->\n"
|
||||
);
|
||||
|
||||
$this->assertSame('02.03.04', trim($this->runScript()));
|
||||
@@ -68,7 +68,7 @@ class VersionReadTest extends TestCase
|
||||
{
|
||||
file_put_contents(
|
||||
"{$this->tmpDir}/README.md",
|
||||
"<!-- VERSION: 09.37.06 -->\n"
|
||||
"<!-- VERSION: 09.38.05 -->\n"
|
||||
);
|
||||
mkdir("{$this->tmpDir}/src", 0755, true);
|
||||
file_put_contents(
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* INGROUP: MokoPlatform
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
||||
* PATH: /validate/check_file_integrity.php
|
||||
* VERSION: 09.37.06
|
||||
* VERSION: 09.38.05
|
||||
* BRIEF: Compare deployed files on a remote server against the local repository to detect drift
|
||||
*/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user