Compare commits

...

15 Commits

Author SHA1 Message Date
Jonathan Miller cebbb33d87 fix: use single-key pattern instead of universal backup
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (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
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Generic: Repo Health / Access control (pull_request) Successful in 2s
Universal: Auto Version Bump / Version Bump (push) Successful in 8s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 7s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 8s
Universal: PR Check / Validate PR (pull_request) Failing after 11s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request_target) Failing after 14s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 36s
2026-06-06 17:32:31 -05:00
Jonathan Miller 8b7ea2e2c2 Merge branch 'dev' of https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx into dev
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (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
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Generic: Repo Health / Access control (pull_request) Successful in 2s
Universal: Auto Version Bump / Version Bump (push) Successful in 5s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 8s
Universal: PR Check / Validate PR (pull_request) Failing after 10s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 11s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request_target) Failing after 11s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 31s
2026-06-06 17:21:46 -05:00
Jonathan Miller ce9b5f0e5c feat: download key preservation + license key warning (MokoWaaS pattern) 2026-06-06 17:21:27 -05:00
jmiller 59875466f4 chore: sync .mokogitea/workflows/auto-release.yml from moko-platform [skip ci] 2026-06-06 19:50:39 +00:00
jmiller 32cb7cecd6 chore: sync .mokogitea/workflows/pre-release.yml from moko-platform [skip ci] 2026-06-06 19:48:12 +00:00
Jonathan Miller f573ac0a77 chore: move CLAUDE.md to .mokogitea/ directory
Relocate CLAUDE.md from repo root to .mokogitea/ per project convention.
Content updated with focused, repo-specific architecture and rules.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-06 09:31:23 -05:00
jmiller 24e42d9132 chore: sync .mokogitea/workflows/pre-release.yml from moko-platform [skip ci] 2026-06-06 12:31:36 +00:00
Jonathan Miller d957022fc1 chore: remove submodule update workflow for MokoWaaS
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Failing after 4s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 6s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 6s
Universal: PR Check / Validate PR (pull_request) Failing after 6s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 7s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request_target) Failing after 9s
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Has been cancelled
Joomla: Extension CI / PHPStan Analysis (pull_request) Has been cancelled
Joomla: Extension CI / Build RC Pre-Release (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
Generic: Repo Health / Scripts governance (pull_request) Has been cancelled
Generic: Repo Health / Repository health (pull_request) Has been cancelled
Generic: Repo Health / Report Issues (pull_request) Has been cancelled
Submodule reference removed from MokoWaaS; this workflow is no longer needed.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-04 22:21:08 -05:00
Jonathan Miller 82d5beb0f0 Merge branch 'main' into dev
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 2s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 4s
Universal: Auto Version Bump / Version Bump (push) Failing after 4s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 5s
Universal: PR Check / Validate PR (pull_request) Failing after 6s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request_target) Failing after 7s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 1m40s
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Has been cancelled
Joomla: Extension CI / PHPStan Analysis (pull_request) Has been cancelled
Joomla: Extension CI / Build RC Pre-Release (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
Generic: Repo Health / Scripts governance (pull_request) Has been cancelled
Generic: Repo Health / Repository health (pull_request) Has been cancelled
Generic: Repo Health / Report Issues (pull_request) Has been cancelled
# Conflicts:
#	updates.xml
2026-06-04 20:28:09 -05:00
Jonathan Miller 9968c81660 chore: remove updates.xml from dev branch [skip ci]
Update server now served via Gitea Pages from main only.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-04 19:56:14 -05:00
jmiller 6802b256d0 chore: remove update-server workflow [skip ci] 2026-06-05 00:07:21 +00:00
Jonathan Miller d0ea5e43c0 chore: merge main into dev, resolve version header conflicts [skip bump]
Generic: Repo Health / Site Health (push) Has been skipped
Universal: Auto Version Bump / Version Bump (push) Has been skipped
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 5s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 5s
Universal: PR Check / Validate PR (pull_request) Failing after 6s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 29s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request_target) Failing after 8s
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Has been cancelled
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Has been cancelled
Joomla: Extension CI / PHPStan Analysis (pull_request) Has been cancelled
Joomla: Extension CI / Build RC Pre-Release (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
Generic: Repo Health / Scripts governance (pull_request) Has been cancelled
Generic: Repo Health / Repository health (pull_request) Has been cancelled
Generic: Repo Health / Report Issues (pull_request) Has been cancelled
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-04 17:52:44 -05:00
gitea-actions[bot] 7b9ea92faa chore: update development channel 02.19.06-dev [skip ci] 2026-06-04 22:48:21 +00:00
gitea-actions[bot] 9f628201ad chore(version): auto-bump 02.19.06-dev [skip ci] 2026-06-04 22:48:19 +00:00
Jonathan Miller 86f341bd72 fix(script): remove faulty template-mokoonyx duplicate in postflight
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Universal: Auto Version Bump / Version Bump (push) Failing after 4s
Update Server / Update Server (push) Successful in 12s
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
Adds cleanup for the template-mokoonyx extension entry created by
a bad install. Removes the extension, its update sites link, and
any template styles. Runs on every update via postflight.

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-04 17:48:02 -05:00
16 changed files with 514 additions and 500 deletions
+63
View File
@@ -0,0 +1,63 @@
# MokoOnyx
Joomla site template — successor to MokoCassiopeia. Base template for all WaaS client deployments.
## Quick Reference
| Field | Value |
|---|---|
| **Element** | `tpl_mokoonyx` |
| **Type** | Joomla site template |
| **Language** | PHP 8.1+ / CSS / JS |
| **Branch** | develop on `dev`, merge to `main` (protected) |
| **Wiki** | [MokoOnyx Wiki](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/wiki) |
## Commands
```bash
make build # Build template ZIP
make lint # Run linters
make validate # Validate structure
make release # Full release pipeline
make minify # Minify CSS/JS assets
make clean # Clean build artifacts
composer install # Install PHP dependencies
```
## Architecture
Joomla **site template** — the base layer that client theme packages override:
- `src/templateDetails.xml` — template manifest
- `src/index.php` — main template entry point
- `src/error.php` — error page
- `src/offline.php` — maintenance page
- `src/component.php` — print/component-only layout
- `src/html/` — template overrides for core components
- `src/media/css/` — base stylesheets
- `src/media/js/` — base scripts
- `src/media/images/` — template images
- `src/language/` — translations
### Client Theme Packages
Client repos (`client-clarksvillefurs`, `client-optainfunding`, etc.) install `type="file"` packages that overlay client-specific CSS, images, and JS into the MokoOnyx media directory. MokoOnyx provides the structure; client themes customize the appearance.
### Minification
`MokoMinifyHelper` handles runtime CSS/JS minification in Joomla. Build-time minification via `make minify`. Never commit `*.min.css`/`*.min.js` — they're generated.
## Rules
- **Never commit** `.claude/`, `.mcp.json`, `TODO.md`, `*.min.css`/`*.min.js`
- **Attribution**: `Authored-by: Moko Consulting`
- **Workflow directory**: `.mokogitea/` (not `.gitea/` or `.github/`)
- **Minification**: handled at build time (CI) and runtime (MokoMinifyHelper)
- **Wiki**: documentation lives in the Gitea wiki, not `docs/` files
- **Standards**: [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)
## Coding Standards
- PHP 8.1+ minimum
- SPDX license headers on all PHP files
- `defined('_JEXEC') or die;` on all PHP files
+1 -1
View File
@@ -9,7 +9,7 @@
<display-name>Template - MokoOnyx</display-name> <display-name>Template - MokoOnyx</display-name>
<org>MokoConsulting</org> <org>MokoConsulting</org>
<description>MokoOnyx - Joomla site template (successor to MokoCassiopeia)</description> <description>MokoOnyx - Joomla site template (successor to MokoCassiopeia)</description>
<version>02.20.00</version> <version>02.19.06</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>
+70 -31
View File
@@ -17,7 +17,7 @@
# | Reads manifest.xml (joomla|dolibarr|generic) to branch logic. | # | Reads manifest.xml (joomla|dolibarr|generic) to branch logic. |
# | | # | |
# | Platform-specific: | # | Platform-specific: |
# | joomla: XML manifest, updates.xml, type-prefixed packages | # | joomla: XML manifest, type-prefixed packages |
# | dolibarr: mod*.class.php, update.txt, dev version reset | # | dolibarr: mod*.class.php, update.txt, dev version reset |
# | generic: README-only, no update stream | # | generic: README-only, no update stream |
# | | # | |
@@ -71,20 +71,25 @@ jobs:
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
run: | run: |
if ! command -v composer &> /dev/null; then if [ -f /opt/moko-platform/cli/version_bump.php ] && [ -f /opt/moko-platform/vendor/autoload.php ]; 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 echo Using pre-installed /opt/moko-platform
echo MOKO_CLI=/opt/moko-platform/cli >> $GITHUB_ENV
else
echo Falling back to fresh clone
if ! command -v composer > /dev/null 2>&1; 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
rm -rf /tmp/moko-platform-api
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git
git clone --depth 1 --branch main --quiet $CLONE_URL /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 fi
# Always fetch latest CLI tools — never use stale cache from previous runs
rm -rf /tmp/moko-platform-api
git clone --depth 1 --branch main --quiet \
"https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git" \
/tmp/moko-platform-api
cd /tmp/moko-platform-api
composer install --no-dev --no-interaction --quiet
- name: Rename branch to rc - name: Rename branch to rc
run: | run: |
php /tmp/moko-platform-api/cli/branch_rename.php \ php ${MOKO_CLI}/branch_rename.php \
--from "${{ github.event.pull_request.head.ref || 'dev' }}" --to rc \ --from "${{ github.event.pull_request.head.ref || 'dev' }}" --to rc \
--token "${{ secrets.MOKOGITEA_TOKEN }}" \ --token "${{ secrets.MOKOGITEA_TOKEN }}" \
--api-base "${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" \ --api-base "${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" \
@@ -100,16 +105,15 @@ jobs:
- name: Publish RC release - name: Publish RC release
run: | run: |
php /tmp/moko-platform-api/cli/release_publish.php \ php ${MOKO_CLI}/release_publish.php \
--path . --stability rc --bump minor --branch rc \ --path . --stability rc --bump minor --branch rc \
--token "${{ secrets.MOKOGITEA_TOKEN }}" \ --token "${{ secrets.MOKOGITEA_TOKEN }}"
--skip-update-stream
- name: Summary - name: Summary
if: always() if: always()
run: | run: |
echo "## Promoted to Release Candidate" >> $GITHUB_STEP_SUMMARY echo "## Promoted to Release Candidate" >> $GITHUB_STEP_SUMMARY
echo "Branch renamed to rc, minor bump, RC release built (updates.xml managed by Gitea Pages)" >> $GITHUB_STEP_SUMMARY echo "Branch renamed to rc, minor bump, RC release built" >> $GITHUB_STEP_SUMMARY
# ── Merged PR → Build & Release (or promote RC to stable) ──────────────────── # ── Merged PR → Build & Release (or promote RC to stable) ────────────────────
release: release:
@@ -151,25 +155,60 @@ jobs:
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_MIRROR_TOKEN }}"}}' COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_MIRROR_TOKEN }}"}}'
run: | run: |
# Ensure PHP + Composer are available if [ -f /opt/moko-platform/cli/version_bump.php ] && [ -f /opt/moko-platform/vendor/autoload.php ]; then
if ! command -v composer &> /dev/null; then echo Using pre-installed /opt/moko-platform
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 echo MOKO_CLI=/opt/moko-platform/cli >> $GITHUB_ENV
else
echo Falling back to fresh clone
if ! command -v composer > /dev/null 2>&1; 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
rm -rf /tmp/moko-platform-api
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git
git clone --depth 1 --branch main --quiet $CLONE_URL /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 fi
# Always fetch latest CLI tools — never use stale cache from previous runs
rm -rf /tmp/moko-platform-api
git clone --depth 1 --branch main --quiet \
"https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git" \
/tmp/moko-platform-api
cd /tmp/moko-platform-api
composer install --no-dev --no-interaction --quiet
- name: "Publish stable release" - name: "Publish stable release"
run: | run: |
php /tmp/moko-platform-api/cli/release_publish.php \ php ${MOKO_CLI}/release_publish.php \
--path . --stability stable --bump minor --branch main \ --path . --stability stable --bump minor --branch main \
--token "${{ secrets.MOKOGITEA_TOKEN }}" \ --token "${{ secrets.MOKOGITEA_TOKEN }}"
--skip-update-stream
- name: Update release notes from CHANGELOG.md
run: |
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
# Extract [Unreleased] section from changelog
if [ -f "CHANGELOG.md" ]; then
NOTES=$(awk '/^## \[Unreleased\]/{found=1; next} /^## \[/{if(found) exit} found{print}' CHANGELOG.md)
[ -z "$NOTES" ] && NOTES="Stable release"
else
NOTES="Stable release"
fi
# Update release body via API
RELEASE_ID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \
"${API_BASE}/releases/tags/stable" | python3 -c "import json,sys; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true)
if [ -n "$RELEASE_ID" ]; then
python3 -c "
import json, urllib.request
body = open('/dev/stdin').read()
payload = json.dumps({'body': body}).encode()
req = urllib.request.Request(
'${API_BASE}/releases/${RELEASE_ID}',
data=payload, method='PATCH',
headers={
'Authorization': 'token ${{ secrets.MOKOGITEA_TOKEN }}',
'Content-Type': 'application/json'
})
urllib.request.urlopen(req)
" <<< "$NOTES"
echo "Release notes updated from CHANGELOG.md"
fi
# -- STEP 9: Mirror to GitHub (stable only) -------------------------------- # -- STEP 9: Mirror to GitHub (stable only) --------------------------------
- name: "Step 9: Mirror release to GitHub" - name: "Step 9: Mirror release to GitHub"
@@ -182,7 +221,7 @@ jobs:
RELEASE_TAG="${{ steps.version.outputs.release_tag }}" RELEASE_TAG="${{ steps.version.outputs.release_tag }}"
GH_REPO="${{ vars.GH_MIRROR_REPO || github.repository }}" GH_REPO="${{ vars.GH_MIRROR_REPO || github.repository }}"
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
php /tmp/moko-platform-api/cli/release_mirror.php \ php ${MOKO_CLI}/release_mirror.php \
--version "$VERSION" --tag "$RELEASE_TAG" \ --version "$VERSION" --tag "$RELEASE_TAG" \
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \ --token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \
--gh-token "${{ secrets.GH_MIRROR_TOKEN }}" --gh-repo "$GH_REPO" \ --gh-token "${{ secrets.GH_MIRROR_TOKEN }}" --gh-repo "$GH_REPO" \
@@ -256,7 +295,7 @@ jobs:
continue-on-error: true continue-on-error: true
run: | run: |
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
php /tmp/moko-platform-api/cli/version_reset_dev.php \ php ${MOKO_CLI}/version_reset_dev.php \
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "${API_BASE}" \ --token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "${API_BASE}" \
--branch dev --path . 2>&1 || true --branch dev --path . 2>&1 || true
+1 -1
View File
@@ -5,7 +5,7 @@
# FILE INFORMATION # FILE INFORMATION
# DEFGROUP: Gitea.Workflow # DEFGROUP: Gitea.Workflow
# INGROUP: moko-platform.Automation # INGROUP: moko-platform.Automation
# VERSION: 02.20.00 # VERSION: 02.19.06
# BRIEF: Auto-create feature branch when an issue is opened # BRIEF: Auto-create feature branch when an issue is opened
name: "Universal: Issue Branch" name: "Universal: Issue Branch"
+243 -259
View File
@@ -1,259 +1,243 @@
# 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.01.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:
pull_request: pull_request:
types: [closed] types: [closed]
branches: branches:
- dev - dev
pull_request_target: pull_request_target:
types: [synchronize, opened, reopened] types: [synchronize, opened, reopened]
branches: branches:
- main - main
workflow_dispatch: workflow_dispatch:
inputs: inputs:
stability: stability:
description: 'Pre-release channel' description: 'Pre-release channel'
required: true required: true
type: choice type: choice
options: options:
- development - development
- alpha - alpha
- beta - beta
- release-candidate - release-candidate
permissions: permissions:
contents: write contents: write
env: env:
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }} GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }} GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }}
jobs: jobs:
build: build:
name: "Build Pre-Release (${{ inputs.stability || 'development' }})" name: "Build Pre-Release (${{ inputs.stability || 'development' }})"
runs-on: release runs-on: release
if: >- if: >-
github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_dispatch' ||
(github.event_name == 'pull_request' && github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'dev') || (github.event_name == 'pull_request' && github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'dev') ||
(github.event_name == 'pull_request_target' && github.event.pull_request.base.ref == 'main') (github.event_name == 'pull_request_target' && github.event.pull_request.base.ref == 'main')
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
token: ${{ secrets.MOKOGITEA_TOKEN }} token: ${{ secrets.MOKOGITEA_TOKEN }}
ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || '' }} ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || '' }}
- name: Setup moko-platform tools - name: Setup moko-platform tools
env: env:
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
run: | run: |
if ! command -v composer &> /dev/null; then # Use pre-installed /opt/moko-platform if available (updated by cron every 6h)
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 if [ -f /opt/moko-platform/cli/version_bump.php ] && [ -f /opt/moko-platform/cli/manifest_element.php ] && [ -f /opt/moko-platform/vendor/autoload.php ]; then
fi echo Using pre-installed /opt/moko-platform
# Always fetch latest CLI tools — never use stale cache from previous runs echo MOKO_CLI=/opt/moko-platform/cli >> $GITHUB_ENV
rm -rf /tmp/moko-platform-api else
git clone --depth 1 --branch main --quiet \ echo Falling back to fresh clone
"https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git" \ if ! command -v composer > /dev/null 2>&1; then
/tmp/moko-platform-api 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
cd /tmp/moko-platform-api && composer install --no-dev --no-interaction --quiet fi
echo "MOKO_CLI=/tmp/moko-platform-api/cli" >> "$GITHUB_ENV" rm -rf /tmp/moko-platform-api
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git
- name: Detect platform git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/moko-platform-api
id: platform cd /tmp/moko-platform-api && composer install --no-dev --no-interaction --quiet
run: | echo MOKO_CLI=/tmp/moko-platform-api/cli >> $GITHUB_ENV
php ${MOKO_CLI}/manifest_read.php --path . --github-output fi
- name: Resolve metadata and bump version - name: Detect platform
id: meta id: platform
run: | run: |
# Auto-detect stability: RC for PRs targeting main, else use input or default to development php ${MOKO_CLI}/manifest_read.php --path . --github-output
if [ "${{ github.event_name }}" = "pull_request_target" ] && [ "${{ github.event.pull_request.base.ref }}" = "main" ]; then
STABILITY="release-candidate" - name: Resolve metadata and bump version
else id: meta
STABILITY="${{ inputs.stability || 'development' }}" run: |
fi # Auto-detect stability: RC for PRs targeting main, else use input or default to development
if [ "${{ github.event_name }}" = "pull_request_target" ] && [ "${{ github.event.pull_request.base.ref }}" = "main" ]; then
case "$STABILITY" in STABILITY="release-candidate"
development) SUFFIX="-dev"; TAG="development" ;; else
alpha) SUFFIX="-alpha"; TAG="alpha" ;; STABILITY="${{ inputs.stability || 'development' }}"
beta) SUFFIX="-beta"; TAG="beta" ;; fi
release-candidate) SUFFIX="-rc"; TAG="release-candidate" ;;
esac case "$STABILITY" in
development) SUFFIX="-dev"; TAG="development" ;;
# Read current version (bump already handled by push workflow) alpha) SUFFIX="-alpha"; TAG="alpha" ;;
VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null) beta) SUFFIX="-beta"; TAG="beta" ;;
[ -z "$VERSION" ] && VERSION="00.00.01" release-candidate) SUFFIX="-rc"; TAG="release-candidate" ;;
esac
# Strip any existing suffix from version before applying stability
VERSION=$(echo "$VERSION" | sed 's/-\(dev\|alpha\|beta\|rc\)$//') # Bump version via CLI: patch for dev/alpha/beta, minor for RC
case "$STABILITY" in
php ${MOKO_CLI}/version_set_platform.php \ release-candidate) BUMP="minor" ;;
--path . --version "$VERSION" --branch "${{ github.ref_name }}" --stability "$STABILITY" 2>/dev/null || true *) BUMP="patch" ;;
esac
# Verify version consistency across all files
php ${MOKO_CLI}/version_check.php --path . --fix 2>/dev/null || true php ${MOKO_CLI}/version_bump.php --path . $([ "$BUMP" = "minor" ] && echo "--minor") 2>/dev/null || true
# Update VERSION variable with suffix # Set stability suffix and verify consistency
if [ -n "$SUFFIX" ]; then VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null || echo "00.00.01")
VERSION="${VERSION}${SUFFIX}" VERSION=$(echo "$VERSION" | sed 's/-\(dev\|alpha\|beta\|rc\)$//')
fi
php ${MOKO_CLI}/version_set_platform.php \
# Commit version bump --path . --version "$VERSION" --branch "${{ github.ref_name }}" --stability "$STABILITY" 2>/dev/null || true
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" php ${MOKO_CLI}/version_check.php --path . --fix 2>/dev/null || true
git config --local user.name "gitea-actions[bot]"
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" # Ensure licensing tags (updateservers, dlid) if enabled in manifest.xml
git add -A php ${MOKO_CLI}/manifest_licensing.php --path . --fix 2>/dev/null || true
git diff --cached --quiet || {
git commit -m "chore(version): pre-release bump to ${VERSION} [skip ci]" # Append suffix for output
git push origin HEAD 2>&1 if [ -n "$SUFFIX" ]; then
} VERSION="${VERSION}${SUFFIX}"
fi
# Auto-detect element via manifest_element.php
php ${MOKO_CLI}/manifest_element.php \ # Commit version bump
--path . --version "$VERSION" --stability "$STABILITY" \ git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
--repo "${GITEA_REPO}" --github-output git config --local user.name "gitea-actions[bot]"
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
# Read back element outputs git add -A
EXT_ELEMENT=$(grep '^ext_element=' "$GITHUB_OUTPUT" | tail -1 | cut -d= -f2) git diff --cached --quiet || {
ZIP_NAME=$(grep '^zip_name=' "$GITHUB_OUTPUT" | tail -1 | cut -d= -f2) git commit -m "chore(version): pre-release bump to ${VERSION} [skip ci]"
[ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -') git push origin HEAD 2>&1
[ -z "$ZIP_NAME" ] && ZIP_NAME="${EXT_ELEMENT}-${VERSION}.zip" }
echo "version=${VERSION}" >> "$GITHUB_OUTPUT" # Auto-detect element via manifest_element.php
echo "stability=${STABILITY}" >> "$GITHUB_OUTPUT" php ${MOKO_CLI}/manifest_element.php \
echo "suffix=${SUFFIX}" >> "$GITHUB_OUTPUT" --path . --version "$VERSION" --stability "$STABILITY" \
echo "tag=${TAG}" >> "$GITHUB_OUTPUT" --repo "${GITEA_REPO}" --github-output
echo "zip_name=${ZIP_NAME}" >> "$GITHUB_OUTPUT"
echo "ext_element=${EXT_ELEMENT}" >> "$GITHUB_OUTPUT" # Read back element outputs
EXT_ELEMENT=$(grep '^ext_element=' "$GITHUB_OUTPUT" | tail -1 | cut -d= -f2)
echo "=== Pre-Release: ${EXT_ELEMENT} ${VERSION}${SUFFIX} ===" ZIP_NAME=$(grep '^zip_name=' "$GITHUB_OUTPUT" | tail -1 | cut -d= -f2)
[ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -')
- name: Create release [ -z "$ZIP_NAME" ] && ZIP_NAME="${EXT_ELEMENT}-${VERSION}.zip"
id: release
run: | echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
TAG="${{ steps.meta.outputs.tag }}" echo "stability=${STABILITY}" >> "$GITHUB_OUTPUT"
VERSION="${{ steps.meta.outputs.version }}" echo "suffix=${SUFFIX}" >> "$GITHUB_OUTPUT"
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
php ${MOKO_CLI}/release_create.php \ echo "zip_name=${ZIP_NAME}" >> "$GITHUB_OUTPUT"
--path . --version "$VERSION" --tag "$TAG" \ echo "ext_element=${EXT_ELEMENT}" >> "$GITHUB_OUTPUT"
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \
--repo "${GITEA_REPO}" --branch dev --prerelease echo "=== Pre-Release: ${EXT_ELEMENT} ${VERSION}${SUFFIX} ==="
- name: Ensure prerelease flag - name: Create release
run: | id: release
TAG="${{ steps.meta.outputs.tag }}" run: |
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" TAG="${{ steps.meta.outputs.tag }}"
# Get release ID by tag and force prerelease=true VERSION="${{ steps.meta.outputs.version }}"
RELEASE_ID=$(curl -s "${API_BASE}/releases/tags/${TAG}" \ API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
-H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" | jq -r '.id // empty') php ${MOKO_CLI}/release_create.php \
if [ -n "$RELEASE_ID" ]; then --path . --version "$VERSION" --tag "$TAG" \
curl -s -X PATCH "${API_BASE}/releases/${RELEASE_ID}" \ --token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \
-H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ --repo "${GITEA_REPO}" --branch dev --prerelease
-H "Content-Type: application/json" \
-d '{"prerelease": true}' - name: Update release notes from CHANGELOG.md
echo "Marked release ${TAG} (id=${RELEASE_ID}) as prerelease" run: |
fi TAG="${{ steps.meta.outputs.tag }}"
VERSION="${{ steps.meta.outputs.version }}"
- name: Build package and upload API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
id: package
run: | # Extract [Unreleased] section from changelog (everything between [Unreleased] and next ## heading)
VERSION="${{ steps.meta.outputs.version }}" if [ -f "CHANGELOG.md" ]; then
TAG="${{ steps.meta.outputs.tag }}" NOTES=$(awk '/^## \[Unreleased\]/{found=1; next} /^## \[/{if(found) exit} found{print}' CHANGELOG.md)
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" [ -z "$NOTES" ] && NOTES="Release ${VERSION}"
php ${MOKO_CLI}/release_package.php \ else
--path . --version "$VERSION" --tag "$TAG" \ NOTES="Release ${VERSION}"
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \ fi
--repo "${GITEA_REPO}" --output /tmp || true
# Update release body via API
- name: Update updates.xml RELEASE_ID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \
if: steps.platform.outputs.platform == 'joomla' "${API_BASE}/releases/tags/${TAG}" | python3 -c "import json,sys; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true)
run: |
VERSION="${{ steps.meta.outputs.version }}" if [ -n "$RELEASE_ID" ]; then
STABILITY="${{ steps.meta.outputs.stability }}" python3 -c "
SHA256="${{ steps.package.outputs.sha256_zip }}" import json, urllib.request
body = open('/dev/stdin').read()
if [ ! -f "updates.xml" ]; then payload = json.dumps({'body': body}).encode()
echo "No updates.xml -- skipping" req = urllib.request.Request(
exit 0 '${API_BASE}/releases/${RELEASE_ID}',
fi data=payload, method='PATCH',
headers={
SHA_FLAG="" 'Authorization': 'token ${{ secrets.MOKOGITEA_TOKEN }}',
[ -n "$SHA256" ] && SHA_FLAG="--sha ${SHA256}" 'Content-Type': 'application/json'
})
php ${MOKO_CLI}/updates_xml_build.php \ urllib.request.urlopen(req)
--path . --version "${VERSION}" --stability "${STABILITY}" \ " <<< "$NOTES"
--gitea-url "${GITEA_URL}" --org "${GITEA_ORG}" --repo "${GITEA_REPO}" \ echo "Release notes updated from CHANGELOG.md"
${SHA_FLAG} fi
# Commit and push - name: Build package and upload
if ! git diff --quiet updates.xml 2>/dev/null; then id: package
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" run: |
git config --local user.name "gitea-actions[bot]" VERSION="${{ steps.meta.outputs.version }}"
git add updates.xml TAG="${{ steps.meta.outputs.tag }}"
git commit -m "chore: update ${STABILITY} channel ${VERSION} [skip ci]" API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
git push origin HEAD 2>&1 || echo "WARNING: push failed" php ${MOKO_CLI}/release_package.php \
fi --path . --version "$VERSION" --tag "$TAG" \
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \
- name: "Sync updates.xml to all branches" --repo "${GITEA_REPO}" --output /tmp || true
if: steps.platform.outputs.platform == 'joomla'
run: | # updates.xml is generated dynamically by MokoGitea license server
CURRENT_BRANCH="${{ github.ref_name }}" # No need to build, commit, or sync updates.xml from workflows
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
git config --local user.name "gitea-actions[bot]" - name: "Delete lesser pre-release channels (cascade)"
continue-on-error: true
for BRANCH in main dev; do run: |
[ "$BRANCH" = "$CURRENT_BRANCH" ] && continue API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
echo "Syncing updates.xml -> ${BRANCH}" TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
git fetch origin "${BRANCH}" 2>/dev/null || continue
git checkout "origin/${BRANCH}" -- updates.xml 2>/dev/null || continue php ${MOKO_CLI}/release_cascade.php \
git checkout "${CURRENT_BRANCH}" -- updates.xml --stability "${{ steps.meta.outputs.stability }}" \
if ! git diff --quiet updates.xml 2>/dev/null; then --token "${TOKEN}" \
git add updates.xml --api-base "${API_BASE}"
git commit -m "chore: sync updates.xml from ${CURRENT_BRANCH} [skip ci]"
git push origin HEAD:refs/heads/${BRANCH} 2>&1 || echo "WARNING: push to ${BRANCH} failed" - name: Summary
fi if: always()
git checkout "${CURRENT_BRANCH}" 2>/dev/null run: |
done VERSION="${{ steps.meta.outputs.version }}"
STABILITY="${{ steps.meta.outputs.stability }}"
- name: "Delete lesser pre-release channels (cascade)" ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
continue-on-error: true SHA256="${{ steps.package.outputs.sha256_zip }}"
run: | echo "## Pre-Release Complete" >> $GITHUB_STEP_SUMMARY
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" echo "" >> $GITHUB_STEP_SUMMARY
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
php ${MOKO_CLI}/release_cascade.php \ echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
--stability "${{ steps.meta.outputs.stability }}" \ echo "| Channel | ${STABILITY} |" >> $GITHUB_STEP_SUMMARY
--token "${TOKEN}" \ echo "| Package | \`${ZIP_NAME}\` |" >> $GITHUB_STEP_SUMMARY
--api-base "${API_BASE}" echo "| SHA-256 | \`${SHA256:-n/a}\` |" >> $GITHUB_STEP_SUMMARY
- name: Summary
if: always()
run: |
VERSION="${{ steps.meta.outputs.version }}"
STABILITY="${{ steps.meta.outputs.stability }}"
ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
SHA256="${{ steps.package.outputs.sha256_zip }}"
echo "## Pre-Release Complete" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Channel | ${STABILITY} |" >> $GITHUB_STEP_SUMMARY
echo "| Package | \`${ZIP_NAME}\` |" >> $GITHUB_STEP_SUMMARY
echo "| SHA-256 | \`${SHA256:-n/a}\` |" >> $GITHUB_STEP_SUMMARY
@@ -1,106 +0,0 @@
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# BRIEF: Update MokoOnyx submodule in MokoWaas on main and dev branches
name: "Update MokoWaas Submodule"
on:
release:
types: [published]
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
WAAS_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
WAAS_REPO: MokoWaaS
# Path where MokoOnyx lives as a submodule inside MokoWaaS
SUBMODULE_PATH: src/packages/tpl_mokoonyx
permissions:
contents: read
jobs:
update-submodule:
name: "Update submodule on ${{ matrix.branch }}"
runs-on: ubuntu-latest
strategy:
matrix:
branch: [main, dev]
fail-fast: false
steps:
- name: Get release info
id: release
run: |
TAG="${{ github.event.release.tag_name }}"
IS_PRE="${{ github.event.release.prerelease }}"
echo "tag=${TAG}" >> $GITHUB_OUTPUT
echo "prerelease=${IS_PRE}" >> $GITHUB_OUTPUT
echo "Release tag: ${TAG} (prerelease: ${IS_PRE})"
# Skip pre-releases (RC) — only update on stable releases
- name: Skip pre-releases
if: steps.release.outputs.prerelease == 'true'
run: |
echo "Skipping pre-release ${TAG} — only stable releases update MokoWaas"
exit 0
- name: Clone MokoWaas
if: steps.release.outputs.prerelease != 'true'
run: |
git clone --branch "${{ matrix.branch }}" --depth 1 --recurse-submodules \
"https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${WAAS_ORG}/${WAAS_REPO}.git" \
waas
env:
GIT_TERMINAL_PROMPT: 0
- name: Configure git
if: steps.release.outputs.prerelease != 'true'
working-directory: waas
run: |
git config user.email "gitea-actions[bot]@mokoconsulting.tech"
git config user.name "gitea-actions[bot]"
git remote set-url origin \
"https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${WAAS_ORG}/${WAAS_REPO}.git"
- name: Update submodule to release tag
if: steps.release.outputs.prerelease != 'true'
working-directory: waas
run: |
TAG="${{ steps.release.outputs.tag }}"
SUBPATH="${SUBMODULE_PATH}"
# Verify submodule exists
if [ ! -f ".gitmodules" ] || ! grep -q "${SUBPATH}" .gitmodules; then
echo "::error::Submodule '${SUBPATH}' not found in .gitmodules on ${{ matrix.branch }}"
exit 1
fi
# Fetch the tag in the submodule and update to it
cd "${SUBPATH}"
git fetch origin "refs/tags/${TAG}:refs/tags/${TAG}" --depth 1
git checkout "${TAG}"
cd -
# Stage the submodule pointer change
git add "${SUBPATH}"
# Only commit if there's actually a change
if git diff --cached --quiet; then
echo "Submodule already at ${TAG} on ${{ matrix.branch }} — nothing to do"
else
git commit -m "chore: update MokoOnyx submodule to ${TAG}
Authored-by: Moko Consulting"
git push origin "${{ matrix.branch }}"
echo "Updated MokoOnyx to ${TAG} on ${{ matrix.branch }}"
fi
- name: Summary
if: always() && steps.release.outputs.prerelease != 'true'
run: |
TAG="${{ steps.release.outputs.tag }}"
echo "## MokoWaas Submodule Update (${{ matrix.branch }})" >> $GITHUB_STEP_SUMMARY
echo "Updated \`${SUBMODULE_PATH}\` to \`${TAG}\`" >> $GITHUB_STEP_SUMMARY
+2 -5
View File
@@ -8,16 +8,13 @@
DEFGROUP: Joomla.Template.Site DEFGROUP: Joomla.Template.Site
INGROUP: MokoOnyx.Documentation INGROUP: MokoOnyx.Documentation
PATH: ./CHANGELOG.md PATH: ./CHANGELOG.md
VERSION: 02.20.00 VERSION: 02.19.06
BRIEF: Changelog file documenting version history of MokoOnyx BRIEF: Changelog file documenting version history of MokoOnyx
--> -->
# Changelog — MokoOnyx (VERSION: 02.20.00) # Changelog — MokoOnyx (VERSION: 02.19.06)
## [Unreleased] ## [Unreleased]
## [02.20.00] --- 2026-06-04
### Fixed ### Fixed
- Strip Joomla-injected `p-2` padding class from Font Awesome icons in all menu overrides (default, mainmenu, horizontal) - Strip Joomla-injected `p-2` padding class from Font Awesome icons in all menu overrides (default, mainmenu, horizontal)
-42
View File
@@ -1,42 +0,0 @@
# CLAUDE.md
This file provides guidance to Claude Code when working with this repository.
## Project Overview
**MokoOnyx** -- MokoOnyx - Joomla site template (successor to MokoCassiopeia)
| Field | Value |
|---|---|
| **Platform** | joomla |
| **Language** | PHP |
| **Default branch** | main |
| **License** | GPL-3.0-or-later |
| **Wiki** | [MokoOnyx Wiki](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/wiki) |
| **Standards** | [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home) |
## Common Commands
```bash
composer install # Install PHP dependencies
```
## Architecture
This is a Joomla extension. Key directories:
- `src/` -- extension source (deployed to Joomla)
- `src/*.xml` -- manifest file (version, files, params)
- `src/src/` or `src/services/` -- PHP classes
- `src/language/` -- translation strings
- `src/media/` -- CSS/JS/images
## Rules
- **Workflow directory**: `.mokogitea/` (not `.gitea/` or `.github/`)
- **Never commit** `.claude/`, `.mcp.json`, `TODO.md`, or `*.min.css`/`*.min.js`
- **Attribution**: use `Authored-by: Moko Consulting` in commits
- **Branch strategy**: develop on `dev`, merge to `main` for release
- **Minification**: handled at build time (CI) and runtime (MokoMinifyHelper for Joomla templates)
- **Wiki**: documentation lives in the Gitea wiki, not in `docs/` files
- **Standards**: this repo follows [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home)
+1 -1
View File
@@ -10,7 +10,7 @@
INGROUP: MokoOnyx.Governance INGROUP: MokoOnyx.Governance
REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
FILE: SECURITY.md FILE: SECURITY.md
VERSION: 02.20.00 VERSION: 02.19.06
BRIEF: Security policy and vulnerability reporting process for MokoOnyx. BRIEF: Security policy and vulnerability reporting process for MokoOnyx.
PATH: /SECURITY.md PATH: /SECURITY.md
NOTE: This policy is process oriented and does not replace secure engineering practices. NOTE: This policy is process oriented and does not replace secure engineering practices.
+2 -2
View File
@@ -236,11 +236,11 @@ use Joomla\CMS\Log\Log;
// Update the update server // Update the update server
try { try {
$onyxUpdatesUrl = 'https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/raw/branch/main/updates.xml'; $onyxUpdatesUrl = 'https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/updates.xml';
$query = $db->getQuery(true) $query = $db->getQuery(true)
->update('#__update_sites') ->update('#__update_sites')
->set($db->quoteName('location') . ' = ' . $db->quote($onyxUpdatesUrl)) ->set($db->quoteName('location') . ' = ' . $db->quote($onyxUpdatesUrl))
->set($db->quoteName('name') . ' = ' . $db->quote($newDisplay)) ->set($db->quoteName('name') . ' = ' . $db->quote('Template - MokoOnyx'))
->where($db->quoteName('location') . ' LIKE ' . $db->quote('%MokoCassiopeia%')); ->where($db->quoteName('location') . ' LIKE ' . $db->quote('%MokoCassiopeia%'));
$db->setQuery($query)->execute(); $db->setQuery($query)->execute();
$n = $db->getAffectedRows(); $n = $db->getAffectedRows();
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: MokoOnyx * INGROUP: MokoOnyx
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx * REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
* PATH: /html/layouts/joomla/module/card.php * PATH: /html/layouts/joomla/module/card.php
* VERSION: 02.20.00 * VERSION: 02.19.06
* BRIEF: Custom card module chrome — renders module titles for all modules * BRIEF: Custom card module chrome — renders module titles for all modules
*/ */
@@ -11,7 +11,7 @@
* INGROUP: MokoOnyx.Layouts * INGROUP: MokoOnyx.Layouts
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx * REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
* PATH: /src/html/layouts/mokoonyx/article-metadata.php * PATH: /src/html/layouts/mokoonyx/article-metadata.php
* VERSION: 02.20.00 * VERSION: 02.19.06
* BRIEF: Article metadata footer layout -- renders jcfields grouped by field group * BRIEF: Article metadata footer layout -- renders jcfields grouped by field group
*/ */
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: MokoOnyx.Accessibility * INGROUP: MokoOnyx.Accessibility
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx * REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
* PATH: ./media/css/a11y-high-contrast.css * PATH: ./media/css/a11y-high-contrast.css
* VERSION: 02.20.00 * VERSION: 02.19.06
* BRIEF: High-contrast stylesheet for accessibility toolbar * BRIEF: High-contrast stylesheet for accessibility toolbar
*/ */
+127
View File
@@ -34,6 +34,9 @@ class Tpl_MokoonyxInstallerScript implements InstallerScriptInterface
private const OLD_DISPLAY = 'MokoCassiopeia'; private const OLD_DISPLAY = 'MokoCassiopeia';
private const NEW_DISPLAY = 'MokoOnyx'; private const NEW_DISPLAY = 'MokoOnyx';
public function preflight(string $type, InstallerAdapter $parent): bool public function preflight(string $type, InstallerAdapter $parent): bool
{ {
if (version_compare(PHP_VERSION, self::MIN_PHP, '<')) { if (version_compare(PHP_VERSION, self::MIN_PHP, '<')) {
@@ -83,11 +86,16 @@ class Tpl_MokoonyxInstallerScript implements InstallerScriptInterface
public function uninstall(InstallerAdapter $parent): bool public function uninstall(InstallerAdapter $parent): bool
{ {
$this->logMessage('MokoOnyx template uninstalled.'); $this->logMessage('MokoOnyx template uninstalled.');
$this->saveDownloadKey();
return true; return true;
} }
public function postflight(string $type, InstallerAdapter $parent): bool public function postflight(string $type, InstallerAdapter $parent): bool
{ {
$this->restoreDownloadKey();
$this->warnMissingLicenseKey();
if ($type === 'install' || $type === 'update') { if ($type === 'install' || $type === 'update') {
$this->migrateFromCassiopeia(); $this->migrateFromCassiopeia();
$this->replaceCassiopeiaReferences(); $this->replaceCassiopeiaReferences();
@@ -533,6 +541,37 @@ class Tpl_MokoonyxInstallerScript implements InstallerScriptInterface
} }
} }
// Remove faulty "template-mokoonyx" duplicate (wrong element name from bad install)
$faultyId = (int) $db->setQuery(
$db->getQuery(true)
->select('extension_id')
->from('#__extensions')
->where($db->quoteName('element') . ' = ' . $db->quote('template-mokoonyx'))
->where($db->quoteName('type') . ' = ' . $db->quote('template'))
)->loadResult();
if ($faultyId) {
$db->setQuery(
$db->getQuery(true)
->delete('#__update_sites_extensions')
->where('extension_id = ' . $faultyId)
)->execute();
$db->setQuery(
$db->getQuery(true)
->delete('#__extensions')
->where('extension_id = ' . $faultyId)
)->execute();
$db->setQuery(
$db->getQuery(true)
->delete('#__template_styles')
->where($db->quoteName('template') . ' = ' . $db->quote('template-mokoonyx'))
)->execute();
$this->logMessage('Removed faulty template-mokoonyx duplicate extension.');
}
// Remove stale MokoCassiopeia if not set as default // Remove stale MokoCassiopeia if not set as default
$oldExt = (int) $db->setQuery( $oldExt = (int) $db->setQuery(
$db->getQuery(true) $db->getQuery(true)
@@ -653,4 +692,92 @@ class Tpl_MokoonyxInstallerScript implements InstallerScriptInterface
Log::add($message, $priorities[$priority] ?? Log::INFO, 'mokoonyx'); Log::add($message, $priorities[$priority] ?? Log::INFO, 'mokoonyx');
} }
private ?string $savedDownloadKey = null;
private function saveDownloadKey(): void
{
try
{
$db = \Joomla\CMS\Factory::getDbo();
$db->setQuery(
$db->getQuery(true)
->select($db->quoteName('us.extra_query'))
->from($db->quoteName('#__update_sites', 'us'))
->join('INNER', $db->quoteName('#__update_sites_extensions', 'use') . ' ON use.update_site_id = us.update_site_id')
->join('INNER', $db->quoteName('#__extensions', 'e') . ' ON e.extension_id = use.extension_id')
->where($db->quoteName('e.element') . ' = ' . $db->quote('mokoonyx'))
->setLimit(1)
);
$key = $db->loadResult();
if (!empty($key)) { $this->savedDownloadKey = $key; }
}
catch (\Throwable $e) {}
}
private function restoreDownloadKey(): void
{
if ($this->savedDownloadKey === null) { return; }
try
{
$db = \Joomla\CMS\Factory::getDbo();
$db->setQuery(
$db->getQuery(true)
->select($db->quoteName('us.update_site_id'))
->from($db->quoteName('#__update_sites', 'us'))
->join('INNER', $db->quoteName('#__update_sites_extensions', 'use') . ' ON use.update_site_id = us.update_site_id')
->join('INNER', $db->quoteName('#__extensions', 'e') . ' ON e.extension_id = use.extension_id')
->where($db->quoteName('e.element') . ' = ' . $db->quote('mokoonyx'))
->setLimit(1)
);
$siteId = (int) $db->loadResult();
if ($siteId > 0)
{
$db->setQuery(
$db->getQuery(true)
->update($db->quoteName('#__update_sites'))
->set($db->quoteName('extra_query') . ' = ' . $db->quote($this->savedDownloadKey))
->where($db->quoteName('update_site_id') . ' = ' . $siteId)
)->execute();
}
}
catch (\Throwable $e) {}
}
private function warnMissingLicenseKey(): void
{
try
{
$db = \Joomla\CMS\Factory::getDbo();
$db->setQuery(
$db->getQuery(true)
->select([$db->quoteName('update_site_id'), $db->quoteName('extra_query')])
->from($db->quoteName('#__update_sites'))
->where('(' . $db->quoteName('name') . ' LIKE ' . $db->quote('%MokoOnyx%') . ' OR ' . $db->quoteName('location') . ' LIKE ' . $db->quote('%MokoOnyx%') . ')')
->setLimit(1)
);
$site = $db->loadObject();
if ($site)
{
$eq = (string) ($site->extra_query ?? '');
if (!empty($eq) && strpos($eq, 'dlid=') !== false) { parse_str($eq, $p); if (!empty($p['dlid'])) { return; } }
$editUrl = 'index.php?option=com_installer&task=updatesite.edit&update_site_id=' . (int) $site->update_site_id;
}
else
{
$editUrl = 'index.php?option=com_installer&view=updatesites';
}
\Joomla\CMS\Factory::getApplication()->enqueueMessage(
'<strong>Moko Consulting License Key Required</strong> — '
. 'No download key is configured. Updates will not be available until a valid license key is entered. '
. '<a href="' . $editUrl . '" class="btn btn-sm btn-warning ms-2">Enter License Key</a>',
'warning'
);
}
catch (\Throwable $e) {}
}
} }
+1 -1
View File
@@ -35,7 +35,7 @@
</updateservers> </updateservers>
<dlid prefix="dlid=" suffix=""/> <dlid prefix="dlid=" suffix=""/>
<name>mokoonyx</name> <name>mokoonyx</name>
<version>02.20.00</version> <version>02.19.06-dev</version>
<scriptfile>script.php</scriptfile> <scriptfile>script.php</scriptfile>
<creationDate>2026-05-16</creationDate> <creationDate>2026-05-16</creationDate>
<author>Jonathan Miller || Moko Consulting</author> <author>Jonathan Miller || Moko Consulting</author>
-48
View File
@@ -1,48 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
SPDX-License-Identifier: GPL-3.0-or-later
VERSION: 02.19.06-dev
-->
<updates>
<update>
<name>Template - MokoOnyx</name>
<description>Template - MokoOnyx development build.</description>
<element>mokoonyx</element>
<type>template</type>
<client>site</client>
<version>02.19.06-dev</version>
<creationDate>2026-06-04</creationDate>
<infourl title='Template - MokoOnyx'>https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/tag/development</infourl>
<downloads>
<downloadurl type='full' format='zip'>https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/download/development/tpl_mokoonyx-02.19.06-dev.zip</downloadurl>
</downloads>
<sha256>718dd24295a5c8e3a0c855b01f86bf619bae84a4f7ab6e037c5cd5bfaadb2e30</sha256>
<tags><tag>dev</tag></tags>
<changelogurl>https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/raw/branch/main/CHANGELOG.md</changelogurl>
<maintainer>Moko Consulting</maintainer>
<maintainerurl>https://mokoconsulting.tech</maintainerurl>
<targetplatform name="joomla" version="(5|6)\..*" />
<php_minimum>8.1.0</php_minimum>
</update>
<update>
<name>Template - MokoOnyx</name>
<description>Template - MokoOnyx stable build.</description>
<element>mokoonyx</element>
<type>template</type>
<client>site</client>
<version>02.20.00</version>
<creationDate>2026-06-04</creationDate>
<infourl title="Template - MokoOnyx">https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/tag/stable</infourl>
<downloads>
<downloadurl type="full" format="zip">https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/download/stable/tpl_mokoonyx-02.20.00.zip</downloadurl>
</downloads>
<sha256>00851a8a0ce9f64b873cbfbf4495422e78788d303ad5a4ac13f48122a8bc9e30</sha256>
<tags><tag>stable</tag></tags>
<changelogurl>https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/raw/branch/main/CHANGELOG.md</changelogurl>
<maintainer>Moko Consulting</maintainer>
<maintainerurl>https://mokoconsulting.tech</maintainerurl>
<targetplatform name="joomla" version="(5|6)\..*"/>
<php_minimum>8.1.0</php_minimum>
</update>
</updates>