Compare commits

...

34 Commits

Author SHA1 Message Date
jmiller e9dcd48e44 Merge pull request 'chore: cascade main → dev (1bd170c) [skip ci]' (#190) from main into dev
chore: cascade main → dev [skip ci]
2026-05-26 22:47:23 +00:00
Jonathan Miller 1bd170c77f fix: workflow race conditions, pre-release CLI migration, auto-bump dev-only
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 3s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 48s
2026-05-26 17:47:19 -05:00
gitea-actions[bot] 1e18d6bcb8 chore(version): patch bump to 09.02.05 [skip ci] 2026-05-26 22:46:31 +00:00
Jonathan Miller 35befccf06 fix: resolve workflow race conditions and remaining gaps
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Successful in 3s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 45s
Race condition fixes:
- auto-bump.yml: dev-only, skips merge commits (avoids conflict with pre-release)
- auto-release.yml: minor bump restored inline (avoids conflict with auto-bump on main)

auto-release.yml:
- Step 8b: removed 26-line inline fallback, uses release_body_update.php only
- promote-rc: branch defaults to 'dev' when workflow_dispatch (no PR context)

pre-release.yml (328 → 223 lines):
- Replaced 53-line inline build with release_package.php
- Replaced 47-line inline release creation with release_create.php
- Standardized setup step to match auto-release pattern
- Fixed empty $MANIFEST variable output
- SHA256 now sourced from release_package.php output

auto-bump.yml:
- Dev-only (removed main), skips merge commits
- Added FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 env
- Fixed job name to "Version Bump"

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 17:46:25 -05:00
gitea-actions[bot] d012bb900b chore(version): minor bump to 09.03.00 [skip ci] 2026-05-26 22:34:23 +00:00
jmiller 2ab332161d Merge pull request 'chore: cascade main → dev (a9acb2d) [skip ci]' (#189) from main into dev
chore: cascade main → dev [skip ci]
2026-05-26 22:34:22 +00:00
Jonathan Miller a9acb2d27c Merge dev: SHA-256 in updates.xml, centralized auto-bump, Joomla package language fix
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 3s
Universal: Auto Version Bump / Patch Bump (push) Successful in 4s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 47s
2026-05-26 17:34:15 -05:00
gitea-actions[bot] e609a4e205 chore(version): patch bump to 09.02.04 [skip ci] 2026-05-26 22:31:57 +00:00
Jonathan Miller dbf4cdef9a fix: Joomla package builds now include language/ and other top-level dirs
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: Auto Version Bump / Patch Bump (push) Successful in 4s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 45s
pre-release.yml package build was only copying *.xml and *.php from
src/ root, missing language/, media/, and other non-package directories.

Fixes #187

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 17:31:47 -05:00
gitea-actions[bot] 24d5238b64 chore(version): minor bump to 09.03.00 [skip ci] 2026-05-26 22:30:52 +00:00
jmiller 4ccefec2dc Merge pull request 'chore: cascade main → dev (5a8b18e) [skip ci]' (#188) from main into dev
chore: cascade main → dev [skip ci]
2026-05-26 22:30:50 +00:00
Jonathan Miller 5a8b18ea8d fix: SHA-256 checksums in updates.xml + centralized auto-bump
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 4s
Universal: Auto Version Bump / Patch Bump (push) Successful in 5s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 48s
2026-05-26 17:30:43 -05:00
gitea-actions[bot] 9dbf790e1a chore(version): patch bump to 09.02.03 [skip ci] 2026-05-26 22:30:20 +00:00
Jonathan Miller a07d93b6fc fix: pass SHA-256 checksum to updates.xml in both release workflows
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Auto Version Bump / Patch Bump (push) Successful in 4s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 47s
- release_package.php now outputs sha256_zip= to GITHUB_OUTPUT
- auto-release.yml: moved updates.xml write after package build so SHA is available
- pre-release.yml: passes --sha from zip step to updates_xml_build.php
- updates.xml now includes <sha256> tag for Joomla update integrity verification

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 17:30:12 -05:00
gitea-actions[bot] 415e58d06c chore(version): minor bump to 09.03.00 [skip ci] 2026-05-26 22:22:49 +00:00
jmiller d8ec7b5ba0 Merge pull request 'chore: cascade main → dev (e882425) [skip ci]' (#186) from main into dev
chore: cascade main → dev [skip ci]
2026-05-26 22:22:49 +00:00
Jonathan Miller e882425f04 feat: centralized auto-bump workflow for all version bumps
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 3s
Universal: Auto Version Bump / Patch Bump (push) Successful in 4s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 50s
2026-05-26 17:22:42 -05:00
gitea-actions[bot] 3171fb3ef0 chore(version): patch bump to 09.02.02 [skip ci] 2026-05-26 22:22:29 +00:00
Jonathan Miller 6cd46f0b7f feat: auto-bump.yml handles all version bumps, removed from release workflows
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: Auto Version Bump / Patch Bump (push) Successful in 5s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 48s
auto-bump.yml: patch bump on push to dev, minor bump on push to main
auto-release.yml: removed Step 1b (minor bump) — handled by auto-bump
pre-release.yml: removed patch bump — handled by auto-bump

Version bump is now centralized in one workflow across all branches.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 17:21:55 -05:00
gitea-actions[bot] 48ae7c1e88 chore(version): patch bump to 09.02.01 [skip ci] 2026-05-26 22:19:23 +00:00
Jonathan Miller 63a2640254 fix: include top-level directories (language/) in Joomla package ZIP
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (pull_request) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (pull_request) Blocked by required conditions
Platform: moko-platform CI / CI Summary (pull_request) Blocked by required conditions
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Generic: Repo Health / Release configuration (pull_request) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Access control (push) Successful in 1s
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 2s
Universal: PR Check / Validate PR (pull_request) Successful in 4s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 5s
Universal: Auto Version Bump / Patch Bump (push) Successful in 6s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 54s
Platform: moko-platform CI / Gate 1: Code Quality (pull_request) Failing after 54s
release_package.php was only copying *.xml and *.php from the package
source root, missing the language/ directory. Joomla install fails with
"File does not exist" for package-level language files.

Now includes all top-level directories (except packages/) in the
package ZIP.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 17:19:15 -05:00
Jonathan Miller 6ec2202c6e fix: include language directory in Joomla package ZIP builds
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 2s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 54s
Package-type extensions reference language files in their manifest
(e.g. language/en-GB/pkg_*.sys.ini) but the build only copied
top-level XML/PHP files. Now also adds the language/ directory.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 17:19:09 -05:00
Jonathan Miller 8f7cce051b docs(changelog): add auto-bump entry [skip bump]
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (pull_request) Blocked by required conditions
Platform: moko-platform CI / CI Summary (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Generic: Repo Health / Release configuration (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Universal: Auto Version Bump / Patch Bump (push) Has been skipped
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 5s
Universal: PR Check / Validate PR (pull_request) Successful in 4s
Platform: moko-platform CI / Gate 1: Code Quality (pull_request) Failing after 47s
2026-05-26 17:15:46 -05:00
Jonathan Miller f426f21f2e feat: auto patch-bump on every push to dev
New workflow auto-bump.yml: runs version_bump.php on every push to dev,
propagates via version_set_platform.php + version_check.php, commits
with [skip ci] to avoid retriggering.

Skips when commit message contains [skip ci] or [skip bump].

Removed redundant patch bump from pre-release.yml — version is already
bumped by the push workflow before pre-release runs.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 17:11:09 -05:00
Jonathan Miller 2ee5a55ec5 fix: preserve version suffix (-dev/-rc/etc) in version_bump.php
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 43s
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (pull_request) Blocked by required conditions
Platform: moko-platform CI / CI Summary (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Generic: Repo Health / Release configuration (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: Build & Release / Promote Pre-Release to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Universal: PR Check / Validate PR (pull_request) Successful in 4s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 5s
Platform: moko-platform CI / Gate 1: Code Quality (pull_request) Failing after 44s
version_bump.php was stripping stability suffixes (e.g. -dev, -rc) from
Joomla extension manifest <version> tags during auto-bump. Now captures
the suffix from the source version and re-applies it after incrementing.

manifest.xml and README.md remain suffix-free (canonical bare version).
Only Joomla extension manifests preserve their suffix.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 17:07:07 -05:00
Jonathan Miller a04040533c docs(changelog): add v09.02.00 release notes
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 1s
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 16:59:25 -05:00
jmiller d5541abf22 Merge pull request 'chore: cascade main → dev (8ae829a) [skip ci]' (#183) from main into dev
chore: cascade main → dev [skip ci]
2026-05-26 21:55:38 +00:00
Jonathan Miller 8ae829ad89 feat: add live deploy target with multi-instance support to deploy-module.yml
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 3s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 44s
- Add 'live' and 'all' options to server selector
- Live deploy reads LIVE_TARGETS JSON secret for multiple production instances
- Move dev/demo host config from hardcoded env to vars.*
- Add summary step for deploy reporting

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 16:55:32 -05:00
jmiller 5815ad040f Merge pull request 'chore: cascade main → dev (96b6db7) [skip ci]' (#182) from main into dev
chore: cascade main → dev [skip ci]
2026-05-26 21:54:46 +00:00
Jonathan Miller 96b6db73a9 Merge dev: workflow CLI refactoring, version_bump package.json/pyproject.toml, v09.02.00
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 3s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 46s
2026-05-26 16:54:15 -05:00
jmiller 8eb3e310cf Merge pull request 'chore: cascade main → dev (eca475c) [skip ci]' (#181) from main into dev
chore: cascade main → dev [skip ci]
2026-05-26 21:32:24 +00:00
Jonathan Miller eca475c6e3 chore: remove legacy SFTP deploy steps from workflows
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 4s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 47s
- Remove SFTP deploy step from update-server.yml
- Delete deploy-manual.yml (manual SFTP deploy workflow)

All deployment now goes through updates.xml and Gitea releases.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 16:31:35 -05:00
Jonathan Miller 92822303ef feat: version_bump/read support package.json and pyproject.toml
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 44s
version_read.php now reads version from:
- .mokogitea/manifest.xml (authoritative)
- README.md, Joomla XML, composer.json (existing)
- package.json (Node.js / MCP repos) — new
- pyproject.toml (Python repos) — new

version_bump.php now writes bumped version to all of the above.

Also bumps moko-platform 09.01.00 → 09.02.00.

Closes #179

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 16:28:40 -05:00
Jonathan Miller 9649fb55cf refactor: replace all inline bash in workflows with CLI tool calls
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 46s
auto-release.yml (761 → 490 lines, -271 lines):
- Sanity checks: release_validate.php replaces 95-line inline bash (#180)
- Step 7b: release_create.php replaces 65-line curl+python3 block (#176)
- Step 8: release_package.php replaces 115-line build+upload block (#173)
- Step 9: release_mirror.php replaces 40-line GitHub mirror block (#175)
- Dolibarr reset: version_reset_dev.php replaces 20-line inline (#174)
- Added workflow_dispatch promote-rc fallback for MokoGitea#220 (#178)

pre-release.yml:
- Fixed updates.xml sync: checkout only updates.xml, not entire tree (#177)

Closes #173 #174 #175 #176 #177 #178 #180

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 16:21:02 -05:00
11 changed files with 1483 additions and 1729 deletions
+84
View File
@@ -0,0 +1,84 @@
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: moko-platform.Release
# REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
# PATH: /.mokogitea/workflows/auto-bump.yml
# VERSION: 09.02.00
# BRIEF: Auto patch-bump version on every push to dev (skips merge commits)
name: "Universal: Auto Version Bump"
on:
push:
branches:
- dev
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
permissions:
contents: write
jobs:
bump:
name: Version Bump
runs-on: release
if: >-
!contains(github.event.head_commit.message, '[skip ci]') &&
!contains(github.event.head_commit.message, '[skip bump]') &&
!startsWith(github.event.head_commit.message, 'Merge pull request')
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
token: ${{ secrets.GA_TOKEN }}
fetch-depth: 1
- name: Setup moko-platform tools
run: |
if ! command -v composer &> /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
if [ -d "/opt/moko-platform/cli" ]; then
echo "MOKO_CLI=/opt/moko-platform/cli" >> "$GITHUB_ENV"
else
git clone --depth 1 --branch main --quiet \
"https://x-access-token:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/moko-platform.git" \
/tmp/moko-platform-api
cd /tmp/moko-platform-api && composer install --no-dev --no-interaction --quiet
echo "MOKO_CLI=/tmp/moko-platform-api/cli" >> "$GITHUB_ENV"
fi
- name: Bump version
run: |
BUMP=$(php ${MOKO_CLI}/version_bump.php --path . 2>&1) || true
echo "$BUMP"
VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null) || true
[ -z "$VERSION" ] && { echo "No version found — skipping"; exit 0; }
# Propagate to platform manifests
php ${MOKO_CLI}/version_set_platform.php \
--path . --version "$VERSION" --branch dev 2>/dev/null || true
php ${MOKO_CLI}/version_check.php --path . --fix 2>/dev/null || true
# Commit if anything changed
if git diff --quiet && git diff --cached --quiet; then
echo "No version changes to commit"
exit 0
fi
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
git config --local user.name "gitea-actions[bot]"
git remote set-url origin "https://jmiller:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
git add -A
git commit -m "chore(version): patch bump to ${VERSION} [skip ci]" \
--author="gitea-actions[bot] <gitea-actions[bot]@mokoconsulting.tech>"
git push origin dev
echo "Bumped to ${VERSION}" >> $GITHUB_STEP_SUMMARY
File diff suppressed because it is too large Load Diff
-139
View File
@@ -1,139 +0,0 @@
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: moko-platform.Deploy
# REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
# PATH: /templates/workflows/joomla/deploy-manual.yml.template
# VERSION: 04.07.00
# BRIEF: Manual SFTP deploy to dev server for Joomla repos
name: "Universal: Deploy to Dev (Manual)"
on:
workflow_dispatch:
inputs:
clear_remote:
description: 'Delete all remote files before uploading'
required: false
default: 'false'
type: boolean
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
permissions:
contents: read
jobs:
deploy:
name: SFTP Deploy to Dev
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Setup PHP
run: |
php -v && composer --version
- name: Setup moko-platform tools
env:
GA_TOKEN: ${{ secrets.GA_TOKEN || secrets.GA_TOKEN || github.token }}
MOKO_CLONE_TOKEN: ${{ secrets.GA_TOKEN || secrets.GA_TOKEN || github.token }}
MOKO_CLONE_HOST: ${{ secrets.GA_TOKEN && 'git.mokoconsulting.tech/MokoConsulting' || 'github.com/mokoconsulting-tech' }}
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GA_TOKEN || github.token }}"}}'
run: |
git clone --depth 1 --branch main --quiet \
"https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git" \
/tmp/moko-platform-api 2>/dev/null || true
if [ -d "/tmp/moko-platform-api" ] && [ -f "/tmp/moko-platform-api/composer.json" ]; then
cd /tmp/moko-platform-api && composer install --no-dev --no-interaction --quiet 2>/dev/null || true
fi
- name: Check FTP configuration
id: check
env:
HOST: ${{ vars.DEV_FTP_HOST }}
PATH_VAR: ${{ vars.DEV_FTP_PATH }}
PORT: ${{ vars.DEV_FTP_PORT }}
run: |
if [ -z "$HOST" ] || [ -z "$PATH_VAR" ]; then
echo "DEV_FTP_HOST or DEV_FTP_PATH not configured -- cannot deploy"
echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "skip=false" >> "$GITHUB_OUTPUT"
echo "host=$HOST" >> "$GITHUB_OUTPUT"
REMOTE="${PATH_VAR%/}"
echo "remote=$REMOTE" >> "$GITHUB_OUTPUT"
[ -z "$PORT" ] && PORT="22"
echo "port=$PORT" >> "$GITHUB_OUTPUT"
- name: Deploy via SFTP
if: steps.check.outputs.skip != 'true'
env:
SFTP_KEY: ${{ secrets.DEV_FTP_KEY }}
SFTP_PASS: ${{ secrets.DEV_FTP_PASSWORD }}
SFTP_USER: ${{ vars.DEV_FTP_USERNAME }}
run: |
SOURCE_DIR="src"
[ ! -d "$SOURCE_DIR" ] && SOURCE_DIR="htdocs"
[ ! -d "$SOURCE_DIR" ] && { echo "No src/ or htdocs/ -- nothing to deploy"; exit 0; }
printf '{"host":"%s","port":%s,"username":"%s","remotePath":"%s"' \
"${{ steps.check.outputs.host }}" "${{ steps.check.outputs.port }}" "$SFTP_USER" "${{ steps.check.outputs.remote }}" \
> /tmp/sftp-config.json
if [ -n "$SFTP_KEY" ]; then
echo "$SFTP_KEY" > /tmp/deploy_key
chmod 600 /tmp/deploy_key
printf ',"privateKeyPath":"/tmp/deploy_key"}' >> /tmp/sftp-config.json
else
printf ',"password":"%s"}' "$SFTP_PASS" >> /tmp/sftp-config.json
fi
DEPLOY_ARGS=(--path . --src-dir "$SOURCE_DIR" --config /tmp/sftp-config.json)
[ "${{ inputs.clear_remote }}" = "true" ] && DEPLOY_ARGS+=(--clear-remote)
PLATFORM=$(php /tmp/moko-platform-api/cli/platform_detect.php --path . 2>/dev/null || true)
if [ "$PLATFORM" = "waas-component" ] && [ -f "/tmp/moko-platform-api/deploy/deploy-joomla.php" ]; then
php /tmp/moko-platform-api/deploy/deploy-joomla.php "${DEPLOY_ARGS[@]}"
else
php /tmp/moko-platform-api/deploy/deploy-sftp.php "${DEPLOY_ARGS[@]}"
fi
rm -f /tmp/deploy_key /tmp/sftp-config.json
- name: Post-deploy health check
if: success() && steps.check.outputs.skip != 'true'
run: |
if [ -f "deploy/health-check.php" ]; then
SITE_URL="${{ vars.DEV_SITE_URL }}"
if [ -n "$SITE_URL" ]; then
php deploy/health-check.php --url "$SITE_URL" --checks http --timeout 30 || echo "::warning::Health check failed after deploy"
else
echo "DEV_SITE_URL not configured, skipping health check"
fi
fi
- name: Summary
if: always()
run: |
if [ "${{ steps.check.outputs.skip }}" = "true" ]; then
echo "### Deploy Skipped -- FTP not configured" >> $GITHUB_STEP_SUMMARY
else
echo "### Manual Dev Deploy Complete" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| Host | \`${{ steps.check.outputs.host }}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Remote | \`${{ steps.check.outputs.remote }}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Clear | ${{ inputs.clear_remote }} |" >> $GITHUB_STEP_SUMMARY
fi
+36 -127
View File
@@ -52,28 +52,19 @@ jobs:
fetch-depth: 0
token: ${{ secrets.GA_TOKEN }}
- name: Setup tools
- name: Setup moko-platform tools
env:
MOKO_CLONE_TOKEN: ${{ secrets.GA_TOKEN }}
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
run: |
# Update moko-platform CLI tools if available; install PHP if missing
if command -v moko-platform-update &> /dev/null; then
moko-platform-update
elif [ -d "/opt/moko-platform" ]; then
cd /opt/moko-platform && git pull origin main --quiet 2>/dev/null || true
else
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 >/dev/null 2>&1
fi
git clone --depth 1 --branch main --quiet \
"https://x-access-token:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/moko-platform.git" \
/tmp/moko-platform-api
fi
# Set MOKO_CLI to whichever path exists
if [ -d "/opt/moko-platform/cli" ]; then
echo "MOKO_CLI=/opt/moko-platform/cli" >> "$GITHUB_ENV"
else
echo "MOKO_CLI=/tmp/moko-platform-api/cli" >> "$GITHUB_ENV"
if ! command -v composer &> /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
git clone --depth 1 --branch main --quiet \
"https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git" \
/tmp/moko-platform-api
cd /tmp/moko-platform-api && composer install --no-dev --no-interaction --quiet
echo "MOKO_CLI=/tmp/moko-platform-api/cli" >> "$GITHUB_ENV"
- name: Detect platform
id: platform
@@ -92,8 +83,7 @@ jobs:
release-candidate) SUFFIX="-rc"; TAG="release-candidate" ;;
esac
# Patch bump via CLI tool
php ${MOKO_CLI}/version_bump.php --path .
# Read current version (bump already handled by push workflow)
VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null)
[ -z "$VERSION" ] && VERSION="00.00.01"
@@ -130,131 +120,50 @@ jobs:
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
echo "zip_name=${ZIP_NAME}" >> "$GITHUB_OUTPUT"
echo "ext_element=${EXT_ELEMENT}" >> "$GITHUB_OUTPUT"
echo "manifest=${MANIFEST}" >> "$GITHUB_OUTPUT"
echo "=== Pre-Release: ${EXT_ELEMENT} ${VERSION}${SUFFIX} ==="
- name: Build package
run: |
SOURCE_DIR="src"
[ ! -d "$SOURCE_DIR" ] && SOURCE_DIR="htdocs"
if [ ! -d "$SOURCE_DIR" ]; then
echo "::error::No src/ or htdocs/ directory"
exit 1
fi
MANIFEST="${{ steps.meta.outputs.manifest }}"
EXT_TYPE=""
if [ -n "$MANIFEST" ]; then
EXT_TYPE=$(sed -n 's/.*<extension[^>]*type="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1)
fi
EXCLUDES="sftp-config* .ftpignore *.ppk *.pem *.key .env* *.local .build-trigger"
mkdir -p build/package
if [ "$EXT_TYPE" = "package" ] && [ -d "${SOURCE_DIR}/packages" ]; then
echo "=== Building Joomla PACKAGE (multi-extension) ==="
for ext_dir in "${SOURCE_DIR}"/packages/*/; do
[ ! -d "$ext_dir" ] && continue
EXT_NAME=$(basename "$ext_dir")
echo " Packaging sub-extension: ${EXT_NAME}"
cd "$ext_dir"
zip -r "../../build/package/${EXT_NAME}.zip" . -x $EXCLUDES
cd "$OLDPWD"
done
for f in "${SOURCE_DIR}"/*.xml "${SOURCE_DIR}"/*.php; do
[ -f "$f" ] && cp "$f" build/package/
done
else
echo "=== Building standard extension ==="
rsync -a \
--exclude='sftp-config*' \
--exclude='.ftpignore' \
--exclude='*.ppk' \
--exclude='*.pem' \
--exclude='*.key' \
--exclude='.env*' \
--exclude='*.local' \
--exclude='.build-trigger' \
"${SOURCE_DIR}/" build/package/
fi
- name: Create ZIP
id: zip
run: |
ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
cd build/package
zip -r "../${ZIP_NAME}" .
cd ..
SHA256=$(sha256sum "${ZIP_NAME}" | cut -d' ' -f1)
echo "sha256=${SHA256}" >> "$GITHUB_OUTPUT"
echo "ZIP: ${ZIP_NAME} (SHA: ${SHA256:0:16}...)"
- name: Create or replace Gitea release
- name: Create release
id: release
run: |
TAG="${{ steps.meta.outputs.tag }}"
VERSION="${{ steps.meta.outputs.version }}"
STABILITY="${{ steps.meta.outputs.stability }}"
SHA256="${{ steps.zip.outputs.sha256 }}"
ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
EXT_ELEMENT="${{ steps.meta.outputs.ext_element }}"
TOKEN="${{ secrets.GA_TOKEN }}"
API="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
BRANCH=$(git branch --show-current)
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
php ${MOKO_CLI}/release_create.php \
--path . --version "$VERSION" --tag "$TAG" \
--token "${{ secrets.GA_TOKEN }}" --api-base "$API_BASE" \
--repo "${GITEA_REPO}" --branch dev --prerelease
BODY="## ${VERSION} ($(date +%Y-%m-%d))
**Channel:** ${STABILITY}
**SHA-256:** \`${SHA256}\`"
# Delete existing release
EXISTING_ID=$(curl -sS -H "Authorization: token ${TOKEN}" \
"${API}/releases/tags/${TAG}" | jq -r '.id // empty' 2>/dev/null)
if [ -n "$EXISTING_ID" ]; then
curl -sS -X DELETE -H "Authorization: token ${TOKEN}" \
"${API}/releases/${EXISTING_ID}" 2>/dev/null || true
curl -sS -X DELETE -H "Authorization: token ${TOKEN}" \
"${API}/tags/${TAG}" 2>/dev/null || true
fi
# Create release
RELEASE_ID=$(curl -sS -X POST -H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \
"${API}/releases" \
-d "$(jq -n \
--arg tag "$TAG" \
--arg target "$BRANCH" \
--arg name "${EXT_ELEMENT} ${VERSION} (${STABILITY})" \
--arg body "$BODY" \
'{tag_name: $tag, target_commitish: $target, name: $name, body: $body, prerelease: true}'
)" | jq -r '.id')
echo "release_id=${RELEASE_ID}" >> "$GITHUB_OUTPUT"
# Upload ZIP
curl -sS -X POST -H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/octet-stream" \
"${API}/releases/${RELEASE_ID}/assets?name=${ZIP_NAME}" \
--data-binary "@build/${ZIP_NAME}"
echo "Released: ${EXT_ELEMENT} ${VERSION} (${STABILITY})"
- name: Build package and upload
id: package
run: |
VERSION="${{ steps.meta.outputs.version }}"
TAG="${{ steps.meta.outputs.tag }}"
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
php ${MOKO_CLI}/release_package.php \
--path . --version "$VERSION" --tag "$TAG" \
--token "${{ secrets.GA_TOKEN }}" --api-base "$API_BASE" \
--repo "${GITEA_REPO}" --output /tmp || true
- name: Update updates.xml
if: steps.platform.outputs.platform == 'joomla'
run: |
VERSION="${{ steps.meta.outputs.version }}"
STABILITY="${{ steps.meta.outputs.stability }}"
SHA256="${{ steps.package.outputs.sha256_zip }}"
if [ ! -f "updates.xml" ]; then
echo "No updates.xml -- skipping"
exit 0
fi
SHA_FLAG=""
[ -n "$SHA256" ] && SHA_FLAG="--sha ${SHA256}"
php ${MOKO_CLI}/updates_xml_build.php \
--path . --version "${VERSION}" --stability "${STABILITY}" \
--gitea-url "${GITEA_URL}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}"
--gitea-url "${GITEA_URL}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}" \
${SHA_FLAG}
# Commit and push
if ! git diff --quiet updates.xml 2>/dev/null; then
@@ -276,7 +185,7 @@ jobs:
[ "$BRANCH" = "$CURRENT_BRANCH" ] && continue
echo "Syncing updates.xml -> ${BRANCH}"
git fetch origin "${BRANCH}" 2>/dev/null || continue
git checkout "origin/${BRANCH}" -- . 2>/dev/null || continue
git checkout "origin/${BRANCH}" -- updates.xml 2>/dev/null || continue
git checkout "${CURRENT_BRANCH}" -- updates.xml
if ! git diff --quiet updates.xml 2>/dev/null; then
git add updates.xml
@@ -303,7 +212,7 @@ jobs:
VERSION="${{ steps.meta.outputs.version }}"
STABILITY="${{ steps.meta.outputs.stability }}"
ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
SHA256="${{ steps.zip.outputs.sha256 }}"
SHA256="${{ steps.package.outputs.sha256_zip }}"
echo "## Pre-Release Complete" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
File diff suppressed because it is too large Load Diff
+34
View File
@@ -18,6 +18,40 @@ Version format: `XX.YY.ZZ` (zero-padded semver).
## [Unreleased]
### Added
- `auto-bump.yml`: auto patch-bump version on every push to dev
- Removed redundant bump from pre-release.yml (handled by auto-bump)
## [09.02.00] - 2026-05-26
### Added
- **Release promotion pipeline**: draft PR → RC promotion, merged PR → RC-to-stable (skip rebuild)
- **7 new CLI tools**: `manifest_element.php`, `release_create.php`, `release_package.php`, `release_promote.php`, `release_mirror.php`, `version_reset_dev.php`, `ManifestReader.php`
- `version_bump.php` / `version_read.php`: support for `package.json` (Node.js) and `pyproject.toml` (Python)
- `version_bump.php`: now writes bumped version to all sources (README, manifests, Dolibarr mod, composer.json, package.json, pyproject.toml)
- `release_cascade.php`: `--version` flag for version-aware deletion of stale releases
- `release_validate.php`: auto-detect platform from manifest.xml, `--github-output` flag, source dir check
- `updates_xml_build.php`: supports non-Joomla platforms via manifest.xml detection
- `release_package.php`: reads entry-point from manifest.xml for source dir resolution
- `auto-release.yml`: `workflow_dispatch` with `promote-rc` action as fallback for MokoGitea#220
- `update-server.yml`: now universal — pushed to all 69+ repos (Joomla, Dolibarr, generic, MCP)
- `ManifestReader.php`: shared typed accessor for `.mokogitea/manifest.xml`
- Universal workflow cascade: Template-Generic → other templates → all repos via `bulk_sync.php`
- Wiki: UPDATE_SERVER standard page on moko-platform and all template repos
- PHPDoc added to 4 classes missing class-level docs
### Changed
- `auto-release.yml`: 761 → 490 lines — replaced all inline bash with CLI tool calls
- `pre-release.yml`: 389 → 314 lines — replaced inline logic with `manifest_read.php`, `manifest_element.php`, `updates_xml_build.php`
- Removed `paths` filter from workflow triggers (enables Go, Node.js, generic repo compatibility)
- `RepositorySynchronizer.php`: fixed template repo names, `.mokogitea/workflows` path, universal workflow sync
- Template-Generic is now the single source of truth for universal workflows
### Fixed
- `release_cascade.php` in `auto-release.yml`: was using `--org`/`--repo` flags instead of `--api-base`
- `pre-release.yml`: updates.xml sync was checking out entire branch tree instead of just `updates.xml`
- MokoWaaS#48: Joomla 6 typed event API fix for `plg_webservices_mokowaas`
## [09.00.00] - 2026-05-26
### Added
+1 -1
View File
@@ -6,7 +6,7 @@ DEFGROUP: MokoStandards.Root
INGROUP: MokoStandards
REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
PATH: /README.md
VERSION: 09.01.00
VERSION: 09.02.05
BRIEF: Project overview and documentation
-->
+19
View File
@@ -413,6 +413,17 @@ if ($isJoomlaPackage) {
}
}
// Include top-level directories (e.g. language/) that aren't packages/
$topLevelDirs = glob("{$sourceDir}/*", GLOB_ONLYDIR) ?: [];
foreach ($topLevelDirs as $tlDir) {
$dirName = basename($tlDir);
if ($dirName === 'packages') {
continue;
}
addDirToZip($zip, $tlDir, $dirName, $excludePatterns);
echo " Included dir: {$dirName}/\n";
}
$zip->close();
echo "ZIP created: {$zipFile}\n";
} else {
@@ -474,6 +485,14 @@ file_put_contents($tarSha, "{$tarHash} {$baseName}.tar.gz\n");
echo "SHA-256 (ZIP): {$zipHash}\n";
echo "SHA-256 (TAR): {$tarHash}\n";
echo "sha256_zip={$zipHash}\n";
echo "zip_name={$baseName}.zip\n";
// Write to GITHUB_OUTPUT if available
$ghOutput = getenv('GITHUB_OUTPUT');
if ($ghOutput) {
file_put_contents($ghOutput, "sha256_zip={$zipHash}\nzip_name={$baseName}.zip\n", FILE_APPEND);
}
// ── Get release ID from tag ──────────────────────────────────────────────────
+42 -6
View File
@@ -30,7 +30,7 @@ $mokoManifest = "{$root}/.mokogitea/manifest.xml";
$mokoContent = '';
if (file_exists($mokoManifest)) {
$mokoContent = file_get_contents($mokoManifest);
if (preg_match('|<version>(\d{2}\.\d{2}\.\d{2})</version>|', $mokoContent, $m)) {
if (preg_match('|<version>(\d{2}\.\d{2}\.\d{2})(?:-([a-z]+))?</version>|', $mokoContent, $m)) {
$mokoVersion = $m[1];
}
}
@@ -56,15 +56,17 @@ $manifestFiles = array_merge(
glob("{$root}/*.xml") ?: []
);
$manifestSuffix = '';
foreach ($manifestFiles as $xmlFile) {
$xmlContent = file_get_contents($xmlFile);
if (strpos($xmlContent, '<extension') === false && strpos($xmlContent, '<version>') === false) {
continue;
}
if (preg_match('|<version>(\d{2}\.\d{2}\.\d{2})(?:-[a-z]+)?</version>|', $xmlContent, $xm)) {
if (preg_match('|<version>(\d{2}\.\d{2}\.\d{2})(?:-([a-z]+))?</version>|', $xmlContent, $xm)) {
$candidate = $xm[1];
if ($manifestVersion === null || version_compare($candidate, $manifestVersion, '>')) {
$manifestVersion = $candidate;
$manifestSuffix = isset($xm[2]) ? $xm[2] : '';
}
}
}
@@ -106,10 +108,14 @@ switch ($type) {
$new = sprintf('%02d.%02d.%02d', $major, $minor, $patch);
// -- Update .mokogitea/manifest.xml (canonical target) --
// -- Determine suffix to preserve (from whichever source had the version) --
$suffix = !empty($manifestSuffix) ? $manifestSuffix : '';
$newFull = $suffix !== '' ? "{$new}-{$suffix}" : $new;
// -- Update .mokogitea/manifest.xml (canonical target, no suffix) --
if (file_exists($mokoManifest) && !empty($mokoContent)) {
$updated = preg_replace(
'|<version>\d{2}\.\d{2}\.\d{2}</version>|',
'|<version>\d{2}\.\d{2}\.\d{2}(?:-[a-z]+)?</version>|',
"<version>{$new}</version>",
$mokoContent,
1
@@ -146,7 +152,7 @@ foreach ($xmlPatterns as $pattern) {
}
$newContent = preg_replace(
'|<version>\d{2}\.\d{2}\.\d{2}(?:-[a-z]+)?</version>|',
"<version>{$new}</version>",
"<version>{$newFull}</version>",
$content
);
if ($newContent !== $content) {
@@ -160,5 +166,35 @@ if (!empty($updatedFiles)) {
fwrite(STDERR, "Updated " . count($updatedFiles) . " Joomla manifest(s): " . implode(', ', $updatedFiles) . "\n");
}
echo "{$old} -> {$new}\n";
// -- Update package.json (Node.js / MCP) --
$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}',
$pkgContent
);
if ($updatedPkg !== $pkgContent) {
file_put_contents($packageJsonFile, $updatedPkg);
fwrite(STDERR, "Updated package.json\n");
}
}
// -- Update pyproject.toml (Python) --
$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}',
$pyContent
);
if ($updatedPy !== $pyContent) {
file_put_contents($pyprojectFile, $updatedPy);
fwrite(STDERR, "Updated pyproject.toml\n");
}
}
echo "{$old} -> {$newFull}\n";
exit(0);
+44 -9
View File
@@ -54,6 +54,7 @@ if (file_exists($readme)) {
// -- 3. Fallback: Joomla manifest XML --
$manifestVersion = null;
$manifestVersionSuffix = '';
$manifestFiles = array_merge(
glob("{$root}/src/pkg_*.xml") ?: [],
glob("{$root}/src/*.xml") ?: [],
@@ -66,31 +67,65 @@ foreach ($manifestFiles as $xmlFile) {
if (strpos($xmlContent, '<extension') === false && strpos($xmlContent, '<version>') === false) {
continue;
}
if (preg_match('|<version>(\d{2}\.\d{2}\.\d{2})(?:-[a-z]+)?</version>|', $xmlContent, $xm)) {
if (preg_match('|<version>(\d{2}\.\d{2}\.\d{2})(-[a-z]+)?</version>|', $xmlContent, $xm)) {
$candidate = $xm[1];
$candidateSuffix = isset($xm[2]) ? $xm[2] : '';
if ($manifestVersion === null || version_compare($candidate, $manifestVersion, '>')) {
$manifestVersion = $candidate;
$manifestVersionSuffix = $candidateSuffix;
}
}
}
// -- 4. Fallback: package.json (Node.js / MCP) --
$packageJsonVersion = null;
$packageJsonFile = "{$root}/package.json";
if (file_exists($packageJsonFile)) {
$pkgData = json_decode(file_get_contents($packageJsonFile), true);
if (isset($pkgData['version']) && preg_match('/^\d{2}\.\d{2}\.\d{2}$/', $pkgData['version'])) {
$packageJsonVersion = $pkgData['version'];
}
}
// -- 5. Fallback: pyproject.toml (Python) --
$pyprojectVersion = null;
$pyprojectFile = "{$root}/pyproject.toml";
if (file_exists($pyprojectFile)) {
$pyContent = file_get_contents($pyprojectFile);
if (preg_match('/^version\s*=\s*"(\d{2}\.\d{2}\.\d{2})"/m', $pyContent, $pm)) {
$pyprojectVersion = $pm[1];
}
}
// -- Output the higher version --
$candidates = array_filter([
$readmeVersion,
$manifestVersion,
$packageJsonVersion,
$pyprojectVersion,
]);
$version = null;
if ($readmeVersion !== null && $manifestVersion !== null) {
$version = version_compare($manifestVersion, $readmeVersion, '>') ? $manifestVersion : $readmeVersion;
} elseif ($manifestVersion !== null) {
$version = $manifestVersion;
} elseif ($readmeVersion !== null) {
$version = $readmeVersion;
$versionSource = '';
foreach ($candidates as $candidate) {
if ($version === null || version_compare($candidate, $version, '>')) {
$version = $candidate;
$versionSource = ($candidate === $manifestVersion) ? 'manifest' : 'other';
}
}
if ($version === null) {
fwrite(STDERR, "No version found in manifest.xml, README.md, or Joomla XML\n");
fwrite(STDERR, "No version found in manifest.xml, README.md, Joomla XML, package.json, or pyproject.toml\n");
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 <version>, insert it --
if ($mokoVersion === null && file_exists($mokoManifest)) {
if (file_exists($mokoManifest)) {
$content = file_get_contents($mokoManifest);
if (!preg_match('|<version>\d{2}\.\d{2}\.\d{2}</version>|', $content)) {
if (strpos($content, '<license') !== false) {
+126 -30
View File
@@ -1,4 +1,28 @@
name: Deploy Dolibarr Module
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: moko-platform.Deploy
# REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
# PATH: /templates/workflows/deploy-module.yml
# VERSION: 02.00.00
# BRIEF: Deploy Dolibarr module to dev, demo, or live environments
#
# Secrets required:
# GA_TOKEN - Gitea API token for repo access
# DEPLOY_SSH_KEY - SSH private key for server access
# LIVE_TARGETS - JSON array of live instances (optional), e.g.:
# [{"host":"client1.example.com","user":"deploy",
# "mods_dir":"/path/MokoDoliMods",
# "custom_dir":"/path/htdocs/custom"}]
#
# Variables required:
# DEV_HOST, DEV_USER, DEV_MODS_DIR, DEV_CUSTOM_DIR
# DEMO_HOST, DEMO_USER, DEMO_MODS_DIR, DEMO_CUSTOM_DIR
name: "Dolibarr: Deploy Module"
on:
workflow_dispatch:
@@ -7,30 +31,26 @@ on:
description: 'Module repo name (e.g. MokoCRM, MokoDoliSign)'
required: true
server:
description: 'Target server'
description: 'Target environment'
required: true
default: 'dev'
type: choice
options:
- dev
- demo
- both
- live
- dev+demo
- all
env:
GITEA_URL: https://git.mokoconsulting.tech
ORG: MokoConsulting
DEV_HOST: waas.dev.mokoconsulting.tech
DEV_USER: mokoconsulting_dev
DEV_MODS_DIR: /home/mokoconsulting_dev/MokoDoliMods
DEV_CUSTOM_DIR: /home/mokoconsulting_dev/crm.dev.mokoconsulting.tech/htdocs/custom
DEMO_HOST: waas.demo.mokoconsulting.tech
DEMO_USER: mokoconsulting_demo
DEMO_MODS_DIR: /home/mokoconsulting_demo/MokoDoliMods
DEMO_CUSTOM_DIR: /home/mokoconsulting_demo/crm.demo.mokoconsulting.tech/htdocs/custom
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
ORG: ${{ vars.GITEA_ORG || 'MokoConsulting' }}
jobs:
deploy:
name: Deploy ${{ inputs.module_repo }} to ${{ inputs.server }}
runs-on: ubuntu-latest
steps:
- name: Validate module repo
run: |
@@ -39,11 +59,11 @@ jobs:
-H "Authorization: token ${{ secrets.GA_TOKEN }}" \
"${GITEA_URL}/api/v1/repos/${ORG}/${REPO}")
if [ "$STATUS" != "200" ]; then
echo "ERROR: ${ORG}/${REPO} not found"; exit 1
echo "::error::${ORG}/${REPO} not found (HTTP ${STATUS})"
exit 1
fi
echo "REPO=${REPO}" >> $GITHUB_ENV
# Derive symlink name
LINK_NAME=$(echo "$REPO" | sed 's/MokoDoli//;s/Moko//' | tr '[:upper:]' '[:lower:]')
[ "$REPO" = "MokoCRM" ] && LINK_NAME="mokocrm"
[ "$REPO" = "MokoDoliProjTemplate" ] && LINK_NAME="mokoprojtemplate"
@@ -56,27 +76,27 @@ jobs:
"${GITEA_URL}/api/v1/repos/${ORG}/${{ env.REPO }}/tags?limit=1")
TAG=$(echo "$TAGS" | jq -r '.[0].name // empty')
echo "TAG=${TAG}" >> $GITHUB_ENV
[ -n "$TAG" ] && echo "Deploying: $TAG" || echo "No tags deploying main"
[ -n "$TAG" ] && echo "Deploying: $TAG" || echo "No tags - deploying main"
- name: Deploy to dev
if: inputs.server == 'dev' || inputs.server == 'both'
if: inputs.server == 'dev' || inputs.server == 'dev+demo' || inputs.server == 'all'
uses: appleboy/ssh-action@v1
with:
host: ${{ env.DEV_HOST }}
username: ${{ env.DEV_USER }}
host: ${{ vars.DEV_HOST }}
username: ${{ vars.DEV_USER }}
key: ${{ secrets.DEPLOY_SSH_KEY }}
script: |
REPO="${{ env.REPO }}"
LINK="${{ env.LINK_NAME }}"
TAG="${{ env.TAG }}"
MODS="${{ env.DEV_MODS_DIR }}"
CUSTOM="${{ env.DEV_CUSTOM_DIR }}"
MODS="${{ vars.DEV_MODS_DIR }}"
CUSTOM="${{ vars.DEV_CUSTOM_DIR }}"
mkdir -p "$MODS" && cd "$MODS"
if [ -d "$REPO" ]; then
cd "$REPO" && git fetch --tags origin
else
git clone "https://git.mokoconsulting.tech/${{ env.ORG }}/${REPO}.git"
git clone "${{ env.GITEA_URL }}/${{ env.ORG }}/${REPO}.git"
cd "$REPO"
fi
@@ -90,27 +110,27 @@ jobs:
cd "$CUSTOM"
[ -L "$LINK" ] || [ -d "$LINK" ] && rm -rf "$LINK"
ln -sf "$MODS/$REPO/src" "$LINK"
echo "OK: $LINK $MODS/$REPO/src (${TAG:-main})"
echo "OK: $LINK -> $MODS/$REPO/src (${TAG:-main})"
- name: Deploy to demo
if: inputs.server == 'demo' || inputs.server == 'both'
if: inputs.server == 'demo' || inputs.server == 'dev+demo' || inputs.server == 'all'
uses: appleboy/ssh-action@v1
with:
host: ${{ env.DEMO_HOST }}
username: ${{ env.DEMO_USER }}
host: ${{ vars.DEMO_HOST }}
username: ${{ vars.DEMO_USER }}
key: ${{ secrets.DEPLOY_SSH_KEY }}
script: |
REPO="${{ env.REPO }}"
LINK="${{ env.LINK_NAME }}"
TAG="${{ env.TAG }}"
MODS="${{ env.DEMO_MODS_DIR }}"
CUSTOM="${{ env.DEMO_CUSTOM_DIR }}"
MODS="${{ vars.DEMO_MODS_DIR }}"
CUSTOM="${{ vars.DEMO_CUSTOM_DIR }}"
mkdir -p "$MODS" && cd "$MODS"
if [ -d "$REPO" ]; then
cd "$REPO" && git fetch --tags origin
else
git clone "https://git.mokoconsulting.tech/${{ env.ORG }}/${REPO}.git"
git clone "${{ env.GITEA_URL }}/${{ env.ORG }}/${REPO}.git"
cd "$REPO"
fi
@@ -124,4 +144,80 @@ jobs:
cd "$CUSTOM"
[ -L "$LINK" ] || [ -d "$LINK" ] && rm -rf "$LINK"
ln -sf "$MODS/$REPO/src" "$LINK"
echo "OK: $LINK $MODS/$REPO/src (${TAG:-main})"
echo "OK: $LINK -> $MODS/$REPO/src (${TAG:-main})"
- name: Deploy to live
if: inputs.server == 'live' || inputs.server == 'all'
env:
LIVE_TARGETS: ${{ secrets.LIVE_TARGETS }}
DEPLOY_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
run: |
if [ -z "$LIVE_TARGETS" ] || [ "$LIVE_TARGETS" = "null" ]; then
echo "::error::LIVE_TARGETS secret is not configured."
echo "Set it to a JSON array of target objects."
exit 1
fi
COUNT=$(echo "$LIVE_TARGETS" | jq 'length')
echo "Deploying to ${COUNT} live instance(s)..."
echo "$DEPLOY_KEY" > /tmp/deploy_key
chmod 600 /tmp/deploy_key
FAILED=0
for i in $(seq 0 $((COUNT - 1))); do
HOST=$(echo "$LIVE_TARGETS" | jq -r ".[$i].host")
USER=$(echo "$LIVE_TARGETS" | jq -r ".[$i].user")
MODS=$(echo "$LIVE_TARGETS" | jq -r ".[$i].mods_dir")
CUSTOM=$(echo "$LIVE_TARGETS" | jq -r ".[$i].custom_dir")
PORT=$(echo "$LIVE_TARGETS" | jq -r ".[$i].port // 22")
LABEL=$(echo "$LIVE_TARGETS" | jq -r ".[$i].label // empty")
[ -z "$LABEL" ] && LABEL="$HOST"
echo ""
echo "=== Instance $((i+1))/${COUNT}: ${LABEL} (${USER}@${HOST}:${PORT}) ==="
ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=15 \
-i /tmp/deploy_key -p "$PORT" "${USER}@${HOST}" \
"REPO='${{ env.REPO }}' LINK='${{ env.LINK_NAME }}' TAG='${{ env.TAG }}' MODS='${MODS}' CUSTOM='${CUSTOM}' GITEA_URL='${{ env.GITEA_URL }}' ORG='${{ env.ORG }}' bash" <<'REMOTE_SCRIPT' || { echo "::warning::Failed: ${LABEL}"; FAILED=$((FAILED+1)); continue; }
mkdir -p "$MODS" && cd "$MODS"
if [ -d "$REPO" ]; then
cd "$REPO" && git fetch --tags origin
else
git clone "${GITEA_URL}/${ORG}/${REPO}.git"
cd "$REPO"
fi
if [ -n "$TAG" ]; then
git checkout "$TAG" --quiet
else
git checkout main --quiet
git pull --ff-only origin main --quiet
fi
cd "$CUSTOM"
[ -L "$LINK" ] || [ -d "$LINK" ] && rm -rf "$LINK"
ln -sf "$MODS/$REPO/src" "$LINK"
echo "OK: $LINK -> $MODS/$REPO/src (${TAG:-main})"
REMOTE_SCRIPT
done
rm -f /tmp/deploy_key
if [ "$FAILED" -gt 0 ]; then
echo "::error::${FAILED} of ${COUNT} live deployment(s) failed"
exit 1
fi
echo "All ${COUNT} live instance(s) deployed successfully."
- name: Summary
if: always()
run: |
echo "## Deploy: ${{ env.REPO }} -> ${{ inputs.server }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| Module | \`${{ env.REPO }}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Symlink | \`${{ env.LINK_NAME }}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Version | \`${{ env.TAG || 'main' }}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Target | \`${{ inputs.server }}\` |" >> $GITHUB_STEP_SUMMARY