Compare commits

...

159 Commits

Author SHA1 Message Date
jmiller 9a7d5b8359 Merge pull request 'chore: cascade main → dev (9c9a1a7) [skip ci]' (#61) from main into dev
chore: cascade main → dev [skip ci]
2026-05-26 23:47:22 +00:00
jmiller 9c9a1a7b52 Merge pull request 'fix: trusted IP session bypass + CI workflow syncs' (#60) from dev into main
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 3s
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 1s
2026-05-26 23:47:18 +00:00
gitea-actions[bot] 21de2fa115 chore(version): patch bump to 02.11.02 [skip ci]
Universal: Build & Release / Promote Pre-Release to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 13s
2026-05-26 23:46:20 +00:00
Jonathan Miller 9f1848d218 fix: move trusted IP session bypass to boot() for early execution
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Successful in 4s
Update Server / Update updates.xml (push) Failing after 8s
Joomla validates sessions during initialise(), before onAfterInitialise
fires. The previous ini_set approach ran too late — the session was
already expired. Now implements BootableExtensionInterface so the
session lifetime is extended before Joomla's session handler runs.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 18:43:13 -05:00
jmiller ecb456d91e chore(ci): update pre-release.yml from moko-platform [skip ci] 2026-05-26 22:50:50 +00:00
jmiller d9ce74cf38 chore(ci): update pre-release.yml from moko-platform [skip ci] 2026-05-26 22:50:50 +00:00
jmiller 91e9465233 chore(ci): update auto-bump.yml from moko-platform [skip ci] 2026-05-26 22:49:38 +00:00
jmiller 3bbaee7c86 chore(ci): update auto-bump.yml from moko-platform [skip ci] 2026-05-26 22:49:37 +00:00
jmiller d494e7366e chore(ci): update auto-release.yml from moko-platform [skip ci] 2026-05-26 22:48:25 +00:00
jmiller 05c3f5fd1f chore(ci): update auto-release.yml from moko-platform [skip ci] 2026-05-26 22:48:24 +00:00
jmiller c91b44ad34 chore(ci): update pre-release.yml from moko-platform [skip ci] 2026-05-26 22:36:53 +00:00
jmiller e86cc2b48b chore(ci): update pre-release.yml from moko-platform [skip ci] 2026-05-26 22:36:53 +00:00
jmiller c28c2de936 chore(ci): update auto-release.yml from moko-platform [skip ci] 2026-05-26 22:35:32 +00:00
jmiller 1a81267d38 chore(ci): update auto-release.yml from moko-platform [skip ci] 2026-05-26 22:35:31 +00:00
jmiller 343ef64ea2 chore(ci): update auto-bump.yml from moko-platform [skip ci] 2026-05-26 22:25:08 +00:00
jmiller f47a4d3c77 chore(ci): update auto-bump.yml from moko-platform [skip ci] 2026-05-26 22:25:08 +00:00
jmiller cfb05c5964 chore(ci): update auto-release.yml from moko-platform [skip ci] 2026-05-26 22:23:51 +00:00
jmiller ebbd1058f3 chore(ci): update auto-release.yml from moko-platform [skip ci] 2026-05-26 22:23:51 +00:00
jmiller 9e356fa4b5 chore(ci): update pre-release.yml from moko-platform [skip ci] 2026-05-26 22:13:16 +00:00
jmiller e030d85886 chore(ci): update pre-release.yml from moko-platform [skip ci] 2026-05-26 22:13:15 +00:00
jmiller ea9ac21d1a chore(ci): add auto-bump.yml from moko-platform [skip ci] 2026-05-26 22:12:03 +00:00
jmiller e256acbcbb chore(ci): add auto-bump.yml from moko-platform [skip ci] 2026-05-26 22:12:03 +00:00
jmiller b4d11df2a2 Merge pull request 'chore: cascade main → dev (2c0ed08) [skip ci]' (#59) from main into dev
chore: cascade main → dev [skip ci]
2026-05-26 21:44:02 +00:00
jmiller 2c0ed08368 Merge pull request 'feat: show current IP in security tab' (#58) from dev into main
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 2s
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 2s
2026-05-26 21:43:59 +00:00
jmiller 12fe6c196d chore: sync updates.xml from [skip ci] 2026-05-26 21:42:28 +00:00
gitea-actions[bot] 0415972c7d chore: update updates.xml (development: 02.11.01-dev) [skip ci]
Universal: Build & Release / Promote Pre-Release to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 12s
2026-05-26 21:42:27 +00:00
gitea-actions[bot] 6c7bb35ac3 chore(version): auto-bump patch 02.11.01 [skip ci] 2026-05-26 21:42:26 +00:00
Jonathan Miller 834b1325b5 Merge remote-tracking branch 'origin/main' into dev
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Blocked by required conditions
Joomla: Extension CI / PHPStan Analysis (pull_request) Blocked by required conditions
Joomla: Extension CI / Build RC Pre-Release (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Joomla: Repo Health / Release configuration (pull_request) Blocked by required conditions
Joomla: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Joomla: Repo Health / Repository health (pull_request) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 1s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Joomla: Repo Health / Access control (pull_request) Successful in 2s
Universal: PR Check / Validate PR (pull_request) Failing after 4s
Joomla: Extension CI / Release Readiness Check (pull_request) Successful in 5s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 4s
Universal: PR Check / Changelog Updated (pull_request) Successful in 4s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 6s
Update Server / Update updates.xml (push) Failing after 11s
# Conflicts:
#	.mokogitea/manifest.xml
#	.mokogitea/workflows/update-server.yml
#	README.md
#	src/packages/com_mokowaas/mokowaas.xml
#	src/packages/plg_system_mokowaas/mokowaas.xml
#	src/packages/plg_webservices_mokowaas/mokowaas.xml
#	src/pkg_mokowaas.xml
2026-05-26 16:42:01 -05:00
jmiller 4a1b2ea143 chore: sync updates.xml from [skip ci] 2026-05-26 21:30:16 +00:00
gitea-actions[bot] a748ee863c chore: update updates.xml (development: 02.10.06-dev) [skip ci] 2026-05-26 21:30:15 +00:00
gitea-actions[bot] 0546e1eaae chore(version): auto-bump patch 02.10.06 [skip ci] 2026-05-26 21:30:15 +00:00
Jonathan Miller 4595db209e feat: show current IP above trusted IPs table
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 2s
Update Server / Update updates.xml (push) Failing after 7s
Display the admin's current IP address with a hint to add it,
making it easy to configure trusted IP entries without looking
up the IP separately.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 16:29:56 -05:00
gitea-actions[bot] 3f3ff49573 chore(release): build 02.11.00 [skip ci] 2026-05-26 20:16:41 +00:00
jmiller 14318c90c2 chore: sync .mokogitea/workflows/update-server.yml from moko-platform [skip ci] 2026-05-26 20:12:32 +00:00
gitea-actions[bot] 3d79fe9aeb chore(release): build 02.10.05 [skip ci] 2026-05-26 20:12:26 +00:00
jmiller d2e24741af chore: sync .mokogitea/workflows/pre-release.yml from moko-platform [skip ci] 2026-05-26 20:10:36 +00:00
jmiller cb6582ef16 fix(ci): use release_package.php for Joomla package builds [skip ci] 2026-05-26 19:54:40 +00:00
jmiller d0c3a563d1 fix(ci): use release_package.php for Joomla package builds [skip ci] 2026-05-26 19:54:40 +00:00
jmiller 70b5c8de08 Merge pull request 'chore: cascade main → dev (a2eaf54) [skip ci]' (#56) from main into dev
chore: cascade main → dev [skip ci]
2026-05-26 19:44:26 +00:00
jmiller a2eaf549af Merge pull request 'feat: trusted IPs bypass admin session timeout' (#55) from dev into main
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 1s
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 2s
Merge pull request #55: feat: trusted IPs bypass admin session timeout
2026-05-26 19:44:22 +00:00
gitea-actions[bot] c97c29f9ed chore: update updates.xml (development: 02.10.05-dev) [skip ci]
Universal: Build & Release / Promote Pre-Release to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Failing after 9s
2026-05-26 19:40:54 +00:00
jmiller ea48f61f8c chore: sync updates.xml from [skip ci] 2026-05-26 19:40:54 +00:00
gitea-actions[bot] d92df704c4 chore(version): auto-bump patch 02.10.05 [skip ci] 2026-05-26 19:40:52 +00:00
Jonathan Miller ad4c658b3d feat: trusted IPs bypass admin session timeout
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 1s
Update Server / Update updates.xml (push) Failing after 11s
Add configurable repeatable rows of trusted IP addresses that bypass
the admin session timeout. Supports exact IPs, CIDR ranges, and
wildcard patterns with per-entry labels and enabled toggles.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 14:40:32 -05:00
jmiller 0788e8e2ab Merge pull request 'chore: cascade main → dev (a68e90d) [skip ci]' (#54) from main into dev
chore: cascade main → dev [skip ci]
2026-05-26 19:34:05 +00:00
Jonathan Miller a68e90df9d Merge dev: fix(joomla6) webservices plugin + updated workflows
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 1s
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 2s
2026-05-26 14:34:00 -05:00
jmiller bacc0eba19 chore: sync .mokogitea/workflows/update-server.yml from moko-platform [skip ci] 2026-05-26 19:03:56 +00:00
gitea-actions[bot] c8f4e38f6b chore(release): build 02.10.03 [skip ci] 2026-05-26 18:58:54 +00:00
jmiller 0dcb8a4a1d chore(ci): update pre-release.yml from moko-platform [skip ci] 2026-05-26 18:52:46 +00:00
jmiller fa31455619 chore(ci): update auto-release.yml from moko-platform [skip ci] 2026-05-26 18:52:45 +00:00
jmiller bf4dfac2a0 chore(ci): update pre-release.yml — remove paths filter [skip ci] 2026-05-26 18:51:33 +00:00
jmiller d3ceea0e80 chore(ci): update auto-release.yml — remove paths filter [skip ci] 2026-05-26 18:51:32 +00:00
jmiller 49a7418830 chore: sync updates.xml from [skip ci] 2026-05-26 18:42:43 +00:00
gitea-actions[bot] 1b9fc4e0f8 chore: update updates.xml (development: 02.10.04-dev) [skip ci] 2026-05-26 18:42:43 +00:00
gitea-actions[bot] 426853aef7 chore(version): auto-bump patch 02.10.04 [skip ci] 2026-05-26 18:42:41 +00:00
Jonathan Miller 3f20ad985c fix(joomla6): update webservices plugin for Joomla 6 typed event API
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 1s
Joomla: Update Server / Update updates.xml (push) Failing after 9s
Joomla 6 changed SubscriberInterface event handlers to receive a typed
event object instead of pass-by-reference parameters. Update
onBeforeApiRoute() to accept BeforeApiRouteEvent and extract the
router via $event->getRouter().

Fixes #48

Authored-by: Moko Consulting
2026-05-26 13:42:32 -05:00
jmiller ffa50f6460 fix: updates.xml all channels 02.11.00 [skip ci] 2026-05-26 17:41:23 +00:00
jmiller 08e2f171eb chore(ci): update auto-release.yml from moko-platform [skip ci] 2026-05-26 17:36:27 +00:00
jmiller 9d49968272 chore(ci): update pre-release.yml from moko-platform [skip ci] 2026-05-26 17:35:16 +00:00
jmiller be98c55e46 Merge pull request 'chore: cascade main → dev (c6c9b21) [skip ci]' (#47) from main into dev
chore: cascade main → dev [skip ci]
2026-05-26 17:27:08 +00:00
jmiller c6c9b217a1 Merge pull request 'Release 02.11.00: Help menu redirect, support URL fix, CI tag fixes' (#46) from dev into main
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 3s
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 1s
2026-05-26 17:27:03 +00:00
jmiller 657928a01a fix: stable download URL [skip ci]
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 12s
2026-05-26 12:12:33 -05:00
jmiller 91ad0353a6 fix: updates.xml version 02.09.00 [skip ci] 2026-05-26 12:12:33 -05:00
jmiller 431c907391 chore: sync updates.xml from [skip ci] 2026-05-26 17:11:07 +00:00
gitea-actions[bot] 38d5a8eb90 chore: update updates.xml (development: 02.10.03-dev) [skip ci] 2026-05-26 17:11:07 +00:00
gitea-actions[bot] 19ab206f56 chore(version): auto-bump patch 02.10.03 [skip ci] 2026-05-26 17:11:06 +00:00
Jonathan Miller 642aca10fe fix: default support URL to mokoconsulting.tech/support
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 1s
Joomla: Update Server / Update updates.xml (push) Failing after 9s
Updated manifest default, PHP fallbacks in MokoWaaS.php and script.php.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 12:10:57 -05:00
jmiller a5b6d7a42a chore: sync updates.xml from [skip ci] 2026-05-26 17:01:34 +00:00
gitea-actions[bot] 9003570c5a chore: update updates.xml (development: 02.10.02-dev) [skip ci] 2026-05-26 17:01:33 +00:00
gitea-actions[bot] c241463bb1 chore(version): auto-bump patch 02.10.02 [skip ci] 2026-05-26 17:01:33 +00:00
Jonathan Miller 317c4e900a feat: redirect admin Help menu to configured support URL
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 2s
Joomla: Update Server / Update updates.xml (push) Failing after 9s
Replaces hardcoded help.joomla.org and docs.joomla.org links in
the Atum template header with the WaaS support URL from plugin
config. Uses JS injection in onBeforeCompileHead.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 12:01:21 -05:00
jmiller e948074c6a chore: sync updates.xml from [skip ci] 2026-05-26 16:12:53 +00:00
gitea-actions[bot] 848f07429c chore: update updates.xml (development: 02.10.01-dev) [skip ci] 2026-05-26 16:12:53 +00:00
gitea-actions[bot] 203327f5ed chore(version): auto-bump patch 02.10.01 [skip ci] 2026-05-26 16:12:52 +00:00
Jonathan Miller 92261be464 chore: bump dev to 02.10.00 (ahead of main 02.09.00)
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 2s
Joomla: Update Server / Update updates.xml (push) Failing after 9s
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 11:12:40 -05:00
gitea-actions[bot] 28e61b8f8a chore(version): pre-release bump to 02.08.04 [skip ci] 2026-05-26 07:06:54 +00:00
jmiller 188db2d4b8 sync: update-server.yml with updates.xml integrity check [skip ci] 2026-05-26 04:47:46 +00:00
jmiller 1f0b4596ff sync: update-server.yml with updates.xml integrity check [skip ci] 2026-05-26 04:47:46 +00:00
jmiller 1ed11dca03 fix: stable download URL [skip ci] 2026-05-26 04:40:33 +00:00
jmiller ecc5d624d5 fix: updates.xml version 02.09.00 [skip ci] 2026-05-26 04:40:04 +00:00
jmiller dac39212d7 Merge pull request 'chore: cascade main → dev (43abc65) [skip ci]' (#45) from main into dev
chore: cascade main → dev [skip ci]
2026-05-26 04:37:41 +00:00
jmiller 43abc6514e Merge pull request 'Release 02.09.00: CI fixes, update server standard, Joomla skill' (#44) from dev into main
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 3s
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 1s
2026-05-26 04:37:36 +00:00
Jonathan Miller 8d42ef40c5 Merge remote-tracking branch 'origin/main' into dev
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 1s
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Blocked by required conditions
Joomla: Extension CI / PHPStan Analysis (pull_request) Blocked by required conditions
Joomla: Extension CI / Build RC Pre-Release (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Joomla: Repo Health / Release configuration (pull_request) Blocked by required conditions
Joomla: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Joomla: Repo Health / Repository health (pull_request) Blocked by required conditions
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Joomla: Repo Health / Access control (pull_request) Successful in 1s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 4s
Universal: PR Check / Validate PR (pull_request) Failing after 3s
Joomla: Extension CI / Release Readiness Check (pull_request) Successful in 4s
Universal: PR Check / Changelog Updated (pull_request) Successful in 3s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 5s
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 11s
# Conflicts:
#	.mokogitea/workflows/auto-release.yml
#	.mokogitea/workflows/pre-release.yml
#	README.md
#	src/packages/com_mokowaas/mokowaas.xml
#	src/packages/plg_system_mokowaas/mokowaas.xml
#	src/packages/plg_webservices_mokowaas/mokowaas.xml
#	src/pkg_mokowaas.xml
#	updates.xml
2026-05-25 23:37:11 -05:00
gitea-actions[bot] 0546dde89f chore(version): pre-release bump to 02.08.03 [skip ci] 2026-05-26 04:00:46 +00:00
jmiller 598ec0712c fix: updates.xml tag dev + client site [skip ci] 2026-05-26 03:52:18 +00:00
Jonathan Miller 6f9df77f79 fix(ci): remove dead XML_TAG code, CLI handles tag mapping
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 3s
The updates_xml_build.php CLI now maps 'development' → 'dev' internally.
Removed the dead shell case block that was setting XML_TAG (unused since
the inline PHP updater was replaced with the CLI).

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-25 22:51:19 -05:00
jmiller 89aaef14e7 fix: updates.xml same version all channels + client tag [skip ci] 2026-05-26 03:33:21 +00:00
gitea-actions[bot] f72cafe4d7 chore(version): pre-release bump to 02.08.02 [skip ci] 2026-05-26 03:26:36 +00:00
Jonathan Miller a965bcf0ef refactor(ci): clean up auto-release, move logic to CLI tools
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 1s
- Remove duplicate asset deletion loop (new loop handles all assets)
- Remove inline Python updates.xml updater (Step 5 CLI handles it)
- Remove dead Step 8 sync-to-main code (Step 5 commit+push handles it)
- Step 8b uses release_body_update.php CLI with fallback
- Step 6 tag creation always runs (removed never-set is_minor gate)
- Net: -154 lines, +25 lines

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-25 22:20:28 -05:00
Jonathan Miller bd6eec88af feat(ci): checksums as [filename].sha256 assets, not in release body
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 4s
Upload per-file .sha256 checksum files alongside packages instead of
embedding SHA-256 in the release description. Format: "hash  filename"
matching standard sha256sum output.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-25 22:11:53 -05:00
Jonathan Miller ce7e36f779 feat(ci): add version_check.php to pre-release and auto-release workflows
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 1s
Runs --fix mode after version bump to auto-correct any drift between
README.md and manifest XML files before building.

Refs: moko-platform#122

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-25 22:08:40 -05:00
jmiller 46b1469121 chore: sync .mokogitea/workflows/auto-release.yml from moko-platform [skip ci] 2026-05-26 03:07:18 +00:00
jmiller 1e936a67c4 chore: sync .mokogitea/workflows/pre-release.yml from moko-platform [skip ci] 2026-05-26 03:05:25 +00:00
jmiller 0903a4b335 fix: sync updates.xml with all channels and correct versions [skip ci] 2026-05-26 03:05:10 +00:00
gitea-actions[bot] a7823c6440 chore: update updates.xml (development: 02.08.01-dev) [skip ci] 2026-05-26 03:04:40 +00:00
jmiller ed720b2ea9 chore: sync updates.xml from [skip ci] 2026-05-26 03:04:40 +00:00
gitea-actions[bot] 263ac78515 chore(version): auto-bump patch 02.08.01 [skip ci] 2026-05-26 03:04:39 +00:00
Jonathan Miller b9f83c43bc chore: reset versions to 02.08.00, sync all update streams
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 1s
Joomla: Update Server / Update updates.xml (push) Successful in 9s
Dev is now ahead of main (02.07.00). All manifests, README, and
updates.xml aligned. Updates.xml has all 6 channels with correct
pkg_mokowaas element.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-25 22:04:25 -05:00
Jonathan Miller f4609088e3 fix(ci): auto-release preserves all update channels [skip ci]
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-25 21:56:10 -05:00
Jonathan Miller d9326ea34b fix(ci): auto-release fetches updates.xml from main before building
Joomla: Repo Health / Access control (push) Successful in 1s
Joomla: Repo Health / Release configuration (push) Failing after 8s
Joomla: Repo Health / Repository health (push) Failing after 9s
Joomla: Repo Health / Scripts governance (push) Successful in 12s
Preserves all existing channel entries (dev, alpha, beta, rc) when
adding/updating the stable entry. Previously the file on disk was
empty or stale, so the preserve logic had nothing to keep.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-25 21:54:42 -05:00
jmiller 6589adcf75 fix: restore all channel entries in updates.xml [skip ci] 2026-05-26 02:51:58 +00:00
jmiller 2e2c1b82b3 chore: sync updates.xml 02.07.00 [skip ci] 2026-05-26 02:50:57 +00:00
gitea-actions[bot] 0451fa2138 chore(version): pre-release bump to 02.06.04 [skip ci] 2026-05-26 02:50:52 +00:00
jmiller 66b90754f8 Merge pull request 'chore: cascade main → dev (e66b7e9) [skip ci]' (#43) from main into dev
chore: cascade main → dev [skip ci]
2026-05-26 02:50:37 +00:00
jmiller e66b7e9a79 Merge pull request 'Release 02.07.00: Update site fix, settings protection, master god privs' (#42) from dev into main
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 3s
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 6s
2026-05-26 02:49:08 +00:00
Jonathan Miller 4f056763e9 Merge remote-tracking branch 'origin/main' into dev
Joomla: Repo Health / Release configuration (pull_request) Blocked by required conditions
Joomla: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Joomla: Repo Health / Repository health (pull_request) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 2s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 5s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 6s
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Has been skipped
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Has been skipped
Joomla: Extension CI / PHPStan Analysis (pull_request) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Successful in 9s
Joomla: Repo Health / Access control (pull_request) Successful in 3s
Universal: PR Check / Validate PR (pull_request) Failing after 9s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 15s
Universal: PR Check / Changelog Updated (pull_request) Successful in 10s
Universal: PR Check / Build RC Package (pull_request) Has been skipped
Joomla: Update Server / Update updates.xml (push) Failing after 25s
Joomla: Extension CI / Build RC Pre-Release (pull_request) Has been skipped
Joomla: Repo Health / Release configuration (push) Failing after 6s
Joomla: Repo Health / Scripts governance (push) Successful in 5s
Joomla: Repo Health / Repository health (push) Failing after 5s
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 24s
# Conflicts:
#	README.md
#	updates.xml
2026-05-25 21:48:49 -05:00
jmiller de70224728 fix: updates.xml all entries use pkg_mokowaas element [skip ci] 2026-05-26 02:36:40 +00:00
gitea-actions[bot] 6f69af666f chore: update updates.xml (development: 02.05.05-dev) [skip ci] 2026-05-26 02:34:05 +00:00
jmiller 1f7278022c chore: sync updates.xml from [skip ci] 2026-05-26 02:34:05 +00:00
gitea-actions[bot] b5e8d3dfe2 chore(version): auto-bump patch 02.05.05 [skip ci] 2026-05-26 02:34:04 +00:00
Jonathan Miller 3edec0687c fix: re-enable update site disabled by Joomla's protected flag
Joomla: Repo Health / Access control (push) Successful in 1s
Joomla: Update Server / Update updates.xml (push) Successful in 8s
Joomla: Repo Health / Release configuration (push) Failing after 8s
Joomla: Repo Health / Scripts governance (push) Successful in 8s
Joomla: Repo Health / Repository health (push) Failing after 6s
Joomla automatically disables update sites for extensions with
protected=1. ensureProtectedFlag() now also checks and re-enables
the MokoWaaS update site each admin session.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-25 21:33:53 -05:00
jmiller a503e12ef9 fix: updates.xml with all channels (stable, rc, beta, alpha, dev, legacy) [skip ci] 2026-05-26 02:20:26 +00:00
Jonathan Miller ea60ac60ba fix(ci): pre-release uses updates_xml_build CLI with preserve logic
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 1s
The inline PHP regex approach only updated existing entries — if no
matching channel entry existed, nothing was added. Now uses the
moko-platform CLI which creates new entries and preserves other channels.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-25 21:18:22 -05:00
jmiller 825820f7b9 fix: add RC and legacy entries to updates.xml [skip ci] 2026-05-26 02:17:42 +00:00
gitea-actions[bot] ba4a806cd7 chore(version): pre-release bump to 02.06.03 [skip ci] 2026-05-26 02:09:25 +00:00
Jonathan Miller effd1fd588 fix(ci): use absolute paths in package build step [skip ci]
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-25 21:09:09 -05:00
Jonathan Miller bf2b01df2d fix(ci): use absolute paths in package build step
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 1s
Relative path ../../build/package/ broke when cd'd 3 levels deep into
src/packages/ext_name/. Now captures REPO_ROOT=$(pwd) and uses it
for zip output and cd back.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-25 21:08:41 -05:00
gitea-actions[bot] 4581088a0a chore(version): pre-release bump to 02.06.02 [skip ci] 2026-05-26 02:05:10 +00:00
gitea-actions[bot] 863dbb02f4 chore(version): pre-release bump to 02.06.01 [skip ci] 2026-05-26 02:01:47 +00:00
jmiller 8fd8015b19 chore: sync updates.xml 02.06.00 [skip ci] 2026-05-26 01:58:56 +00:00
jmiller 83ddbf0d73 Merge pull request 'chore: cascade main → dev (fad0170) [skip ci]' (#41) from main into dev
chore: cascade main → dev [skip ci]
2026-05-26 01:58:45 +00:00
jmiller fad0170cef Merge pull request 'Release 02.07.00-rc: Master god privs, settings protection, install API fix' (#40) from dev into main
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 6s
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 2s
2026-05-26 01:58:39 +00:00
jmiller a734d381ac chore: sync updates.xml from [skip ci] 2026-05-26 01:55:08 +00:00
gitea-actions[bot] 0b8f492613 chore: update updates.xml (development: 02.05.04-dev) [skip ci]
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 18s
2026-05-26 01:55:07 +00:00
gitea-actions[bot] 11c3488438 chore(version): auto-bump patch 02.05.04 [skip ci] 2026-05-26 01:55:06 +00:00
Jonathan Miller cc709a0231 security: master user bypasses all tenant restrictions
Joomla: Repo Health / Release configuration (push) Blocked by required conditions
Joomla: Repo Health / Scripts governance (push) Blocked by required conditions
Joomla: Repo Health / Repository health (push) Blocked by required conditions
Joomla: Repo Health / Access control (push) Successful in 1s
Joomla: Update Server / Update updates.xml (push) Successful in 8s
Moved isMasterUser() check to top of enforceAdminRestrictions() so
master user is never blocked by any restriction including install
from URL, global config, sysinfo, installer, and template editing.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-25 20:54:58 -05:00
jmiller 0a0d998208 chore: sync updates.xml from [skip ci] 2026-05-26 01:38:26 +00:00
gitea-actions[bot] 03839601bb chore: update updates.xml (development: 02.05.03-dev) [skip ci] 2026-05-26 01:38:25 +00:00
gitea-actions[bot] 3e28dd4fae chore(version): auto-bump patch 02.05.03 [skip ci] 2026-05-26 01:38:24 +00:00
Jonathan Miller 2674111e0b security: block non-master users from editing MokoWaaS settings
Joomla: Repo Health / Access control (push) Successful in 2s
Joomla: Update Server / Update updates.xml (push) Successful in 8s
Joomla: Repo Health / Release configuration (push) Failing after 4s
Joomla: Repo Health / Scripts governance (push) Successful in 4s
Joomla: Repo Health / Repository health (push) Failing after 4s
Non-master users navigating to the plugin edit page are redirected
back to the plugins list with a warning message.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-25 20:38:14 -05:00
gitea-actions[bot] 7488225aa6 chore(version): pre-release bump to 02.05.02 [skip ci] 2026-05-26 01:30:19 +00:00
jmiller c1a9816c57 fix: updates.xml element=pkg_mokowaas + legacy plugin entry [skip ci] 2026-05-26 01:25:32 +00:00
jmiller 2d1932719a chore: sync updates.xml 02.06.00 [skip ci] 2026-05-26 01:12:15 +00:00
jmiller 315be81e20 Merge pull request 'chore: cascade main → dev (65d9aa3) [skip ci]' (#39) from main into dev
chore: cascade main → dev [skip ci]
2026-05-26 01:12:07 +00:00
jmiller 65d9aa3e9f Merge pull request 'Release 02.06.00: Alias offline bypass, install API fix, stream tags' (#38) from dev into main
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 3s
Joomla: Repo Health / Access control (push) Successful in 1s
Joomla: Repo Health / Release configuration (push) Failing after 3s
Joomla: Repo Health / Scripts governance (push) Successful in 4s
Joomla: Repo Health / Repository health (push) Failing after 4s
2026-05-26 01:12:02 +00:00
jmiller 8243e8c49d chore: sync updates.xml from [skip ci] 2026-05-26 01:11:51 +00:00
gitea-actions[bot] c9d31b3ba4 chore: update updates.xml (development: 02.05.01-dev) [skip ci]
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 13s
2026-05-26 01:11:50 +00:00
gitea-actions[bot] 29cfee7154 chore(version): auto-bump patch 02.05.01 [skip ci] 2026-05-26 01:11:49 +00:00
Jonathan Miller bbae842fdb Merge remote-tracking branch 'origin/main' into dev
Joomla: Repo Health / Access control (push) Successful in 1s
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Joomla: Repo Health / Access control (pull_request) Successful in 1s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 4s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 5s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 5s
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Has been skipped
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Has been skipped
Joomla: Extension CI / PHPStan Analysis (pull_request) Has been skipped
Universal: PR Check / Changelog Updated (pull_request) Successful in 5s
Universal: PR Check / Validate PR (pull_request) Failing after 4s
Universal: PR Check / Build RC Package (pull_request) Has been skipped
Joomla: Extension CI / Build RC Pre-Release (pull_request) Has been skipped
Joomla: Update Server / Update updates.xml (push) Successful in 10s
Joomla: Repo Health / Release configuration (push) Failing after 4s
Joomla: Repo Health / Scripts governance (push) Successful in 4s
Joomla: Repo Health / Repository health (push) Failing after 4s
Joomla: Repo Health / Release configuration (pull_request) Failing after 4s
Joomla: Repo Health / Scripts governance (pull_request) Successful in 4s
Joomla: Repo Health / Repository health (pull_request) Failing after 5s
# Conflicts:
#	README.md
2026-05-25 20:11:38 -05:00
jmiller 85e966a3f4 chore: sync updates.xml from [skip ci] 2026-05-26 01:04:00 +00:00
gitea-actions[bot] 3d8bfb6112 chore: update updates.xml (development: 02.04.02-dev) [skip ci] 2026-05-26 01:03:59 +00:00
gitea-actions[bot] 7822064045 chore(version): auto-bump patch 02.04.02 [skip ci] 2026-05-26 01:03:59 +00:00
Jonathan Miller 906861638f fix: install API extracts ZIP before passing to Joomla Installer
Joomla: Repo Health / Access control (push) Successful in 1s
Joomla: Update Server / Update updates.xml (push) Successful in 8s
Joomla: Repo Health / Release configuration (push) Failing after 5s
Joomla: Repo Health / Scripts governance (push) Successful in 5s
Joomla: Repo Health / Repository health (push) Failing after 6s
Installer::install() expects a directory path, not a ZIP file. Now
downloads → extracts to tmp dir → installs from extracted dir → cleans up.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-25 20:03:47 -05:00
Jonathan Miller 78dd453a9b chore: promote CHANGELOG for 02.06.00 release
Joomla: Repo Health / Access control (push) Successful in 3s
Joomla: Repo Health / Release configuration (push) Failing after 4s
Joomla: Repo Health / Scripts governance (push) Successful in 4s
Joomla: Repo Health / Repository health (push) Failing after 5s
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-25 20:01:14 -05:00
jmiller 204520d9c9 chore: sync updates.xml from [skip ci] 2026-05-26 00:59:11 +00:00
gitea-actions[bot] 72b967c0ab chore: update updates.xml (development: 02.04.01-dev) [skip ci] 2026-05-26 00:59:10 +00:00
gitea-actions[bot] 781266885f chore(version): auto-bump patch 02.04.01 [skip ci] 2026-05-26 00:59:09 +00:00
Jonathan Miller a869619fcd feat: alias offline=No bypasses Joomla global offline setting
Joomla: Repo Health / Access control (push) Successful in 1s
Joomla: Update Server / Update updates.xml (push) Successful in 9s
Joomla: Repo Health / Release configuration (push) Failing after 3s
Joomla: Repo Health / Scripts governance (push) Successful in 4s
Joomla: Repo Health / Repository health (push) Failing after 4s
When an alias domain has offline=No, the plugin overrides Joomla's
configuration.php offline=1 setting. This allows the dev/staging alias
to remain accessible while the main site shows the offline page.

Use case: put clarksvillefurs.com offline for maintenance while
clarksvillefurs.dev.mokoconsulting.tech stays accessible for testing.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-25 19:58:52 -05:00
Jonathan Miller 625965e129 fix(ci): use stream tag 'stable' instead of version tag 'vXX'
Joomla: Repo Health / Access control (push) Successful in 1s
Joomla: Repo Health / Release configuration (push) Failing after 3s
Joomla: Repo Health / Scripts governance (push) Successful in 4s
Joomla: Repo Health / Repository health (push) Failing after 4s
Release tags should use update stream names (stable, development,
release-candidate) not version-based tags (v02, v03). This aligns
with the pre-release workflow which already uses stream tags.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-25 19:22:05 -05:00
jmiller 91504c663b fix: use stream tag 'stable' not version tag in updates.xml [skip ci] 2026-05-26 00:21:50 +00:00
jmiller 6cd690b737 feat(ci): add issue-branch.yml [skip ci] 2026-05-25 05:12:32 +00:00
Jonathan Miller 3b2fe37ce1 chore: update CHANGELOG for 02.05.00 stable release
Joomla: Repo Health / Access control (push) Successful in 1s
Joomla: Repo Health / Release configuration (push) Failing after 3s
Joomla: Repo Health / Scripts governance (push) Successful in 3s
Joomla: Repo Health / Repository health (push) Failing after 4s
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-24 23:15:29 -05:00
jmiller 8fea27e8b6 fix(ci): update pre-release.yml - PHP CLI tools, fix broken platform detection [skip ci] 2026-05-25 04:12:59 +00:00
jmiller cbea5752d1 fix: correct updates.xml stable entries [skip ci] 2026-05-25 04:07:11 +00:00
jmiller 34e789298b chore: sync updates.xml 02.05.00 [skip ci] 2026-05-25 03:59:36 +00:00
gitea-actions[bot] 62c49eab5a chore(release): ZIP + tar.gz for 02.05.00 [skip ci] 2026-05-25 03:59:35 +00:00
gitea-actions[bot] 2f8c81792d chore(release): build 02.05.00 [skip ci] 2026-05-25 03:59:33 +00:00
jmiller 9a356cdd04 Merge pull request 'chore: cascade main → dev (7b5a83c) [skip ci]' (#37) from main into dev
chore: cascade main → dev [skip ci]
2026-05-25 03:59:26 +00:00
jmiller 69ff510bac Merge pull request 'chore: cascade main → dev (8c9e3e6) [skip ci]' (#36) from main into dev
chore: cascade main → dev [skip ci]
2026-05-24 23:23:45 +00:00
20 changed files with 2090 additions and 1595 deletions
+1
View File
@@ -8,6 +8,7 @@
<name>MokoWaaS</name> <name>MokoWaaS</name>
<org>MokoConsulting</org> <org>MokoConsulting</org>
<description>White-label identity, security hardening, and tenant restriction layer for WaaS-managed Joomla environments</description> <description>White-label identity, security hardening, and tenant restriction layer for WaaS-managed Joomla environments</description>
<version>02.11.01</version>
<license spdx="GPL-3.0-or-later">GNU General Public License v3</license> <license spdx="GPL-3.0-or-later">GNU General Public License v3</license>
</identity> </identity>
<governance> <governance>
+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
+73
View File
@@ -0,0 +1,73 @@
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: moko-platform.Automation
# VERSION: 01.00.00
# BRIEF: Auto-create feature branch when an issue is opened
name: "Universal: Issue Branch"
on:
issues:
types: [opened]
permissions:
contents: write
issues: write
env:
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
jobs:
create-branch:
name: Create feature branch
runs-on: ubuntu-latest
steps:
- name: Create branch and comment
run: |
TOKEN="${{ secrets.GA_TOKEN }}"
API="${GITEA_URL}/api/v1/repos/${{ github.repository }}"
ISSUE_NUM="${{ github.event.issue.number }}"
ISSUE_TITLE="${{ github.event.issue.title }}"
# Build slug from title: lowercase, replace non-alnum with dash, trim
SLUG=$(echo "${ISSUE_TITLE}" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//' | cut -c1-40)
BRANCH="feature/${ISSUE_NUM}-${SLUG}"
# Check dev branch exists
DEV_EXISTS=$(curl -sf -o /dev/null -w '%{http_code}' \
-H "Authorization: token ${TOKEN}" \
"${API}/branches/dev" 2>/dev/null || echo "000")
if [ "${DEV_EXISTS}" != "200" ]; then
echo "No dev branch -- skipping"
exit 0
fi
# Create branch from dev
HTTP=$(curl -sf -o /dev/null -w '%{http_code}' -X POST \
-H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \
"${API}/branches" \
-d "{\"new_branch_name\":\"${BRANCH}\",\"old_branch_name\":\"dev\"}" 2>/dev/null || echo "000")
if [ "${HTTP}" = "201" ]; then
echo "Created branch: ${BRANCH}"
# Comment on issue with branch link
REPO_URL="${GITEA_URL}/${{ github.repository }}"
BODY="Branch created: [\`${BRANCH}\`](${REPO_URL}/src/branch/${BRANCH})\n\n\`\`\`bash\ngit fetch origin\ngit checkout ${BRANCH}\n\`\`\`"
curl -sf -X POST \
-H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \
"${API}/issues/${ISSUE_NUM}/comments" \
-d "{\"body\":\"${BODY}\"}" > /dev/null 2>&1
echo "Commented on issue #${ISSUE_NUM}"
else
echo "Failed to create branch (HTTP ${HTTP}) -- may already exist"
fi
+223 -260
View File
@@ -1,260 +1,223 @@
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech> # Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
# #
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
# #
# FILE INFORMATION # FILE INFORMATION
# DEFGROUP: Gitea.Workflow # DEFGROUP: Gitea.Workflow
# INGROUP: moko-platform.Release # INGROUP: moko-platform.Release
# REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform # REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
# PATH: /templates/workflows/universal/pre-release.yml.template # PATH: /templates/workflows/universal/pre-release.yml.template
# VERSION: 05.00.00 # VERSION: 05.01.00
# BRIEF: Manual pre-release builds dev/alpha/beta/rc packages from any branch # BRIEF: Manual pre-release -- builds dev/alpha/beta/rc packages from any branch
name: "Universal: Pre-Release" name: "Universal: Pre-Release"
on: on:
workflow_dispatch: pull_request:
inputs: types: [closed]
stability: branches:
description: 'Pre-release channel' - dev
required: true workflow_dispatch:
type: choice inputs:
options: stability:
- development description: 'Pre-release channel'
- alpha required: true
- beta type: choice
- release-candidate options:
- development
permissions: - alpha
contents: write - beta
- release-candidate
env:
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} permissions:
GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }} contents: write
GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }}
env:
jobs: GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
build: GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
name: "Build Pre-Release (${{ inputs.stability }})" GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }}
runs-on: release
jobs:
steps: build:
- name: Checkout name: "Build Pre-Release (${{ inputs.stability || 'development' }})"
uses: actions/checkout@v4 runs-on: release
with: if: >-
fetch-depth: 0 github.event_name == 'workflow_dispatch' ||
token: ${{ secrets.GA_TOKEN }} (github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'dev')
- name: Setup PHP steps:
run: | - name: Checkout
if ! command -v php &> /dev/null; then uses: actions/checkout@v4
sudo apt-get update -qq with:
sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl >/dev/null 2>&1 fetch-depth: 0
fi token: ${{ secrets.GA_TOKEN }}
- name: Setup moko-platform tools - name: Setup moko-platform tools
env: env:
MOKO_CLONE_TOKEN: ${{ secrets.GA_TOKEN }} MOKO_CLONE_TOKEN: ${{ secrets.GA_TOKEN }}
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
run: | 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 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
- name: Detect platform fi
id: platform git clone --depth 1 --branch main --quiet \
run: | "https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git" \
php /tmp/moko-platform-api/cli/manifest_read.php --path . --github-output /tmp/moko-platform-api
cd /tmp/moko-platform-api && composer install --no-dev --no-interaction --quiet
- name: Resolve metadata echo "MOKO_CLI=/tmp/moko-platform-api/cli" >> "$GITHUB_ENV"
id: meta
run: | - name: Detect platform
STABILITY="${{ inputs.stability }}" id: platform
MOKO_API="/tmp/moko-platform-api/cli" run: |
php ${MOKO_CLI}/manifest_read.php --path . --github-output
case "$STABILITY" in
development) SUFFIX="-dev"; TAG="development" ;; - name: Resolve metadata and bump version
alpha) SUFFIX="-alpha"; TAG="alpha" ;; id: meta
beta) SUFFIX="-beta"; TAG="beta" ;; run: |
release-candidate) SUFFIX="-rc"; TAG="release-candidate" ;; STABILITY="${{ inputs.stability || 'development' }}"
esac
case "$STABILITY" in
# Read current version from manifest (priority) or README — no bump yet development) SUFFIX="-dev"; TAG="development" ;;
VERSION=$(php ${MOKO_API}/version_read.php --path .) alpha) SUFFIX="-alpha"; TAG="alpha" ;;
echo "Version: ${VERSION}" beta) SUFFIX="-beta"; TAG="beta" ;;
release-candidate) SUFFIX="-rc"; TAG="release-candidate" ;;
# Ensure platform-specific manifest matches esac
php ${MOKO_API}/version_set_platform.php --path . --version "${VERSION}"
# Read current version (bump already handled by push workflow)
# Git setup for later commits VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null)
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" [ -z "$VERSION" ] && VERSION="00.00.01"
git config --local user.name "gitea-actions[bot]"
git remote set-url origin "https://jmiller:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" php ${MOKO_CLI}/version_set_platform.php \
--path . --version "$VERSION" --branch "${{ github.ref_name }}" 2>/dev/null || true
# Detect element from Joomla/Dolibarr manifest
set +o pipefail # Verify version consistency across all files
PLATFORM="${{ steps.platform.outputs.platform }}" php ${MOKO_CLI}/version_check.php --path . --fix 2>/dev/null || true
EXT_ELEMENT=$(php ${MOKO_API}/manifest_read.php --path . --field name 2>/dev/null | tr -d ' ' | tr '[:upper:]' '[:lower:]' || true)
# For Joomla, prefer <element> tag # Commit version bump
if [ "$PLATFORM" = "joomla" ]; then git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
MANIFEST=$(find . -maxdepth 4 -name "*.xml" ! -path "./.git/*" -print0 2>/dev/null | xargs -0 grep -l '<extension' 2>/dev/null | head -1 || true) git config --local user.name "gitea-actions[bot]"
if [ -n "$MANIFEST" ]; then git remote set-url origin "https://jmiller:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
ELEM=$(grep -oP "<element>\K[^<]+" "$MANIFEST" 2>/dev/null | head -1 || true) git add -A
[ -n "$ELEM" ] && EXT_ELEMENT="$ELEM" git diff --cached --quiet || {
fi git commit -m "chore(version): pre-release bump to ${VERSION} [skip ci]"
fi git push origin HEAD 2>&1
[ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') }
set -o pipefail
# Auto-detect element via manifest_element.php
ZIP_NAME="${EXT_ELEMENT}-${VERSION}${SUFFIX}.zip" php ${MOKO_CLI}/manifest_element.php \
--path . --version "$VERSION" --stability "$STABILITY" \
echo "version=${VERSION}" >> "$GITHUB_OUTPUT" --repo "${GITEA_REPO}" --github-output
echo "stability=${STABILITY}" >> "$GITHUB_OUTPUT"
echo "suffix=${SUFFIX}" >> "$GITHUB_OUTPUT" # Read back element outputs
echo "tag=${TAG}" >> "$GITHUB_OUTPUT" EXT_ELEMENT=$(grep '^ext_element=' "$GITHUB_OUTPUT" | tail -1 | cut -d= -f2)
echo "zip_name=${ZIP_NAME}" >> "$GITHUB_OUTPUT" ZIP_NAME=$(grep '^zip_name=' "$GITHUB_OUTPUT" | tail -1 | cut -d= -f2)
echo "ext_element=${EXT_ELEMENT}" >> "$GITHUB_OUTPUT" [ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -')
[ -z "$ZIP_NAME" ] && ZIP_NAME="${EXT_ELEMENT}-${VERSION}${SUFFIX}.zip"
echo "=== Pre-Release: ${EXT_ELEMENT} ${VERSION}${SUFFIX} ==="
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
- name: Build package echo "stability=${STABILITY}" >> "$GITHUB_OUTPUT"
id: zip echo "suffix=${SUFFIX}" >> "$GITHUB_OUTPUT"
run: | echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
VERSION="${{ steps.meta.outputs.version }}" echo "zip_name=${ZIP_NAME}" >> "$GITHUB_OUTPUT"
SUFFIX="${{ steps.meta.outputs.suffix }}" echo "ext_element=${EXT_ELEMENT}" >> "$GITHUB_OUTPUT"
PLATFORM="${{ steps.platform.outputs.platform }}"
echo "=== Pre-Release: ${EXT_ELEMENT} ${VERSION}${SUFFIX} ==="
if [ "$PLATFORM" = "joomla" ]; then
php /tmp/moko-platform-api/cli/joomla_build.php --path . --version "${VERSION}" --suffix "${SUFFIX}" --output build --github-output - name: Create release
else id: release
# Generic build: zip src/ directory run: |
SOURCE_DIR="src" TAG="${{ steps.meta.outputs.tag }}"
[ ! -d "$SOURCE_DIR" ] && SOURCE_DIR="htdocs" VERSION="${{ steps.meta.outputs.version }}"
[ ! -d "$SOURCE_DIR" ] && { echo "::error::No src/ or htdocs/"; exit 1; } API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
EXT_ELEMENT="${{ steps.meta.outputs.ext_element }}" php ${MOKO_CLI}/release_create.php \
ZIP_NAME="${EXT_ELEMENT}-${VERSION}${SUFFIX}.zip" --path . --version "$VERSION" --tag "$TAG" \
mkdir -p build --token "${{ secrets.GA_TOKEN }}" --api-base "$API_BASE" \
cd "$SOURCE_DIR" && zip -r "../build/${ZIP_NAME}" . && cd .. --repo "${GITEA_REPO}" --branch dev --prerelease
SHA256=$(sha256sum "build/${ZIP_NAME}" | cut -d' ' -f1)
echo "zip_name=${ZIP_NAME}" >> "$GITHUB_OUTPUT" - name: Build package and upload
echo "zip_path=build/${ZIP_NAME}" >> "$GITHUB_OUTPUT" id: package
echo "sha256=${SHA256}" >> "$GITHUB_OUTPUT" run: |
fi VERSION="${{ steps.meta.outputs.version }}"
TAG="${{ steps.meta.outputs.tag }}"
- name: Create or replace Gitea release API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
id: release php ${MOKO_CLI}/release_package.php \
continue-on-error: true --path . --version "$VERSION" --tag "$TAG" \
run: | --token "${{ secrets.GA_TOKEN }}" --api-base "$API_BASE" \
TAG="${{ steps.meta.outputs.tag }}" --repo "${GITEA_REPO}" --output /tmp || true
VERSION="${{ steps.meta.outputs.version }}"
STABILITY="${{ steps.meta.outputs.stability }}" - name: Update updates.xml
SHA256="${{ steps.zip.outputs.sha256 }}" if: steps.platform.outputs.platform == 'joomla'
ZIP_NAME="${{ steps.zip.outputs.zip_name }}" run: |
EXT_ELEMENT="${{ steps.meta.outputs.ext_element }}" VERSION="${{ steps.meta.outputs.version }}"
TOKEN="${{ secrets.GA_TOKEN }}" STABILITY="${{ steps.meta.outputs.stability }}"
API="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" SHA256="${{ steps.package.outputs.sha256_zip }}"
BRANCH=$(git branch --show-current)
if [ ! -f "updates.xml" ]; then
BODY="## ${VERSION} ($(date +%Y-%m-%d)) echo "No updates.xml -- skipping"
**Channel:** ${STABILITY} exit 0
**SHA-256:** \`${SHA256}\`" fi
# Delete existing release SHA_FLAG=""
EXISTING_ID=$(curl -sS -H "Authorization: token ${TOKEN}" \ [ -n "$SHA256" ] && SHA_FLAG="--sha ${SHA256}"
"${API}/releases/tags/${TAG}" | jq -r '.id // empty' 2>/dev/null)
if [ -n "$EXISTING_ID" ]; then php ${MOKO_CLI}/updates_xml_build.php \
curl -sS -X DELETE -H "Authorization: token ${TOKEN}" \ --path . --version "${VERSION}" --stability "${STABILITY}" \
"${API}/releases/${EXISTING_ID}" 2>/dev/null || true --gitea-url "${GITEA_URL}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}" \
curl -sS -X DELETE -H "Authorization: token ${TOKEN}" \ ${SHA_FLAG}
"${API}/tags/${TAG}" 2>/dev/null || true
fi # Commit and push
if ! git diff --quiet updates.xml 2>/dev/null; then
# Create release git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
RELEASE_ID=$(curl -sS -X POST -H "Authorization: token ${TOKEN}" \ git config --local user.name "gitea-actions[bot]"
-H "Content-Type: application/json" \ git add updates.xml
"${API}/releases" \ git commit -m "chore: update ${STABILITY} channel ${VERSION} [skip ci]"
-d "$(jq -n \ git push origin HEAD 2>&1 || echo "WARNING: push failed"
--arg tag "$TAG" \ fi
--arg target "$BRANCH" \
--arg name "${EXT_ELEMENT} ${VERSION} (${STABILITY})" \ - name: "Sync updates.xml to all branches"
--arg body "$BODY" \ if: steps.platform.outputs.platform == 'joomla'
'{tag_name: $tag, target_commitish: $target, name: $name, body: $body, prerelease: true}' run: |
)" | jq -r '.id') CURRENT_BRANCH="${{ github.ref_name }}"
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
echo "release_id=${RELEASE_ID}" >> "$GITHUB_OUTPUT" git config --local user.name "gitea-actions[bot]"
# Upload ZIP for BRANCH in main dev; do
curl -sS -X POST -H "Authorization: token ${TOKEN}" \ [ "$BRANCH" = "$CURRENT_BRANCH" ] && continue
-H "Content-Type: application/octet-stream" \ echo "Syncing updates.xml -> ${BRANCH}"
"${API}/releases/${RELEASE_ID}/assets?name=${ZIP_NAME}" \ git fetch origin "${BRANCH}" 2>/dev/null || continue
--data-binary "@${{ steps.zip.outputs.zip_path }}" git checkout "origin/${BRANCH}" -- updates.xml 2>/dev/null || continue
git checkout "${CURRENT_BRANCH}" -- updates.xml
echo "Released: ${EXT_ELEMENT} ${VERSION} (${STABILITY})" if ! git diff --quiet updates.xml 2>/dev/null; then
git add updates.xml
- name: "Update updates.xml" git commit -m "chore: sync updates.xml from ${CURRENT_BRANCH} [skip ci]"
if: steps.platform.outputs.platform == 'joomla' git push origin HEAD:refs/heads/${BRANCH} 2>&1 || echo "WARNING: push to ${BRANCH} failed"
run: | fi
VERSION="${{ steps.meta.outputs.version }}" git checkout "${CURRENT_BRANCH}" 2>/dev/null
STABILITY="${{ steps.meta.outputs.stability }}" done
SHA256="${{ steps.zip.outputs.sha256 }}"
php /tmp/moko-platform-api/cli/updates_xml_build.php --path . --version "$VERSION" --stability "$STABILITY" --sha "$SHA256" --gitea-url "$GITEA_URL" --org "$GITEA_ORG" --repo "$GITEA_REPO" - name: "Delete lesser pre-release channels (cascade)"
if ! git diff --quiet updates.xml 2>/dev/null; then continue-on-error: true
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" run: |
git config --local user.name "gitea-actions[bot]" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
git add updates.xml TOKEN="${{ secrets.GA_TOKEN }}"
git commit -m "chore: update $STABILITY channel $VERSION [skip ci]"
git push origin HEAD 2>&1 || echo "WARNING: push failed" php ${MOKO_CLI}/release_cascade.php \
fi --stability "${{ steps.meta.outputs.stability }}" \
--token "${TOKEN}" \
- name: "Sync updates.xml to all branches" --api-base "${API_BASE}"
if: steps.platform.outputs.platform == 'joomla'
run: | - name: Summary
php /tmp/moko-platform-api/cli/updates_xml_sync.php --path . --current "${{ github.ref_name }}" --branches main,dev --version "${{ steps.meta.outputs.version }}" --token "${{ secrets.GA_TOKEN }}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}" --gitea-url "${GITEA_URL}" if: always()
run: |
- name: "Delete lesser pre-release channels (cascade)" VERSION="${{ steps.meta.outputs.version }}"
continue-on-error: true STABILITY="${{ steps.meta.outputs.stability }}"
run: | ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" SHA256="${{ steps.package.outputs.sha256_zip }}"
TOKEN="${{ secrets.GA_TOKEN }}" echo "## Pre-Release Complete" >> $GITHUB_STEP_SUMMARY
STABILITY="${{ steps.meta.outputs.stability }}" echo "" >> $GITHUB_STEP_SUMMARY
echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
# Cascade: rc → beta,alpha,dev | beta → alpha,dev | alpha → dev | dev → nothing echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
case "$STABILITY" in echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
release-candidate) TAGS_TO_DELETE="beta alpha development" ;; echo "| Channel | ${STABILITY} |" >> $GITHUB_STEP_SUMMARY
beta) TAGS_TO_DELETE="alpha development" ;; echo "| Package | \`${ZIP_NAME}\` |" >> $GITHUB_STEP_SUMMARY
alpha) TAGS_TO_DELETE="development" ;; echo "| SHA-256 | \`${SHA256:-n/a}\` |" >> $GITHUB_STEP_SUMMARY
*) TAGS_TO_DELETE="" ;;
esac
[ -z "$TAGS_TO_DELETE" ] && exit 0
for TAG in $TAGS_TO_DELETE; do
RELEASE_ID=$(curl -sS -H "Authorization: token ${TOKEN}" \
"${API_BASE}/releases/tags/${TAG}" 2>/dev/null | \
python3 -c "import sys,json; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true)
if [ -n "$RELEASE_ID" ] && [ "$RELEASE_ID" != "None" ]; then
curl -sS -X DELETE -H "Authorization: token ${TOKEN}" \
"${API_BASE}/releases/${RELEASE_ID}" 2>/dev/null || true
curl -sS -X DELETE -H "Authorization: token ${TOKEN}" \
"${API_BASE}/tags/${TAG}" 2>/dev/null || true
echo "Deleted: ${TAG} (id: ${RELEASE_ID})"
fi
done
- name: "Post-release version bump"
run: |
MOKO_API="/tmp/moko-platform-api/cli"
VERSION="${{ steps.meta.outputs.version }}"
# Bump patch for next dev cycle
BUMP_OUTPUT=$(php ${MOKO_API}/version_bump.php --path .)
NEXT=$(echo "$BUMP_OUTPUT" | grep -oP '\d{2}\.\d{2}\.\d{2}$' || true)
[ -z "$NEXT" ] && exit 0
# Update platform-specific manifest to next version
php ${MOKO_API}/version_set_platform.php --path . --version "${NEXT}"
git add -A
git diff --cached --quiet || {
git commit -m "chore: update development channel ${VERSION} [skip ci]"
git push origin HEAD 2>&1
}
File diff suppressed because it is too large Load Diff
+49
View File
@@ -31,6 +31,55 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- License/subscription check - License/subscription check
- System email template branding (DB approach) - System email template branding (DB approach)
### Added
- Trusted IPs: configurable repeatable rows of IP addresses, CIDR ranges, and wildcards that bypass admin session timeout
- Supports exact IPs (192.168.1.100), CIDR (10.0.0.0/24), and wildcards (192.168.1.*)
- Each entry has a label and enabled toggle for easy management
- Current IP display above trusted IPs table so admins can easily add their own IP
### Fixed
- Trusted IP session bypass: moved from `onAfterInitialise` to `boot()` so Joomla's session lifetime is extended before the session handler validates it (was too late, Joomla expired the session first)
## [02.06.00] - 2026-05-25
### Added
- Alias offline bypass: aliases with offline=No override Joomla's global offline setting, allowing access via alias domain while main site is down
- Block non-master users from viewing or editing MokoWaaS plugin settings
- Master user bypasses ALL tenant restrictions (install from URL, global config, sysinfo, installer, templates)
- Admin Help menu redirected to configured support URL (replaces help.joomla.org)
### Fixed
- Install API endpoint: extract ZIP to temp directory before passing to Joomla Installer (was passing ZIP path directly)
- Clean up extracted temp directory on success or failure
- Update site disabled by Joomla when protected=1 — ensureProtectedFlag() now re-enables it
- CI: auto-release fetches updates.xml from main before building (preserves all channels)
- CI: version_check.php --fix runs after version bump in both workflows
- CI: checksums attached as `[filename].sha256` files instead of in release body
- CI: auto-release cleaned up — removed duplicate asset loops, inline Python updater, dead code
- CI: Step 8b uses `release_body_update.php` CLI instead of inline Python
- CI: Step 6 tag creation no longer gated by `is_minor` (was never set)
### Changed
- CI: auto-release uses stream tag `stable` instead of version tag `vXX`
- CI: pre-release package build uses absolute paths (fixes relative path zip error)
## [02.05.00] - 2026-05-24
### Added
- Joomla `protected=1` flag on all MokoWaaS extensions (framework-level disable/uninstall prevention)
- Self-healing protected flag — restored each admin session if cleared
- Block non-master disable via plugin list toggle (`plugins.publish`)
- Package script sets `protected=1, locked=0` on every install/update
- Legacy plugin entry in updates.xml for sites upgrading from standalone plugin
### Fixed
- CI: auto-release workflow `pkg_pkg_` duplication in release names, ZIP filenames, and SHA256 paths
- CI: auto-release now strips existing type prefix and uses `<packagename>` for packages
- CI: `updates_xml_build` was cascading entries for all lower channels on stable release — now writes only current channel
- CI: `targetplatform` regex `((5.[0-9])|(6.[0-9]))` caused Gitea 500 on XML render — simplified to `(5|6)\..*`
- updates.xml stable entry now has correct `<tag>stable</tag>` and download URL
- README slimmed to overview, detailed content moved to wiki
## [02.03.10] - 2026-05-24 ## [02.03.10] - 2026-05-24
### Added ### Added
+1 -1
View File
@@ -9,7 +9,7 @@
DEFGROUP: Joomla.Plugin DEFGROUP: Joomla.Plugin
INGROUP: MokoWaaS INGROUP: MokoWaaS
REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS
VERSION: 02.04.00 VERSION: 02.11.02
PATH: /README.md PATH: /README.md
BRIEF: MokoWaaS platform plugin for Joomla BRIEF: MokoWaaS platform plugin for Joomla
--> -->
+1 -1
View File
@@ -7,7 +7,7 @@
<license>GPL-3.0-or-later</license> <license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail> <authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl> <authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.04.00</version> <version>02.11.02</version>
<description>Minimal API-only component for MokoWaaS. Provides REST endpoints for site health, cache, updates, and backups.</description> <description>Minimal API-only component for MokoWaaS. Provides REST endpoints for site health, cache, updates, and backups.</description>
<namespace path="api/src">Moko\Component\MokoWaaS\Api</namespace> <namespace path="api/src">Moko\Component\MokoWaaS\Api</namespace>
<administration> <administration>
@@ -31,6 +31,7 @@ namespace Moko\Plugin\System\MokoWaaS\Extension;
defined('_JEXEC') or die; defined('_JEXEC') or die;
use Joomla\CMS\Extension\BootableExtensionInterface;
use Joomla\CMS\Factory; use Joomla\CMS\Factory;
use Joomla\CMS\Log\Log; use Joomla\CMS\Log\Log;
use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\CMSPlugin;
@@ -38,6 +39,7 @@ use Joomla\CMS\Router\Route;
use Joomla\CMS\Language\Language; use Joomla\CMS\Language\Language;
use Joomla\CMS\Uri\Uri; use Joomla\CMS\Uri\Uri;
use Joomla\CMS\User\UserHelper; use Joomla\CMS\User\UserHelper;
use Psr\Container\ContainerInterface;
/** /**
* MokoWaaS Brand System Plugin * MokoWaaS Brand System Plugin
@@ -47,7 +49,7 @@ use Joomla\CMS\User\UserHelper;
* *
* @since 01.04.00 * @since 01.04.00
*/ */
class MokoWaaS extends CMSPlugin class MokoWaaS extends CMSPlugin implements BootableExtensionInterface
{ {
/** /**
* Obfuscated Grafana URL (XOR + base64). * Obfuscated Grafana URL (XOR + base64).
@@ -114,6 +116,37 @@ class MokoWaaS extends CMSPlugin
*/ */
protected $app; protected $app;
/**
* Boot the extension — runs BEFORE Joomla creates the session.
*
* Extends the Joomla session lifetime for trusted IPs so the
* session handler does not destroy the session before
* onAfterInitialise can run.
*
* @param ContainerInterface $container The DI container.
*
* @return void
*
* @since 02.11.00
*/
public function boot(ContainerInterface $container): void
{
$timeout = (int) $this->params->get('admin_session_timeout', 0);
if ($timeout <= 0)
{
return;
}
if ($this->ipIsTrusted())
{
// Set both PHP and Joomla session lifetimes before the
// session handler runs its expiry check.
ini_set('session.gc_maxlifetime', 315360000);
Factory::getConfig()->set('lifetime', 525600);
}
}
/** /**
* Event triggered after the framework has loaded and the application initialise method has been called. * Event triggered after the framework has loaded and the application initialise method has been called.
* *
@@ -653,7 +686,7 @@ class MokoWaaS extends CMSPlugin
return [ return [
'{{BRAND_NAME}}' => $this->params->get('brand_name', 'MokoWaaS'), '{{BRAND_NAME}}' => $this->params->get('brand_name', 'MokoWaaS'),
'{{COMPANY_NAME}}' => $this->params->get('company_name', 'Moko Consulting'), '{{COMPANY_NAME}}' => $this->params->get('company_name', 'Moko Consulting'),
'{{SUPPORT_URL}}' => $this->params->get('support_url', 'https://mokoconsulting.tech'), '{{SUPPORT_URL}}' => $this->params->get('support_url', 'https://mokoconsulting.tech/support'),
]; ];
} }
@@ -936,6 +969,7 @@ class MokoWaaS extends CMSPlugin
} }
$this->injectFavicon($doc); $this->injectFavicon($doc);
$this->redirectHelpMenu($doc);
// Hide MokoWaaS from plugin list for non-master users // Hide MokoWaaS from plugin list for non-master users
if (!$this->isMasterUser()) if (!$this->isMasterUser())
@@ -975,6 +1009,32 @@ class MokoWaaS extends CMSPlugin
"); ");
} }
/**
* Redirect the admin Help menu link to the configured support URL.
*
* Joomla's Atum template hardcodes the Help link to help.joomla.org.
* This replaces it with the WaaS support URL via JS injection.
*
* @param \Joomla\CMS\Document\HtmlDocument $doc Document object
*
* @return void
*
* @since 02.10.00
*/
protected function redirectHelpMenu($doc)
{
$supportUrl = $this->params->get('support_url', 'https://mokoconsulting.tech/support');
$doc->addScriptDeclaration("
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('a[href*=\"help.joomla.org\"], a[href*=\"docs.joomla.org\"]').forEach(function(link) {
link.href = " . json_encode($supportUrl) . ";
link.target = '_blank';
});
});
");
}
/** /**
* Protect the plugin from being disabled or uninstalled by non-master users. * Protect the plugin from being disabled or uninstalled by non-master users.
* Does NOT self-heal (no lock) — master users can still disable if needed. * Does NOT self-heal (no lock) — master users can still disable if needed.
@@ -1025,6 +1085,31 @@ class MokoWaaS extends CMSPlugin
$this->app->redirect('index.php?option=com_plugins'); $this->app->redirect('index.php?option=com_plugins');
} }
} }
// Block non-master from viewing or editing MokoWaaS plugin settings
if ($option === 'com_plugins')
{
$view = $this->app->input->get('view', '');
$layout = $this->app->input->get('layout', '');
$extensionId = (int) $this->app->input->get('extension_id', 0);
if (($view === 'plugin' || $layout === 'edit') && $extensionId > 0)
{
$db = Factory::getDbo();
$query = $db->getQuery(true)
->select('COUNT(*)')
->from($db->quoteName('#__extensions'))
->where($db->quoteName('extension_id') . ' = ' . $extensionId)
->where($db->quoteName('element') . ' = ' . $db->quote('mokowaas'))
->where($db->quoteName('type') . ' = ' . $db->quote('plugin'));
if ((int) $db->setQuery($query)->loadResult() > 0)
{
$this->app->enqueueMessage('MokoWaaS settings are restricted to the master user.', 'warning');
$this->app->redirect('index.php?option=com_plugins');
}
}
}
} }
/** /**
@@ -1042,6 +1127,8 @@ class MokoWaaS extends CMSPlugin
try try
{ {
$db = Factory::getDbo(); $db = Factory::getDbo();
// Set protected=1, locked=0 on MokoWaaS extensions
$query = $db->getQuery(true) $query = $db->getQuery(true)
->update($db->quoteName('#__extensions')) ->update($db->quoteName('#__extensions'))
->set($db->quoteName('protected') . ' = 1') ->set($db->quoteName('protected') . ' = 1')
@@ -1051,6 +1138,18 @@ class MokoWaaS extends CMSPlugin
->where($db->quoteName('protected') . ' = 0'); ->where($db->quoteName('protected') . ' = 0');
$db->setQuery($query); $db->setQuery($query);
$db->execute(); $db->execute();
// Ensure update site stays enabled (protected extensions get their update site disabled by Joomla)
$query = $db->getQuery(true)
->update($db->quoteName('#__update_sites') . ' AS us')
->join('INNER', $db->quoteName('#__update_sites_extensions') . ' AS use2 ON us.update_site_id = use2.update_site_id')
->join('INNER', $db->quoteName('#__extensions') . ' AS e ON use2.extension_id = e.extension_id')
->set('us.enabled = 1')
->where('us.enabled = 0')
->where('(' . $db->quoteName('e.element') . ' = ' . $db->quote('mokowaas')
. ' OR ' . $db->quoteName('e.element') . ' = ' . $db->quote('pkg_mokowaas') . ')');
$db->setQuery($query);
$db->execute();
} }
catch (\Throwable $e) catch (\Throwable $e)
{ {
@@ -2747,11 +2846,36 @@ class MokoWaaS extends CMSPlugin
file_put_contents($tmpFile, $zipData); file_put_contents($tmpFile, $zipData);
// Extract ZIP to temp directory
$extractDir = $this->app->getConfig()->get('tmp_path', JPATH_ROOT . '/tmp')
. '/mokowaas_extract_' . md5($url);
if (is_dir($extractDir))
{
$this->rmdirRecursive($extractDir);
}
mkdir($extractDir, 0755, true);
$zip = new \ZipArchive();
if ($zip->open($tmpFile) !== true)
{
@unlink($tmpFile);
$this->sendHealthResponse(500, ['error' => 'Failed to open ZIP']);
return;
}
$zip->extractTo($extractDir);
$zip->close();
@unlink($tmpFile);
// Install using Joomla's installer // Install using Joomla's installer
$installer = \Joomla\CMS\Installer\Installer::getInstance(); $installer = \Joomla\CMS\Installer\Installer::getInstance();
$result = $installer->install($tmpFile); $result = $installer->install($extractDir);
@unlink($tmpFile); $this->rmdirRecursive($extractDir);
if ($result) if ($result)
{ {
@@ -2774,6 +2898,11 @@ class MokoWaaS extends CMSPlugin
{ {
@unlink($tmpFile ?? ''); @unlink($tmpFile ?? '');
if (!empty($extractDir) && is_dir($extractDir))
{
$this->rmdirRecursive($extractDir);
}
$this->sendHealthResponse(500, [ $this->sendHealthResponse(500, [
'error' => 'Install exception', 'error' => 'Install exception',
'message' => $e->getMessage(), 'message' => $e->getMessage(),
@@ -2782,6 +2911,42 @@ class MokoWaaS extends CMSPlugin
} }
} }
/**
* Recursively remove a directory.
*
* @param string $dir Directory path
*
* @return void
*
* @since 02.06.00
*/
protected function rmdirRecursive(string $dir): void
{
if (!is_dir($dir))
{
return;
}
$items = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS),
\RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($items as $item)
{
if ($item->isDir())
{
rmdir($item->getPathname());
}
else
{
unlink($item->getPathname());
}
}
rmdir($dir);
}
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// Site Alias handling // Site Alias handling
// ------------------------------------------------------------------ // ------------------------------------------------------------------
@@ -2944,25 +3109,33 @@ class MokoWaaS extends CMSPlugin
} }
// Offline: use Joomla's native offline mode for frontend requests // Offline: use Joomla's native offline mode for frontend requests
if (!empty($alias->offline) && (string) $alias->offline === '1' if ($this->app->isClient('site'))
&& $this->app->isClient('site'))
{ {
// Allow health API to still respond if (!empty($alias->offline) && (string) $alias->offline === '1')
if ($this->app->input->get('mokowaas', '') !== '')
{ {
return; // Allow health API to still respond
if ($this->app->input->get('mokowaas', '') !== '')
{
return;
}
// Set custom offline message if provided
$message = $alias->offline_message ?? '';
if (!empty($message))
{
$this->app->getConfig()->set('offline_message', $message);
}
// Enable Joomla's native offline mode
$this->app->getConfig()->set('offline', 1);
} }
else
// Set custom offline message if provided
$message = $alias->offline_message ?? '';
if (!empty($message))
{ {
$this->app->getConfig()->set('offline_message', $message); // Alias is NOT offline — override Joomla's global offline setting
// This allows access via the alias domain even when the main site is offline
$this->app->getConfig()->set('offline', 0);
} }
// Enable Joomla's native offline mode — renders through the template's offline.php
$this->app->getConfig()->set('offline', 1);
} }
} }
@@ -3203,6 +3376,12 @@ class MokoWaaS extends CMSPlugin
return; return;
} }
// Trusted IPs — session lifetime already extended in boot()
if ($this->ipIsTrusted())
{
return;
}
$session = Factory::getSession(); $session = Factory::getSession();
$lastHit = $session->get('mokowaas.last_activity', 0); $lastHit = $session->get('mokowaas.last_activity', 0);
$now = time(); $now = time();
@@ -3220,6 +3399,93 @@ class MokoWaaS extends CMSPlugin
$session->set('mokowaas.last_activity', $now); $session->set('mokowaas.last_activity', $now);
} }
/**
* Check whether the current request IP matches any trusted IP entry.
*
* Supports exact IPs, CIDR notation (e.g. 10.0.0.0/8), and
* wildcard patterns (e.g. 192.168.1.*).
*
* @return bool True if the current IP is in the trusted list.
*
* @since 02.11.00
*/
protected function ipIsTrusted(): bool
{
$entries = $this->params->get('trusted_ips', '');
if (empty($entries))
{
return false;
}
// Subform stores as JSON string or array
if (\is_string($entries))
{
$entries = json_decode($entries, true);
}
if (!\is_array($entries))
{
return false;
}
$ip = $this->app
? $this->app->input->server->getString('REMOTE_ADDR', '')
: ($_SERVER['REMOTE_ADDR'] ?? '');
$ipLong = ip2long($ip);
if ($ipLong === false)
{
return false;
}
foreach ($entries as $entry)
{
if (empty($entry['enabled']) || empty($entry['ip']))
{
continue;
}
$range = trim($entry['ip']);
// Wildcard: 192.168.1.*
if (str_contains($range, '*'))
{
$pattern = '/^' . str_replace(['.', '*'], ['\\.', '\\d+'], $range) . '$/';
if (preg_match($pattern, $ip))
{
return true;
}
continue;
}
// CIDR: 10.0.0.0/8
if (str_contains($range, '/'))
{
[$subnet, $bits] = explode('/', $range, 2);
$subnetLong = ip2long($subnet);
$mask = -1 << (32 - (int) $bits);
if ($subnetLong !== false && ($ipLong & $mask) === ($subnetLong & $mask))
{
return true;
}
continue;
}
// Exact match
if ($ip === $range)
{
return true;
}
}
return false;
}
/** /**
* Override Joomla upload restrictions at runtime. * Override Joomla upload restrictions at runtime.
@@ -3328,12 +3594,18 @@ class MokoWaaS extends CMSPlugin
*/ */
protected function enforceAdminRestrictions() protected function enforceAdminRestrictions()
{ {
// Master user bypasses ALL restrictions
if ($this->isMasterUser())
{
return;
}
$input = $this->app->input; $input = $this->app->input;
$option = $input->get('option', ''); $option = $input->get('option', '');
$view = $input->get('view', ''); $view = $input->get('view', '');
$task = $input->get('task', ''); $task = $input->get('task', '');
// Disable install-from-URL for ALL users (safety net) // Disable install-from-URL for non-master users
if ($this->params->get('disable_install_url', 1) if ($this->params->get('disable_install_url', 1)
&& $option === 'com_installer' && $option === 'com_installer'
&& stripos($task, 'install') !== false && stripos($task, 'install') !== false
@@ -3344,12 +3616,6 @@ class MokoWaaS extends CMSPlugin
return; return;
} }
// Remaining restrictions only apply to non-master users
if ($this->isMasterUser())
{
return;
}
$blocked = []; $blocked = [];
if ($this->params->get('restrict_installer', 1)) if ($this->params->get('restrict_installer', 1))
@@ -0,0 +1,40 @@
<?php
/**
* Copyright (C) 2025 Moko Consulting <hello@mokoconsulting.tech>
*
* SPDX-LICENSE-IDENTIFIER: GPL-3.0-or-later
*
* FILE INFORMATION
* DEFGROUP: Joomla.Plugin
* INGROUP: MokoWaaS
* VERSION: 02.11.00
* PATH: /src/Field/CurrentIpField.php
* BRIEF: Read-only field that displays the current user's IP address
*/
namespace Moko\Plugin\System\MokoWaaS\Field;
defined('_JEXEC') or die;
use Joomla\CMS\Form\FormField;
class CurrentIpField extends FormField
{
protected $type = 'CurrentIp';
protected function getInput()
{
$currentIp = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
return '<div class="alert alert-info mb-0 py-2">'
. '<strong>Your current IP:</strong> '
. '<code>' . htmlspecialchars($currentIp) . '</code> '
. '<small class="text-muted">&mdash; add this to the table below to keep your session alive.</small>'
. '</div>';
}
protected function getLabel()
{
return '';
}
}
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<form>
<field
name="ip"
type="text"
label="PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_ADDR_LABEL"
description="PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_ADDR_DESC"
required="true"
hint="e.g. 192.168.1.100 or 10.0.0.0/24"
/>
<field
name="label"
type="text"
label="PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_LABEL_LABEL"
description="PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_LABEL_DESC"
hint="e.g. Office network"
/>
<field
name="enabled"
type="radio"
label="PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_ENABLED_LABEL"
default="1"
class="btn-group btn-group-yesno"
>
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
</form>
@@ -120,6 +120,13 @@ PLG_SYSTEM_MOKOWAAS_FORCE_HTTPS_LABEL="Force HTTPS"
PLG_SYSTEM_MOKOWAAS_FORCE_HTTPS_DESC="Redirect all HTTP requests to HTTPS. Supports reverse proxy setups." PLG_SYSTEM_MOKOWAAS_FORCE_HTTPS_DESC="Redirect all HTTP requests to HTTPS. Supports reverse proxy setups."
PLG_SYSTEM_MOKOWAAS_SESSION_TIMEOUT_LABEL="Admin Session Timeout" PLG_SYSTEM_MOKOWAAS_SESSION_TIMEOUT_LABEL="Admin Session Timeout"
PLG_SYSTEM_MOKOWAAS_SESSION_TIMEOUT_DESC="Minutes of idle time before admin sessions expire. 0 uses the Joomla default." PLG_SYSTEM_MOKOWAAS_SESSION_TIMEOUT_DESC="Minutes of idle time before admin sessions expire. 0 uses the Joomla default."
PLG_SYSTEM_MOKOWAAS_TRUSTED_IPS_LABEL="Trusted IPs (No Session Timeout)"
PLG_SYSTEM_MOKOWAAS_TRUSTED_IPS_DESC="Sessions from these IP addresses or ranges will never time out. Supports exact IPs, CIDR notation (e.g. 10.0.0.0/24), and wildcards (e.g. 192.168.1.*)."
PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_ADDR_LABEL="IP / CIDR"
PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_ADDR_DESC="An IP address, CIDR range, or wildcard pattern."
PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_LABEL_LABEL="Label"
PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_LABEL_DESC="A descriptive label for this entry (e.g. Office, VPN)."
PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_ENABLED_LABEL="Enabled"
PLG_SYSTEM_MOKOWAAS_PASSWORD_LENGTH_LABEL="Minimum Password Length" PLG_SYSTEM_MOKOWAAS_PASSWORD_LENGTH_LABEL="Minimum Password Length"
PLG_SYSTEM_MOKOWAAS_PASSWORD_LENGTH_DESC="Minimum number of characters required for user passwords." PLG_SYSTEM_MOKOWAAS_PASSWORD_LENGTH_DESC="Minimum number of characters required for user passwords."
PLG_SYSTEM_MOKOWAAS_PASSWORD_UPPER_LABEL="Require Uppercase" PLG_SYSTEM_MOKOWAAS_PASSWORD_UPPER_LABEL="Require Uppercase"
@@ -120,6 +120,13 @@ PLG_SYSTEM_MOKOWAAS_FORCE_HTTPS_LABEL="Force HTTPS"
PLG_SYSTEM_MOKOWAAS_FORCE_HTTPS_DESC="Redirect all HTTP requests to HTTPS. Supports reverse proxy setups." PLG_SYSTEM_MOKOWAAS_FORCE_HTTPS_DESC="Redirect all HTTP requests to HTTPS. Supports reverse proxy setups."
PLG_SYSTEM_MOKOWAAS_SESSION_TIMEOUT_LABEL="Admin Session Timeout" PLG_SYSTEM_MOKOWAAS_SESSION_TIMEOUT_LABEL="Admin Session Timeout"
PLG_SYSTEM_MOKOWAAS_SESSION_TIMEOUT_DESC="Minutes of idle time before admin sessions expire. 0 uses the Joomla default." PLG_SYSTEM_MOKOWAAS_SESSION_TIMEOUT_DESC="Minutes of idle time before admin sessions expire. 0 uses the Joomla default."
PLG_SYSTEM_MOKOWAAS_TRUSTED_IPS_LABEL="Trusted IPs (No Session Timeout)"
PLG_SYSTEM_MOKOWAAS_TRUSTED_IPS_DESC="Sessions from these IP addresses or ranges will never time out. Supports exact IPs, CIDR notation (e.g. 10.0.0.0/24), and wildcards (e.g. 192.168.1.*)."
PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_ADDR_LABEL="IP / CIDR"
PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_ADDR_DESC="An IP address, CIDR range, or wildcard pattern."
PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_LABEL_LABEL="Label"
PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_LABEL_DESC="A descriptive label for this entry (e.g. Office, VPN)."
PLG_SYSTEM_MOKOWAAS_TRUSTED_IP_ENABLED_LABEL="Enabled"
PLG_SYSTEM_MOKOWAAS_PASSWORD_LENGTH_LABEL="Minimum Password Length" PLG_SYSTEM_MOKOWAAS_PASSWORD_LENGTH_LABEL="Minimum Password Length"
PLG_SYSTEM_MOKOWAAS_PASSWORD_LENGTH_DESC="Minimum number of characters required for user passwords." PLG_SYSTEM_MOKOWAAS_PASSWORD_LENGTH_DESC="Minimum number of characters required for user passwords."
PLG_SYSTEM_MOKOWAAS_PASSWORD_UPPER_LABEL="Require Uppercase" PLG_SYSTEM_MOKOWAAS_PASSWORD_UPPER_LABEL="Require Uppercase"
+19 -2
View File
@@ -30,7 +30,7 @@
<license>GNU General Public License version 3 or later; see LICENSE.md</license> <license>GNU General Public License version 3 or later; see LICENSE.md</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail> <authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl> <authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.04.00</version> <version>02.11.02</version>
<description>This plugin rebrands the Joomla system interface with MokoWaaS identity. It applies language overrides and ensures consistent branding across the platform.</description> <description>This plugin rebrands the Joomla system interface with MokoWaaS identity. It applies language overrides and ensures consistent branding across the platform.</description>
<namespace path=".">Moko\Plugin\System\MokoWaaS</namespace> <namespace path=".">Moko\Plugin\System\MokoWaaS</namespace>
<scriptfile>script.php</scriptfile> <scriptfile>script.php</scriptfile>
@@ -108,7 +108,7 @@
type="url" type="url"
label="PLG_SYSTEM_MOKOWAAS_SUPPORT_URL_LABEL" label="PLG_SYSTEM_MOKOWAAS_SUPPORT_URL_LABEL"
description="PLG_SYSTEM_MOKOWAAS_SUPPORT_URL_DESC" description="PLG_SYSTEM_MOKOWAAS_SUPPORT_URL_DESC"
default="https://mokoconsulting.tech" default="https://mokoconsulting.tech/support"
/> />
</fieldset> </fieldset>
<fieldset name="waas_access" <fieldset name="waas_access"
@@ -310,6 +310,7 @@
<fieldset name="security" <fieldset name="security"
label="PLG_SYSTEM_MOKOWAAS_FIELDSET_SECURITY_LABEL" label="PLG_SYSTEM_MOKOWAAS_FIELDSET_SECURITY_LABEL"
description="PLG_SYSTEM_MOKOWAAS_FIELDSET_SECURITY_DESC" description="PLG_SYSTEM_MOKOWAAS_FIELDSET_SECURITY_DESC"
addfieldprefix="Moko\Plugin\System\MokoWaaS\Field"
> >
<field name="force_https" type="radio" default="1" <field name="force_https" type="radio" default="1"
label="PLG_SYSTEM_MOKOWAAS_FORCE_HTTPS_LABEL" label="PLG_SYSTEM_MOKOWAAS_FORCE_HTTPS_LABEL"
@@ -322,6 +323,22 @@
label="PLG_SYSTEM_MOKOWAAS_SESSION_TIMEOUT_LABEL" label="PLG_SYSTEM_MOKOWAAS_SESSION_TIMEOUT_LABEL"
description="PLG_SYSTEM_MOKOWAAS_SESSION_TIMEOUT_DESC" description="PLG_SYSTEM_MOKOWAAS_SESSION_TIMEOUT_DESC"
default="60" hint="Minutes (0 = Joomla default)" /> default="60" hint="Minutes (0 = Joomla default)" />
<field
name="current_ip_display"
type="CurrentIp"
label=""
/>
<field
name="trusted_ips"
type="subform"
label="PLG_SYSTEM_MOKOWAAS_TRUSTED_IPS_LABEL"
description="PLG_SYSTEM_MOKOWAAS_TRUSTED_IPS_DESC"
formsource="plugins/system/mokowaas/forms/trusted_ip_entry.xml"
multiple="true"
layout="joomla.form.field.subform.repeatable-table"
groupByFieldset="false"
buttons="add,remove,move"
/>
<field name="password_min_length" type="number" default="12" <field name="password_min_length" type="number" default="12"
label="PLG_SYSTEM_MOKOWAAS_PASSWORD_LENGTH_LABEL" label="PLG_SYSTEM_MOKOWAAS_PASSWORD_LENGTH_LABEL"
description="PLG_SYSTEM_MOKOWAAS_PASSWORD_LENGTH_DESC" /> description="PLG_SYSTEM_MOKOWAAS_PASSWORD_LENGTH_DESC" />
+1 -1
View File
@@ -482,7 +482,7 @@ class plgSystemMokoWaaSInstallerScript implements InstallerScriptInterface
return [ return [
'{{BRAND_NAME}}' => $params->get('brand_name', 'MokoWaaS'), '{{BRAND_NAME}}' => $params->get('brand_name', 'MokoWaaS'),
'{{COMPANY_NAME}}' => $params->get('company_name', 'Moko Consulting'), '{{COMPANY_NAME}}' => $params->get('company_name', 'Moko Consulting'),
'{{SUPPORT_URL}}' => $params->get('support_url', 'https://mokoconsulting.tech'), '{{SUPPORT_URL}}' => $params->get('support_url', 'https://mokoconsulting.tech/support'),
]; ];
} }
@@ -7,7 +7,7 @@
<license>GPL-3.0-or-later</license> <license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail> <authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl> <authorUrl>https://mokoconsulting.tech</authorUrl>
<version>02.04.00</version> <version>02.11.02</version>
<description>Joomla Web Services API routes for MokoWaaS site management — health checks, cache, updates, backups, and site info.</description> <description>Joomla Web Services API routes for MokoWaaS site management — health checks, cache, updates, backups, and site info.</description>
<namespace path="src">Moko\Plugin\WebServices\MokoWaaS</namespace> <namespace path="src">Moko\Plugin\WebServices\MokoWaaS</namespace>
<files> <files>
@@ -11,6 +11,7 @@ namespace Moko\Plugin\WebServices\MokoWaaS\Extension;
defined('_JEXEC') or die; defined('_JEXEC') or die;
use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Event\Application\BeforeApiRouteEvent;
use Joomla\CMS\Router\ApiRouter; use Joomla\CMS\Router\ApiRouter;
use Joomla\Event\SubscriberInterface; use Joomla\Event\SubscriberInterface;
@@ -36,14 +37,16 @@ final class MokoWaaSApi extends CMSPlugin implements SubscriberInterface
/** /**
* Register API routes for MokoWaaS. * Register API routes for MokoWaaS.
* *
* @param ApiRouter $router The API router * @param BeforeApiRouteEvent $event The API route event (Joomla 6 typed event)
* *
* @return void * @return void
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function onBeforeApiRoute(&$router): void public function onBeforeApiRoute(BeforeApiRouteEvent $event): void
{ {
$router = $event->getRouter();
$router->createCRUDRoutes( $router->createCRUDRoutes(
'v1/mokowaas/health', 'v1/mokowaas/health',
'health', 'health',
+1 -1
View File
@@ -2,7 +2,7 @@
<extension type="package" method="upgrade"> <extension type="package" method="upgrade">
<name>MokoWaaS</name> <name>MokoWaaS</name>
<packagename>mokowaas</packagename> <packagename>mokowaas</packagename>
<version>02.04.00</version> <version>02.11.02</version>
<creationDate>2026-05-23</creationDate> <creationDate>2026-05-23</creationDate>
<author>Moko Consulting</author> <author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail> <authorEmail>hello@mokoconsulting.tech</authorEmail>
+106 -64
View File
@@ -1,83 +1,125 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<!-- Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech> <!-- Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-or-later
VERSION: 02.04.00 VERSION: 02.09.00
--> -->
<updates> <updates>
<update> <update>
<name>MokoWaaS</name> <name>MokoWaaS</name>
<description>MokoWaaS update</description> <description>MokoWaaS update</description>
<element>mokowaas</element> <element>pkg_mokowaas</element>
<type>package</type> <type>package</type>
<version>02.04.00-dev</version> <version>02.09.00</version>
<tags><tag>development</tag></tags> <client>site</client>
<infourl title="MokoWaaS">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/tag/development</infourl>
<downloads>
<downloadurl type="full" format="zip">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/download/development/pkg_mokowaas-02.04.00-dev.zip</downloadurl>
</downloads>
<targetplatform name="joomla" version="(5|6)\..*" />
<maintainer>Moko Consulting</maintainer>
<maintainerurl>https://mokoconsulting.tech</maintainerurl>
</update>
<update>
<name>MokoWaaS</name>
<description>MokoWaaS update</description>
<element>mokowaas</element>
<type>package</type>
<version>02.04.00-alpha</version>
<tags><tag>alpha</tag></tags>
<infourl title="MokoWaaS">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/tag/alpha</infourl>
<downloads>
<downloadurl type="full" format="zip">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/download/alpha/pkg_mokowaas-02.04.00-alpha.zip</downloadurl>
</downloads>
<targetplatform name="joomla" version="(5|6)\..*" />
<maintainer>Moko Consulting</maintainer>
<maintainerurl>https://mokoconsulting.tech</maintainerurl>
</update>
<update>
<name>MokoWaaS</name>
<description>MokoWaaS update</description>
<element>mokowaas</element>
<type>package</type>
<version>02.04.00-beta</version>
<tags><tag>beta</tag></tags>
<infourl title="MokoWaaS">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/tag/beta</infourl>
<downloads>
<downloadurl type="full" format="zip">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/download/beta/pkg_mokowaas-02.04.00-beta.zip</downloadurl>
</downloads>
<targetplatform name="joomla" version="(5|6)\..*" />
<maintainer>Moko Consulting</maintainer>
<maintainerurl>https://mokoconsulting.tech</maintainerurl>
</update>
<update>
<name>MokoWaaS</name>
<description>MokoWaaS update</description>
<element>mokowaas</element>
<type>package</type>
<version>02.04.00-rc</version>
<tags><tag>rc</tag></tags>
<infourl title="MokoWaaS">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/tag/rc</infourl>
<downloads>
<downloadurl type="full" format="zip">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/download/rc/pkg_mokowaas-02.04.00-rc.zip</downloadurl>
</downloads>
<targetplatform name="joomla" version="(5|6)\..*" />
<maintainer>Moko Consulting</maintainer>
<maintainerurl>https://mokoconsulting.tech</maintainerurl>
</update>
<update>
<name>MokoWaaS</name>
<description>MokoWaaS update</description>
<element>mokowaas</element>
<type>package</type>
<version>02.04.00</version>
<tags><tag>stable</tag></tags> <tags><tag>stable</tag></tags>
<infourl title="MokoWaaS">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/tag/stable</infourl> <infourl title="MokoWaaS">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/tag/stable</infourl>
<downloads> <downloads>
<downloadurl type="full" format="zip">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/download/stable/pkg_mokowaas-02.04.00.zip</downloadurl> <downloadurl type="full" format="zip">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/download/stable/pkg_mokowaas-02.09.00.zip</downloadurl>
</downloads> </downloads>
<targetplatform name="joomla" version="(5|6)\..*" /> <targetplatform name="joomla" version="(5|6)\..*" />
<maintainer>Moko Consulting</maintainer> <maintainer>Moko Consulting</maintainer>
<maintainerurl>https://mokoconsulting.tech</maintainerurl> <maintainerurl>https://mokoconsulting.tech</maintainerurl>
</update> </update>
<update>
<name>MokoWaaS</name>
<description>MokoWaaS update</description>
<element>pkg_mokowaas</element>
<type>package</type>
<version>02.09.00</version>
<client>site</client>
<tags><tag>rc</tag></tags>
<infourl title="MokoWaaS">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/tag/development</infourl>
<downloads>
<downloadurl type="full" format="zip">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/download/development/pkg_mokowaas-02.09.00-dev.zip</downloadurl>
</downloads>
<targetplatform name="joomla" version="(5|6)\..*" />
<maintainer>Moko Consulting</maintainer>
<maintainerurl>https://mokoconsulting.tech</maintainerurl>
</update>
<update>
<name>MokoWaaS</name>
<description>MokoWaaS update</description>
<element>pkg_mokowaas</element>
<type>package</type>
<version>02.09.00</version>
<client>site</client>
<tags><tag>beta</tag></tags>
<infourl title="MokoWaaS">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/tag/development</infourl>
<downloads>
<downloadurl type="full" format="zip">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/download/development/pkg_mokowaas-02.09.00-dev.zip</downloadurl>
</downloads>
<targetplatform name="joomla" version="(5|6)\..*" />
<maintainer>Moko Consulting</maintainer>
<maintainerurl>https://mokoconsulting.tech</maintainerurl>
</update>
<update>
<name>MokoWaaS</name>
<description>MokoWaaS update</description>
<element>pkg_mokowaas</element>
<type>package</type>
<version>02.09.00</version>
<client>site</client>
<tags><tag>alpha</tag></tags>
<infourl title="MokoWaaS">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/tag/development</infourl>
<downloads>
<downloadurl type="full" format="zip">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/download/development/pkg_mokowaas-02.09.00-dev.zip</downloadurl>
</downloads>
<targetplatform name="joomla" version="(5|6)\..*" />
<maintainer>Moko Consulting</maintainer>
<maintainerurl>https://mokoconsulting.tech</maintainerurl>
</update>
<update>
<name>MokoWaaS</name>
<description>MokoWaaS update</description>
<element>pkg_mokowaas</element>
<type>package</type>
<version>02.09.00</version>
<client>site</client>
<tags><tag>dev</tag></tags>
<infourl title="MokoWaaS">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/tag/development</infourl>
<downloads>
<downloadurl type="full" format="zip">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/download/development/pkg_mokowaas-02.09.00-dev.zip</downloadurl>
</downloads>
<targetplatform name="joomla" version="(5|6)\..*" />
<maintainer>Moko Consulting</maintainer>
<maintainerurl>https://mokoconsulting.tech</maintainerurl>
</update>
<update>
<name>System - MokoWaaS</name>
<description>MokoWaaS update (legacy plugin)</description>
<element>mokowaas</element>
<type>plugin</type>
<folder>system</folder>
<client>site</client>
<version>02.09.00</version>
<tags><tag>stable</tag></tags>
<infourl title="MokoWaaS">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/tag/development</infourl>
<downloads>
<downloadurl type="full" format="zip">https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/download/development/pkg_mokowaas-02.09.00-dev.zip</downloadurl>
</downloads>
<targetplatform name="joomla" version="(5|6)\..*" />
<maintainer>Moko Consulting</maintainer>
<maintainerurl>https://mokoconsulting.tech</maintainerurl>
</update>
<update>
<name>MokoWaaS</name>
<description>MokoWaaS development build.</description>
<element>pkg_mokowaas</element>
<type>package</type>
<client>site</client>
<version>02.11.01</version>
<creationDate>2026-05-26</creationDate>
<infourl title='MokoWaaS'>https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/tag/development</infourl>
<downloads>
<downloadurl type='full' format='zip'>https://git.mokoconsulting.tech/MokoConsulting/MokoWaaS/releases/download/development/pkg_mokowaas-02.11.01-dev.zip</downloadurl>
</downloads>
<sha256>d517b072a0962c156f0e01a0cd3fea232d5c99240cd452632d37c84b157889e2</sha256>
<tags><tag>development</tag></tags>
<maintainer>Moko Consulting</maintainer>
<maintainerurl>https://mokoconsulting.tech</maintainerurl>
<targetplatform name='joomla' version='(5|6).*'/>
</update>
</updates> </updates>