83 Commits

Author SHA1 Message Date
gitea-actions[bot] 1d428d0944 chore(version): pre-release bump to 02.27.03-dev [skip ci] 2026-06-23 18:12:19 +00:00
gitea-actions[bot] 888be7ebc0 chore(version): auto-bump patch 02.27.02-dev [skip ci] 2026-06-23 18:11:56 +00:00
jmiller a97b985101 chore: remove security-audit.yml -- handled by MokoGitea
Universal: Auto Version Bump / Version Bump (push) Successful in 17s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 26s
2026-06-23 18:04:59 +00:00
gitea-actions[bot] cba1423546 chore(version): pre-release bump to 02.27.01-dev [skip ci] 2026-06-23 18:04:35 +00:00
gitea-actions[bot] a17361879f chore(version): auto-bump patch 02.26.03-dev [skip ci] 2026-06-23 18:04:14 +00:00
jmiller c81df6609f chore: remove deploy-manual.yml -- no longer needed
Universal: Auto Version Bump / Version Bump (push) Successful in 26s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 20s
2026-06-23 17:59:40 +00:00
gitea-actions[bot] b1792627d7 chore(version): pre-release bump to 02.26.02-dev [skip ci] 2026-06-21 02:41:39 +00:00
gitea-actions[bot] 254c06f1d6 chore(version): auto-bump patch 02.26.01-dev [skip ci]
Branch Cleanup / Delete merged branch (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 20s
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Failing after 1m45s
2026-06-21 02:41:17 +00:00
Jonathan Miller a6f9352686 merge: resolve CHANGELOG conflict from main sync
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
Universal: PR Check / Branch Policy (pull_request) Successful in 3s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 10s
Universal: PR Check / Validate PR (pull_request) Failing after 12s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Secret Scan (pull_request) Successful in 13s
Generic: Repo Health / Access control (pull_request) Successful in 3s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 19s
Universal: Auto Version Bump / Version Bump (push) Successful in 21s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 24s
Joomla: Metadata Validation / Validate Joomla Metadata (pull_request) Failing after 57s
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
2026-06-20 21:40:34 -05:00
jmiller d21dc84564 Merge pull request 'fix: set blog item image object-fit to none' (#143) from fix/blog-image-object-fit into dev
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 / Branch Policy (pull_request) Successful in 1s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 4s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: Build & Release / Promote to RC (pull_request) Failing after 5s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 7s
Generic: Project CI / Lint & Validate (pull_request) Successful in 13s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 35s
Universal: PR Check / Validate PR (pull_request) Successful in 35s
Generic: Project CI / Tests (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
2026-06-21 02:35:03 +00:00
Jonathan Miller ca4730c12f fix: set blog item image object-fit to none
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Generic: Project CI / Lint & Validate (pull_request) Successful in 12s
Universal: PR Check / Validate PR (pull_request) Successful in 13s
Branch Cleanup / Delete merged branch (pull_request) Successful in 2s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request) Successful in 11s
Generic: Project CI / Tests (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
2026-06-20 21:22:02 -05:00
jmiller 83b18da22b Merge pull request 'docs: add social icons to README features and update version' (#142) from docs/readme-social-icons into dev 2026-06-21 01:38:41 +00:00
Jonathan Miller 6c2857820e docs: add social icons to README features and update version
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Project CI / Lint & Validate (pull_request) Successful in 26s
Universal: PR Check / Validate PR (pull_request) Successful in 32s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 1s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request) Successful in 12s
Generic: Project CI / Tests (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
2026-06-20 20:36:54 -05:00
jmiller 363971ffa8 chore: sync deploy-manual.yml from Template-Generic [skip ci] 2026-06-21 01:27:30 +00:00
jmiller 5de3d6c25c Merge pull request 'feat: collapsible floating social bar, tooltips, and URL validation' (#141) from feature/social-floating-enhancements into dev 2026-06-21 01:25:24 +00:00
Jonathan Miller 7063b6d633 feat: add collapsible floating social bar, tooltips, and URL validation
Universal: Auto Version Bump / Version Bump (push) Successful in 3s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Project CI / Lint & Validate (pull_request) Successful in 23s
Universal: PR Check / Validate PR (pull_request) Successful in 29s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 3s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request) Successful in 9s
Generic: Project CI / Tests (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
- Floating social bar now has a toggle button to collapse/expand,
  with state persisted in localStorage
- All social icon links show Bootstrap tooltips on hover with the
  platform name, placement-aware based on position
- Enhanced URL validation: server-side Joomla validate="url" on all
  social URL fields, stricter PHP regex with Joomla log warnings
  for skipped invalid URLs
- Updated CSS Variables tab docs for floating bar variables
2026-06-20 20:22:47 -05:00
jmiller 2b3bcbac9a chore: delete manifest.xml (no longer used) 2026-06-21 00:19:37 +00:00
jmiller c0aab513c0 chore: sync pr-check.yml from Template-Joomla [skip ci] 2026-06-20 23:45:55 +00:00
jmiller 24e0a1af85 chore: sync gitleaks.yml from Template-Joomla [skip ci] 2026-06-20 23:45:54 +00:00
jmiller a05a93af76 chore: sync ci-generic.yml from Template-Joomla [skip ci] 2026-06-20 23:45:53 +00:00
jmiller 4870336a5a chore: sync workflow-sync-trigger.yml from Template-Joomla [skip ci] 2026-06-20 23:07:40 +00:00
jmiller 5edcb6bd04 chore: sync rc-revert.yml from Template-Joomla [skip ci] 2026-06-20 23:07:40 +00:00
jmiller d1d2cb1f77 chore: sync issue-branch.yml from Template-Joomla [skip ci] 2026-06-20 23:07:39 +00:00
jmiller 388c9138c9 chore: sync ci-joomla.yml from Template-Joomla [skip ci] 2026-06-20 23:07:38 +00:00
jmiller a49bcd7e65 chore: sync auto-release.yml from Template-Joomla [skip ci] 2026-06-20 23:07:37 +00:00
jmiller 1592ab5efa chore: sync repo-health.yml from Template-Joomla [skip ci] 2026-06-20 22:29:54 +00:00
jmiller d5513b9517 chore: sync rc-revert.yml from Template-Joomla [skip ci] 2026-06-20 22:29:54 +00:00
jmiller 36f4eeb122 chore: sync pr-check.yml from Template-Joomla [skip ci] 2026-06-20 22:29:53 +00:00
jmiller 28d90a93a1 chore: sync cleanup.yml from Template-Joomla [skip ci] 2026-06-20 22:29:53 +00:00
jmiller 4dedece818 ci: sync security-audit.yml from Template-Joomla [skip ci] 2026-06-20 22:26:30 +00:00
jmiller 5e0d6720c6 ci: sync repo-health.yml from Template-Joomla [skip ci] 2026-06-20 22:26:02 +00:00
jmiller 2fd86c1f5b ci: sync rc-revert.yml from Template-Joomla [skip ci] 2026-06-20 22:25:53 +00:00
jmiller 07ec634dc0 ci: sync pr-check.yml from Template-Joomla [skip ci] 2026-06-20 22:24:46 +00:00
jmiller d6d67f8913 ci: sync issue-branch.yml from Template-Joomla [skip ci] 2026-06-20 22:22:20 +00:00
jmiller f27ca6330e ci: sync cleanup.yml from Template-Joomla [skip ci] 2026-06-20 22:15:34 +00:00
jmiller 9b195d2a14 chore: sync issue-branch.yml from Template-Joomla [skip ci] 2026-06-20 21:35:16 +00:00
jmiller 748bf45646 chore: sync ci-generic.yml from Template-Joomla [skip ci] 2026-06-20 21:35:15 +00:00
jmiller 3b041f7008 ci: sync ci-generic.yml from Template-Joomla [skip ci] 2026-06-20 21:34:01 +00:00
jmiller 3ec4c57f42 ci: sync cascade-dev.yml from Template-Joomla [skip ci] 2026-06-20 21:31:33 +00:00
jmiller 2170d8d83b ci: sync branch-cleanup.yml from Template-Joomla [skip ci] 2026-06-20 21:28:08 +00:00
jmiller 7692478e22 ci: sync auto-release.yml from Template-Joomla [skip ci] 2026-06-20 21:26:57 +00:00
gitea-actions[bot] 3f1c5a317f chore: promote changelog [Unreleased] → [02.26.00] 2026-06-20 20:56:35 +00:00
gitea-actions[bot] 7ffee71dee chore(release): build 02.26.00 [skip ci] 2026-06-20 20:56:33 +00:00
jmiller e59c5d303c Merge pull request 'merge: dev to main' (#140) from dev into main 2026-06-20 20:52:51 +00:00
jmiller 1ac8cfe325 Merge pull request 'chore: remove deploy-manual.yml workflow' (#139) from fix/remove-deploy-manual into dev
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
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 5s
Universal: PR Check / Branch Policy (pull_request) Successful in 4s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 8s
Generic: Repo Health / Access control (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Failing after 8s
Generic: Project CI / Lint & Validate (pull_request) Successful in 54s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 1m7s
Universal: PR Check / Validate PR (pull_request) Successful in 54s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 13s
Generic: Project CI / Tests (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
2026-06-20 20:52:24 +00:00
Jonathan Miller 396c95168b chore: remove deploy-manual.yml workflow
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 2s
Generic: Project CI / Lint & Validate (pull_request) Successful in 46s
Universal: PR Check / Validate PR (pull_request) Successful in 1m1s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request) Successful in 14s
Generic: Project CI / Tests (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
MokoOnyx deploys via the Joomla update server, not SFTP workflows.
2026-06-20 15:51:57 -05:00
jmiller e9c9b1d8d4 chore: sync issue-branch.yml from Template-Joomla [skip ci] 2026-06-20 20:50:59 +00:00
gitea-actions[bot] 12e0eb87e6 chore: promote changelog [Unreleased] → [02.25.00] 2026-06-20 20:50:15 +00:00
gitea-actions[bot] f4dbdd2d57 chore(release): build 02.25.00 [skip ci] 2026-06-20 20:50:12 +00:00
jmiller 2a2f5373fc Merge pull request 'merge: dev to main' (#138) from dev into main 2026-06-20 20:49:59 +00:00
jmiller c1dee0d055 Merge pull request 'fix: show social style/URL fields only when display position enabled' (#137) from fix/social-showon-urls into dev
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 / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 3s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 5s
Generic: Project CI / Lint & Validate (pull_request) Successful in 11s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 8s
Universal: PR Check / Validate PR (pull_request) Successful in 29s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 17s
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Failing after 6m48s
Generic: Project CI / Tests (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
2026-06-20 20:49:12 +00:00
Jonathan Miller f2a9ffd50f fix: show social style/URL fields only when a display position is enabled
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Project CI / Lint & Validate (pull_request) Successful in 20s
Branch Cleanup / Delete merged branch (pull_request) Successful in 1s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Universal: PR Check / Validate PR (pull_request) Successful in 26s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || 'development' }}) (pull_request) Successful in 10s
Generic: Project CI / Tests (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
Added showon conditions to style options and platform URL section so
they only appear when topbar, footer, or floating social is enabled.
Updated note to indicate at least one URL is required.
2026-06-20 15:48:30 -05:00
jmiller 3d85e755bb ci: sync ci-generic.yml from Template-Joomla [skip ci] 2026-06-20 20:35:05 +00:00
gitea-actions[bot] 07f564f6c7 chore: promote changelog [Unreleased] → [02.24.00] 2026-06-20 20:34:05 +00:00
gitea-actions[bot] d115314702 chore(release): build 02.24.00 [skip ci] 2026-06-20 20:34:02 +00:00
jmiller 7497a2e363 Merge pull request 'merge: dev to main' (#136) from dev into main 2026-06-20 20:33:46 +00:00
jmiller 102b475103 ci: sync cascade-dev.yml from Template-Joomla [skip ci] 2026-06-20 20:32:51 +00:00
jmiller 053ca6b5d2 ci: sync branch-cleanup.yml from Template-Joomla [skip ci] 2026-06-20 20:31:53 +00:00
jmiller fafba5f38a ci: sync auto-release.yml from Template-Joomla [skip ci] 2026-06-20 20:30:58 +00:00
gitea-actions[bot] ddfaf8d535 chore: promote changelog [Unreleased] → [02.23.02] 2026-06-20 20:03:57 +00:00
gitea-actions[bot] b94401ba92 chore(release): build 02.23.02 [skip ci] 2026-06-20 20:03:54 +00:00
jmiller 9686c23afa Merge pull request 'fix: remove duplicate changelog header' (#134) from fix/changelog-duplicate-header into main 2026-06-20 20:03:39 +00:00
gitea-actions[bot] 27344e3bad chore(version): pre-release bump to 02.23.02-dev [skip ci]
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 20s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 2s
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Failing after 4s
2026-06-20 20:02:41 +00:00
jmiller dfe71375e9 fix: remove duplicate [02.23.00] changelog header
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 13s
Universal: Build & Release / Promote to RC (pull_request) Failing after 11s
Universal: Build & Release / Build & Release Pipeline (pull_request) Has been skipped
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 7s
Universal: PR Check / Branch Policy (pull_request) Failing after 2s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 9s
Universal: PR Check / Validate PR (pull_request) Failing after 17s
Generic: Repo Health / Access control (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Project CI / Lint & Validate (pull_request) Successful in 43s
Joomla: Metadata Validation / Validate Joomla Metadata (pull_request) Failing after 1m53s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 2m12s
Generic: Project CI / Tests (pull_request) 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
2026-06-20 20:01:33 +00:00
gitea-actions[bot] a7b3346920 chore(version): pre-release bump to 02.23.01-dev [skip ci] 2026-06-20 19:59:39 +00:00
jmiller 3987bdd469 ci: sync auto-bump.yml from Template-Joomla [skip ci] 2026-06-20 19:59:08 +00:00
gitea-actions[bot] ecefcffda5 chore: promote changelog [Unreleased] → [02.23.00]
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 13s
2026-06-20 19:06:17 +00:00
gitea-actions[bot] cda4951285 chore(release): build 02.23.00 [skip ci] 2026-06-20 19:06:14 +00:00
jmiller c84ae7abb1 ci: sync ci-generic.yml from Template-Joomla [skip ci] 2026-06-20 19:05:59 +00:00
jmiller 7e783470fe Merge pull request 'merge: dev to main' (#133) from dev into main 2026-06-20 19:05:55 +00:00
jmiller 8dca6e6f6a ci: sync cascade-dev.yml from Template-Joomla [skip ci] 2026-06-20 19:03:17 +00:00
jmiller 9ff1af1eb0 ci: sync branch-cleanup.yml from Template-Joomla [skip ci] 2026-06-20 19:02:44 +00:00
jmiller de4b4c7065 ci: sync auto-release.yml from Template-Joomla [skip ci] 2026-06-20 19:01:04 +00:00
jmiller dd01e90bab ci: sync auto-bump.yml from Template-Joomla [skip ci] 2026-06-20 18:53:50 +00:00
jmiller 5dff2895f5 ci: sync pre-release workflow from Template-Joomla 2026-06-20 18:49:29 +00:00
jmiller 29642ea45b ci: add Joomla metadata validation workflow for PRs 2026-06-20 18:39:06 +00:00
jmiller 1d58129b84 fix: rename moko-platform to mokocli + changelog promotion in workflows 2026-06-20 17:15:58 +00:00
jmiller ce87a2c6e5 fix: rename moko-platform to mokocli + changelog promotion in workflows 2026-06-20 17:15:57 +00:00
jmiller 2b899e2872 fix: rename moko-platform to mokocli + changelog promotion in workflows 2026-06-20 17:15:56 +00:00
jmiller 00ce506bac fix: rename moko-platform to mokocli + changelog promotion in workflows 2026-06-20 17:15:55 +00:00
jmiller d353387cba fix: rename moko-platform to mokocli + changelog promotion in workflows 2026-06-20 17:15:54 +00:00
jmiller 3ba52f2152 fix: rename moko-platform to mokocli + changelog promotion in workflows 2026-06-20 17:15:53 +00:00
jmiller 3b4e22da17 Merge pull request 'refactor: rename src/ to source/' (#131) from fix/rename-src-to-source into main 2026-06-20 15:59:46 +00:00
28 changed files with 715 additions and 462 deletions
-26
View File
@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Moko Platform Repository Manifest
See: https://git.mokoconsulting.tech/MokoConsulting/moko-platform/wiki/Home
-->
<moko-platform xmlns="https://standards.mokoconsulting.tech/moko-platform/1.0" schema-version="1.0">
<identity>
<name>MokoOnyx</name>
<display-name>Template - MokoOnyx</display-name>
<org>MokoConsulting</org>
<description>MokoOnyx - Joomla site template (successor to MokoCassiopeia)</description>
<version>02.22.00</version>
<license spdx="GPL-3.0-or-later">GNU General Public License v3</license>
</identity>
<governance>
<platform>joomla</platform>
<standards-version>04.07.00</standards-version>
<standards-source>https://git.mokoconsulting.tech/MokoConsulting/moko-platform</standards-source>
<last-synced>2026-05-10T19:51:09+00:00</last-synced>
</governance>
<build>
<language>PHP</language>
<package-type>joomla</package-type>
<entry-point>src/</entry-point>
</build>
</moko-platform>
+66 -65
View File
@@ -1,65 +1,66 @@
# 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:
- rc
- 'feature/**'
- 'patch/**'
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.MOKOGITEA_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.MOKOGITEA_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: |
php ${MOKO_CLI}/version_auto_bump.php \
--path . --branch "${GITHUB_REF_NAME}" \
--token "${{ secrets.MOKOGITEA_TOKEN }}" \
--repo-url "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: mokocli.Release
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
# 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
- rc
- 'feature/**'
- 'patch/**'
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.MOKOGITEA_TOKEN }}
fetch-depth: 1
- name: Setup mokocli 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/mokocli/cli" ]; then
echo "MOKO_CLI=/opt/mokocli/cli" >> "$GITHUB_ENV"
else
git clone --depth 1 --branch main --quiet \
"https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/mokocli.git" \
/tmp/mokocli
cd /tmp/mokocli && composer install --no-dev --no-interaction --quiet
echo "MOKO_CLI=/tmp/mokocli/cli" >> "$GITHUB_ENV"
fi
- name: Bump version
run: |
php ${MOKO_CLI}/version_auto_bump.php \
--path . --branch "${GITHUB_REF_NAME}" \
--token "${{ secrets.MOKOGITEA_TOKEN }}" \
--repo-url "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
+291 -17
View File
@@ -4,8 +4,8 @@
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: moko-platform.Release
# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/moko-platform
# INGROUP: mokocli.Release
# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli
# PATH: /templates/workflows/universal/auto-release.yml.template
# VERSION: 05.00.00
# BRIEF: Universal build & release detects platform from manifest.xml
@@ -66,25 +66,25 @@ jobs:
token: ${{ secrets.MOKOGITEA_TOKEN }}
fetch-depth: 1
- name: Setup moko-platform tools
- name: Setup mokocli tools
env:
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
run: |
if [ -f /opt/moko-platform/cli/version_bump.php ] && [ -f /opt/moko-platform/vendor/autoload.php ]; then
echo Using pre-installed /opt/moko-platform
echo MOKO_CLI=/opt/moko-platform/cli >> $GITHUB_ENV
if [ -f /opt/mokocli/cli/version_bump.php ] && [ -f /opt/mokocli/vendor/autoload.php ]; then
echo Using pre-installed /opt/mokocli
echo MOKO_CLI=/opt/mokocli/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
rm -rf /tmp/mokocli
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
cd /tmp/mokocli
composer install --no-dev --no-interaction --quiet
echo MOKO_CLI=/tmp/moko-platform-api/cli >> $GITHUB_ENV
echo MOKO_CLI=/tmp/mokocli/cli >> $GITHUB_ENV
fi
- name: Rename branch to rc
@@ -112,16 +112,19 @@ jobs:
- name: Update RC release notes from CHANGELOG.md
run: |
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
# Extract [Unreleased] section from changelog
NOTES=""
if [ -f "CHANGELOG.md" ]; then
NOTES=$(awk '/^## \[Unreleased\]/{found=1; next} /^## \[/{if(found) exit} found{print}' CHANGELOG.md)
[ -z "$NOTES" ] && NOTES="Release candidate"
else
NOTES="Release candidate"
fi
[ -z "$NOTES" ] && NOTES="Release candidate"
RELEASE_ID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \
"${API_BASE}/releases/tags/release-candidate" | python3 -c "import json,sys; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true)
# Find the RC release and update its body
RELEASE_ID=$(curl -sf -H "Authorization: token ${TOKEN}" \
"${API_BASE}/releases/tags/release-candidate" \
| python3 -c "import json,sys; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true)
if [ -n "$RELEASE_ID" ]; then
python3 -c "
@@ -132,7 +135,7 @@ jobs:
'${API_BASE}/releases/${RELEASE_ID}',
data=payload, method='PATCH',
headers={
'Authorization': 'token ${{ secrets.MOKOGITEA_TOKEN }}',
'Authorization': 'token ${TOKEN}',
'Content-Type': 'application/json'
})
urllib.request.urlopen(req)
@@ -145,3 +148,274 @@ jobs:
run: |
echo "## Promoted to Release Candidate" >> $GITHUB_STEP_SUMMARY
echo "Branch renamed to rc, minor bump, RC release built" >> $GITHUB_STEP_SUMMARY
# ── Merged PR → Build & Release (or promote RC to stable) ────────────────────
release:
name: Build & Release Pipeline
runs-on: release
if: >-
github.event.pull_request.merged == true ||
(github.event_name == 'workflow_dispatch' && inputs.action != 'promote-rc')
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
token: ${{ secrets.MOKOGITEA_TOKEN }}
fetch-depth: 0
- name: Configure git for bot pushes
run: |
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
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"
- name: Check for merge conflict markers
run: |
CONFLICTS=$(grep -rn '<<<<<<< \|>>>>>>> \|^=======$' --include='*.php' --include='*.xml' --include='*.css' --include='*.js' --include='*.json' --include='*.md' --include='*.yml' --include='*.yaml' --include='*.ini' --include='*.txt' . 2>/dev/null | grep -v '.git/' || true)
if [ -n "$CONFLICTS" ]; then
echo "::error::Merge conflict markers found — aborting release"
echo "## Release Blocked: Conflict Markers" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "$CONFLICTS" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
exit 1
fi
echo "No conflict markers found"
- name: Setup mokocli tools
env:
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_MIRROR_TOKEN }}"}}'
run: |
if [ -f /opt/mokocli/cli/version_bump.php ] && [ -f /opt/mokocli/vendor/autoload.php ]; then
echo Using pre-installed /opt/mokocli
echo MOKO_CLI=/opt/mokocli/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/mokocli
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
cd /tmp/mokocli
composer install --no-dev --no-interaction --quiet
echo MOKO_CLI=/tmp/mokocli/cli >> $GITHUB_ENV
fi
- name: "Detect platform"
id: platform
run: |
php ${MOKO_CLI}/platform_detect.php --path . --github-output 2>/dev/null || true
php ${MOKO_CLI}/manifest_read.php --path . --github-output 2>/dev/null || true
- name: "Determine version bump level"
id: bump
run: |
# Fix/patch branches: version was already bumped by pre-release, just strip suffix
# Feature/dev branches: bump minor for the new stable release
HEAD_REF="${{ github.event.pull_request.head.ref || 'dev' }}"
case "$HEAD_REF" in
fix/*|patch/*|hotfix/*|bugfix/*) BUMP="none" ;;
*) BUMP="minor" ;;
esac
echo "level=${BUMP}" >> "$GITHUB_OUTPUT"
echo "Bump level: ${BUMP} (from branch: ${HEAD_REF})"
- name: "Publish stable release"
run: |
BUMP_FLAG=""
if [ "${{ steps.bump.outputs.level }}" != "none" ]; then
BUMP_FLAG="--bump ${{ steps.bump.outputs.level }}"
fi
php ${MOKO_CLI}/release_publish.php \
--path . --stability stable ${BUMP_FLAG} --branch main \
--token "${{ secrets.MOKOGITEA_TOKEN }}"
- name: "Read published version"
id: version
run: |
VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null || echo "")
VERSION=$(echo "$VERSION" | sed 's/-\(dev\|alpha\|beta\|rc\)$//')
[ -z "$VERSION" ] && VERSION="00.00.00" && echo "skip=true" >> "$GITHUB_OUTPUT"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "tag=stable" >> "$GITHUB_OUTPUT"
echo "release_tag=stable" >> "$GITHUB_OUTPUT"
echo "branch=main" >> "$GITHUB_OUTPUT"
echo "Published version: ${VERSION}"
- name: Update release notes and promote changelog
run: |
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
# Get the stable release info (version and ID)
RELEASE_JSON=$(curl -sf -H "Authorization: token ${TOKEN}" \
"${API_BASE}/releases/tags/stable" 2>/dev/null || echo '{}')
RELEASE_ID=$(python3 -c "import json,sys; print(json.load(sys.stdin).get('id',''))" <<< "$RELEASE_JSON" 2>/dev/null || true)
# Extract version from release name (e.g. "06.17.00" or "v06.17.00")
VERSION=$(python3 -c "
import json, sys, re
r = json.load(sys.stdin)
name = r.get('name', '')
m = re.search(r'(\d+\.\d+\.\d+)', name)
print(m.group(1) if m else '')
" <<< "$RELEASE_JSON" 2>/dev/null || true)
# Extract [Unreleased] section from changelog
NOTES=""
if [ -f "CHANGELOG.md" ]; then
NOTES=$(awk '/^## \[Unreleased\]/{found=1; next} /^## \[/{if(found) exit} found{print}' CHANGELOG.md)
fi
[ -z "$NOTES" ] && NOTES="Stable release"
# Update release body via API
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 ${TOKEN}',
'Content-Type': 'application/json'
})
urllib.request.urlopen(req)
" <<< "$NOTES"
echo "Release notes updated from CHANGELOG.md"
fi
# Promote [Unreleased] → [version] in CHANGELOG.md and reset
if [ -n "$VERSION" ] && [ -f "CHANGELOG.md" ]; then
DATE=$(date +%Y-%m-%d)
python3 -c "
import sys
version, date = sys.argv[1], sys.argv[2]
content = open('CHANGELOG.md').read()
old = '## [Unreleased]'
new = f'## [Unreleased]\n\n## [{version}] --- {date}'
content = content.replace(old, new, 1)
open('CHANGELOG.md', 'w').write(content)
" "$VERSION" "$DATE"
git add CHANGELOG.md
git commit -m "chore: promote changelog [Unreleased] → [${VERSION}]" || true
git push origin main || true
echo "Changelog promoted: [Unreleased] → [${VERSION}]"
fi
# -- STEP 9: Mirror to GitHub (stable only) --------------------------------
- name: "Step 9: Mirror release to GitHub"
if: >-
steps.version.outputs.skip != 'true' &&
secrets.GH_MIRROR_TOKEN != ''
continue-on-error: true
run: |
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}"
RELEASE_TAG="${{ steps.version.outputs.release_tag }}"
GH_REPO="${{ vars.GH_MIRROR_REPO || github.repository }}"
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
php ${MOKO_CLI}/release_mirror.php \
--version "$VERSION" --tag "$RELEASE_TAG" \
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \
--gh-token "${{ secrets.GH_MIRROR_TOKEN }}" --gh-repo "$GH_REPO" \
--branch main 2>&1 || true
echo "GitHub mirror updated" >> $GITHUB_STEP_SUMMARY
# -- STEP 10: Sync main branch to GitHub mirror ----------------------------
- name: "Step 10: Push main to GitHub mirror"
if: >-
steps.version.outputs.skip != 'true' &&
secrets.GH_MIRROR_TOKEN != ''
continue-on-error: true
run: |
GH_REPO="${{ vars.GH_MIRROR_REPO || github.repository }}"
GH_ORG=$(echo "$GH_REPO" | cut -d/ -f1)
GH_NAME=$(echo "$GH_REPO" | cut -d/ -f2)
git remote add github "https://x-access-token:${{ secrets.GH_MIRROR_TOKEN }}@github.com/${GH_ORG}/${GH_NAME}.git" 2>/dev/null || \
git remote set-url github "https://x-access-token:${{ secrets.GH_MIRROR_TOKEN }}@github.com/${GH_ORG}/${GH_NAME}.git"
git fetch origin main --depth=1
git push github origin/main:refs/heads/main --force 2>/dev/null \
&& echo "main branch pushed to GitHub mirror" \
|| echo "WARNING: GitHub mirror push failed"
- name: "Step 11: Delete rc branch and recreate dev from main"
if: steps.version.outputs.skip != 'true'
continue-on-error: true
run: |
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
# Delete rc branch (ephemeral — created by promote-rc)
curl -sf -X DELETE -H "Authorization: token ${TOKEN}" \
"${API_BASE}/branches/rc" 2>/dev/null \
&& echo "Deleted rc branch" || echo "rc branch not found"
# Delete dev branch
curl -sf -X DELETE -H "Authorization: token ${TOKEN}" \
"${API_BASE}/branches/dev" 2>/dev/null && echo "Deleted dev branch"
# Recreate dev from main (now includes version bump + changelog promotion)
curl -sf -X POST -H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \
"${API_BASE}/branches" \
-d '{"new_branch_name":"dev","old_branch_name":"main"}' 2>/dev/null && echo "Recreated dev from main"
echo "Pre-release branches cleaned, dev reset from main" >> $GITHUB_STEP_SUMMARY
- name: "Step 12: Create version branch from main"
if: steps.version.outputs.skip != 'true'
continue-on-error: true
run: |
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}"
BRANCH_NAME="version/${VERSION}"
MAIN_SHA=$(git rev-parse HEAD)
# Delete old version branch if it exists (same version re-release)
curl -sf -X DELETE -H "Authorization: token ${TOKEN}" "${API_BASE}/branches/${BRANCH_NAME}" 2>/dev/null && echo "Deleted old ${BRANCH_NAME}"
# Create version/XX.YY.ZZ from main
curl -sf -X POST -H "Authorization: token ${TOKEN}" -H "Content-Type: application/json" "${API_BASE}/branches" -d "{\"new_branch_name\":\"${BRANCH_NAME}\",\"old_branch_name\":\"main\"}" 2>/dev/null && echo "Created ${BRANCH_NAME} from main (${MAIN_SHA})" || echo "WARNING: ${BRANCH_NAME} creation failed"
echo "Version branch created: ${BRANCH_NAME} (${MAIN_SHA})" >> $GITHUB_STEP_SUMMARY
# -- Dolibarr post-release: Reset dev version -----------------------------
- name: "Post-release: Reset dev version"
if: steps.version.outputs.skip != 'true'
continue-on-error: true
run: |
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
php ${MOKO_CLI}/version_reset_dev.php \
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "${API_BASE}" \
--branch dev --path . 2>&1 || true
# -- Summary --------------------------------------------------------------
- name: Pipeline Summary
if: always()
run: |
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}"
PLATFORM="${{ steps.platform.outputs.platform }}"
if [ "${{ steps.version.outputs.skip }}" = "true" ]; then
echo "## Release Skipped" >> $GITHUB_STEP_SUMMARY
echo "No VERSION in README.md" >> $GITHUB_STEP_SUMMARY
elif [ "${{ steps.check.outputs.already_released }}" = "true" ]; then
echo "## Already Released — ${VERSION}" >> $GITHUB_STEP_SUMMARY
else
echo "" >> $GITHUB_STEP_SUMMARY
echo "## Build & Release Complete (${PLATFORM})" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Step | Result |" >> $GITHUB_STEP_SUMMARY
echo "|------|--------|" >> $GITHUB_STEP_SUMMARY
echo "| Platform | \`${PLATFORM}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Branch | \`${{ steps.version.outputs.branch }}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Tag | \`${{ steps.version.outputs.tag }}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Release | [View](${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/tag/${{ steps.version.outputs.tag }}) |" >> $GITHUB_STEP_SUMMARY
fi
+1 -1
View File
@@ -5,7 +5,7 @@
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: MokoStandards.Universal
# REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
# PATH: /.mokogitea/workflows/branch-cleanup.yml
# VERSION: 01.00.00
# BRIEF: Delete feature branches after PR merge
-6
View File
@@ -13,12 +13,6 @@
name: "Generic: Project CI"
on:
pull_request:
branches:
- main
- dev
- dev/**
- rc/**
workflow_dispatch:
permissions:
+7 -7
View File
@@ -45,17 +45,17 @@ jobs:
fi
php -v && composer --version
- name: Setup moko-platform tools
- name: Setup mokocli tools
env:
MOKO_CLONE_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
MOKO_CLONE_HOST: ${{ secrets.GA_TOKEN && 'git.mokoconsulting.tech/MokoConsulting' || 'github.com/mokoconsulting-tech' }}
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN || secrets.GA_TOKEN || github.token }}
MOKO_CLONE_HOST: ${{ secrets.MOKOGITEA_TOKEN && 'git.mokoconsulting.tech/MokoConsulting' || 'github.com/mokoconsulting-tech' }}
run: |
if [ -d "/tmp/moko-platform" ] || [ -d "/opt/moko-platform" ]; then
echo "moko-platform already available on runner — skipping clone"
if [ -d "/opt/mokocli" ] || [ -d "/tmp/mokocli" ]; then
echo "mokocli already available on runner — skipping clone"
else
git clone --depth 1 --branch main --quiet \
"https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git" \
/tmp/moko-platform 2>/dev/null || echo "moko-platform clone skipped — continuing without it"
"https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git" \
/tmp/mokocli 2>/dev/null || echo "mokocli clone skipped — continuing without it"
fi
- name: Install dependencies
-126
View File
@@ -1,126 +0,0 @@
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: MokoStandards.Deploy
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards-API
# PATH: /templates/workflows/joomla/deploy-manual.yml.template
# VERSION: 04.07.00
# BRIEF: Manual SFTP deploy to dev server for Joomla repos
name: "Universal: Deploy to Dev (Manual)"
on:
workflow_dispatch:
inputs:
clear_remote:
description: 'Delete all remote files before uploading'
required: false
default: 'false'
type: boolean
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
permissions:
contents: read
jobs:
deploy:
name: SFTP Deploy to Dev
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Setup PHP
run: |
php -v && composer --version
- name: Setup MokoStandards tools
env:
GA_TOKEN: ${{ secrets.GA_TOKEN || secrets.GA_TOKEN || github.token }}
MOKO_CLONE_TOKEN: ${{ secrets.GA_TOKEN || secrets.GA_TOKEN || github.token }}
MOKO_CLONE_HOST: ${{ secrets.GA_TOKEN && 'git.mokoconsulting.tech/MokoConsulting' || 'github.com/mokoconsulting-tech' }}
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GA_TOKEN || github.token }}"}}'
run: |
git clone --depth 1 --branch main --quiet \
"https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/MokoStandards-API.git" \
/tmp/mokostandards-api 2>/dev/null || true
if [ -d "/tmp/mokostandards-api" ] && [ -f "/tmp/mokostandards-api/composer.json" ]; then
cd /tmp/mokostandards-api && composer install --no-dev --no-interaction --quiet 2>/dev/null || true
fi
- name: Check FTP configuration
id: check
env:
HOST: ${{ vars.DEV_FTP_HOST }}
PATH_VAR: ${{ vars.DEV_FTP_PATH }}
PORT: ${{ vars.DEV_FTP_PORT }}
run: |
if [ -z "$HOST" ] || [ -z "$PATH_VAR" ]; then
echo "DEV_FTP_HOST or DEV_FTP_PATH not configured -- cannot deploy"
echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "skip=false" >> "$GITHUB_OUTPUT"
echo "host=$HOST" >> "$GITHUB_OUTPUT"
REMOTE="${PATH_VAR%/}"
echo "remote=$REMOTE" >> "$GITHUB_OUTPUT"
[ -z "$PORT" ] && PORT="22"
echo "port=$PORT" >> "$GITHUB_OUTPUT"
- name: Deploy via SFTP
if: steps.check.outputs.skip != 'true'
env:
SFTP_KEY: ${{ secrets.DEV_FTP_KEY }}
SFTP_PASS: ${{ secrets.DEV_FTP_PASSWORD }}
SFTP_USER: ${{ vars.DEV_FTP_USERNAME }}
run: |
SOURCE_DIR="src"
[ ! -d "$SOURCE_DIR" ] && SOURCE_DIR="htdocs"
[ ! -d "$SOURCE_DIR" ] && { echo "No src/ or htdocs/ -- nothing to deploy"; exit 0; }
printf '{"host":"%s","port":%s,"username":"%s","remotePath":"%s"' \
"${{ steps.check.outputs.host }}" "${{ steps.check.outputs.port }}" "$SFTP_USER" "${{ steps.check.outputs.remote }}" \
> /tmp/sftp-config.json
if [ -n "$SFTP_KEY" ]; then
echo "$SFTP_KEY" > /tmp/deploy_key
chmod 600 /tmp/deploy_key
printf ',"privateKeyPath":"/tmp/deploy_key"}' >> /tmp/sftp-config.json
else
printf ',"password":"%s"}' "$SFTP_PASS" >> /tmp/sftp-config.json
fi
DEPLOY_ARGS=(--path . --src-dir "$SOURCE_DIR" --config /tmp/sftp-config.json)
[ "${{ inputs.clear_remote }}" = "true" ] && DEPLOY_ARGS+=(--clear-remote)
PLATFORM=$(php /tmp/mokostandards-api/cli/platform_detect.php --path . 2>/dev/null || true)
if [ "$PLATFORM" = "waas-component" ] && [ -f "/tmp/mokostandards-api/deploy/deploy-joomla.php" ]; then
php /tmp/mokostandards-api/deploy/deploy-joomla.php "${DEPLOY_ARGS[@]}"
else
php /tmp/mokostandards-api/deploy/deploy-sftp.php "${DEPLOY_ARGS[@]}"
fi
rm -f /tmp/deploy_key /tmp/sftp-config.json
- name: Summary
if: always()
run: |
if [ "${{ steps.check.outputs.skip }}" = "true" ]; then
echo "### Deploy Skipped -- FTP not configured" >> $GITHUB_STEP_SUMMARY
else
echo "### Manual Dev Deploy Complete" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| Host | \`${{ steps.check.outputs.host }}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Remote | \`${{ steps.check.outputs.remote }}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Clear | ${{ inputs.clear_remote }} |" >> $GITHUB_STEP_SUMMARY
fi
-4
View File
@@ -25,10 +25,6 @@
name: "Universal: Secret Scanning"
on:
pull_request:
branches:
- main
- 'dev/**'
schedule:
- cron: '0 5 * * 1' # Weekly Monday 05:00 UTC
workflow_dispatch:
+2 -2
View File
@@ -4,8 +4,8 @@
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: moko-platform.Automation
# VERSION: 01.00.00
# INGROUP: mokocli.Automation
# VERSION: 02.27.03
# BRIEF: Auto-create feature branch when an issue is opened
name: "Universal: Issue Branch"
+26
View File
@@ -96,6 +96,32 @@ jobs:
echo "Branch policy: OK (${HEAD} → ${BASE})"
echo "## Branch Policy: Passed" >> $GITHUB_STEP_SUMMARY
# ── Secret Scanning ──────────────────────────────────────────────────
gitleaks:
name: Secret Scan
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Gitleaks
run: |
GITLEAKS_VERSION="8.21.2"
curl -sSL "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \
| tar -xz -C /usr/local/bin gitleaks
- name: Scan PR commits for secrets
run: |
if gitleaks detect --source . --verbose \
--log-opts=${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} 2>&1; then
echo "**No secrets detected.**" >> $GITHUB_STEP_SUMMARY
else
echo "::error::Potential secrets detected in PR commits"
exit 1
fi
# ── Code Validation ────────────────────────────────────────────────────
validate:
name: Validate PR
@@ -0,0 +1,71 @@
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: mokocli.Validation
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
# PATH: /templates/workflows/joomla/pr-metadata-check.yml.template
# VERSION: 01.00.00
# BRIEF: Validate MokoGitea metadata matches Joomla extension manifest on PRs
name: "Joomla: Metadata Validation"
on:
pull_request:
types: [opened, synchronize, reopened, converted_to_draft, ready_for_review]
permissions:
contents: read
env:
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }}
jobs:
validate-metadata:
name: "Validate Joomla Metadata"
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup mokocli tools
env:
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
run: |
if [ -f /opt/mokocli/cli/joomla_metadata_validate.php ] && [ -f /opt/mokocli/vendor/autoload.php ]; then
echo Using pre-installed /opt/mokocli
echo MOKO_CLI=/opt/mokocli/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/mokocli
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
cd /tmp/mokocli && composer install --no-dev --no-interaction --quiet
echo MOKO_CLI=/tmp/mokocli/cli >> $GITHUB_ENV
fi
- name: Validate metadata against Joomla manifest
env:
GITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
run: |
php ${MOKO_CLI}/joomla_metadata_validate.php \
--path . \
--token "${GITEA_TOKEN}" \
--org "${GITEA_ORG}" \
--repo "${GITEA_REPO}" \
--api-base "${GITEA_URL}/api/v1" \
--ci
if [ $? -ne 0 ]; then
echo "::error::Joomla metadata mismatch — update delivery will fail. Run 'php cli/joomla_metadata_validate.php' locally to see details."
exit 1
fi
+39 -40
View File
@@ -4,23 +4,26 @@
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: mokoplatform.Release
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
# INGROUP: mokocli.Release
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
# PATH: /templates/workflows/universal/pre-release.yml.template
# VERSION: 05.01.00
# BRIEF: Manual pre-release -- builds dev/alpha/beta/rc packages from any branch
# BRIEF: Auto pre-release on push to dev/alpha/beta/rc branches
name: "Universal: Pre-Release"
on:
pull_request:
types: [closed]
push:
branches:
- dev
pull_request_target:
types: [synchronize, opened, reopened]
branches:
- main
- 'fix/**'
- 'patch/**'
- 'hotfix/**'
- 'bugfix/**'
- 'chore/**'
- alpha
- beta
- rc
workflow_dispatch:
inputs:
stability:
@@ -43,12 +46,11 @@ env:
jobs:
build:
name: "Build Pre-Release (${{ inputs.stability || 'development' }})"
name: "Build Pre-Release (${{ inputs.stability || github.ref_name }})"
runs-on: release
if: >-
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_target' && github.event.pull_request.base.ref == 'main')
github.event_name == 'push'
steps:
- name: Checkout
@@ -56,40 +58,47 @@ jobs:
with:
fetch-depth: 0
token: ${{ secrets.MOKOGITEA_TOKEN }}
ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || '' }}
ref: ${{ github.ref_name }}
- name: Setup mokoplatform tools
- name: Setup mokocli tools
env:
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
run: |
# Use pre-installed /opt/mokoplatform if available (updated by cron every 6h)
if [ -f /opt/mokoplatform/cli/version_bump.php ] && [ -f /opt/mokoplatform/cli/manifest_element.php ] && [ -f /opt/mokoplatform/vendor/autoload.php ]; then
echo Using pre-installed /opt/mokoplatform
echo MOKO_CLI=/opt/mokoplatform/cli >> $GITHUB_ENV
# Use pre-installed /opt/mokocli if available (updated by cron every 6h)
if [ -f /opt/mokocli/cli/version_bump.php ] && [ -f /opt/mokocli/cli/manifest_element.php ] && [ -f /opt/mokocli/vendor/autoload.php ]; then
echo Using pre-installed /opt/mokocli
echo MOKO_CLI=/opt/mokocli/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/mokoplatform-api
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokoplatform.git
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokoplatform-api
cd /tmp/mokoplatform-api && composer install --no-dev --no-interaction --quiet
echo MOKO_CLI=/tmp/mokoplatform-api/cli >> $GITHUB_ENV
rm -rf /tmp/mokocli
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
cd /tmp/mokocli && composer install --no-dev --no-interaction --quiet
echo MOKO_CLI=/tmp/mokocli/cli >> $GITHUB_ENV
fi
- name: Detect platform
id: platform
run: |
# Auto-detect and update platform if not set in manifest
php ${MOKO_CLI}/platform_detect.php --path . --github-output 2>/dev/null || true
php ${MOKO_CLI}/manifest_read.php --path . --github-output
- name: Resolve metadata and bump version
id: meta
run: |
# 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
STABILITY="release-candidate"
# Auto-detect stability from branch name on push, or use input on dispatch
if [ "${{ github.event_name }}" = "push" ]; then
case "${{ github.ref_name }}" in
rc) STABILITY="release-candidate" ;;
alpha) STABILITY="alpha" ;;
beta) STABILITY="beta" ;;
*) STABILITY="development" ;;
esac
else
STABILITY="${{ inputs.stability || 'development' }}"
fi
@@ -101,20 +110,10 @@ jobs:
release-candidate) SUFFIX="-rc"; TAG="release-candidate" ;;
esac
# Bump version: minor only on branch elevation, patch for rebuilds
# Check branch name — if already on the target stability branch, it's a rebuild
BRANCH="${{ github.ref_name }}"
# Bump version via CLI: patch for dev/alpha/beta, minor for RC
case "$STABILITY" in
release-candidate)
if [ "$BRANCH" = "rc" ]; then
BUMP="patch"
else
BUMP="minor"
fi
;;
*)
BUMP="patch"
;;
release-candidate) BUMP="minor" ;;
*) BUMP="patch" ;;
esac
php ${MOKO_CLI}/version_bump.php --path . $([ "$BUMP" = "minor" ] && echo "--minor") 2>/dev/null || true
@@ -174,7 +173,7 @@ jobs:
php ${MOKO_CLI}/release_create.php \
--path . --version "$VERSION" --tag "$TAG" \
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \
--repo "${GITEA_REPO}" --branch dev --prerelease
--repo "${GITEA_REPO}" --branch "${{ github.ref_name }}" --prerelease
- name: Update release notes from CHANGELOG.md
run: |
+2 -2
View File
@@ -4,8 +4,8 @@
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: MokoPlatform.Universal
# REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
# INGROUP: mokocli.Universal
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
# PATH: /.mokogitea/workflows/rc-revert.yml
# VERSION: 09.23.00
# BRIEF: Rename rc/ branch back to dev/ when PR is closed without merge
+2 -2
View File
@@ -7,8 +7,8 @@
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: moko-platform.Validation
# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/moko-platform
# INGROUP: mokocli.Validation
# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli
# PATH: /templates/workflows/joomla/repo_health.yml.template
# VERSION: 09.23.00
# BRIEF: Enforces repository guardrails by validating scripts governance, tooling availability, and core repository health artifacts.
-82
View File
@@ -1,82 +0,0 @@
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: MokoStandards.Security
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
# PATH: /.gitea/workflows/security-audit.yml
# VERSION: 01.00.00
# BRIEF: Dependency vulnerability scanning for composer and npm packages
name: "Universal: Security Audit"
on:
schedule:
- cron: '0 6 * * 1' # Weekly on Monday at 06:00 UTC
pull_request:
branches:
- main
paths:
- 'composer.json'
- 'composer.lock'
- 'package.json'
- 'package-lock.json'
workflow_dispatch:
permissions:
contents: read
env:
NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }}
NTFY_TOPIC: ${{ vars.NTFY_TOPIC || 'gitea-security' }}
jobs:
audit:
name: Dependency Audit
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Composer audit
if: hashFiles('composer.lock') != ''
run: |
echo "=== Composer Security Audit ==="
if ! command -v composer &> /dev/null; then
sudo apt-get update -qq
sudo apt-get install -y -qq php-cli composer >/dev/null 2>&1
fi
composer audit --format=plain 2>&1 | tee /tmp/composer-audit.txt
RESULT=$?
if [ $RESULT -ne 0 ]; then
echo "::warning::Composer vulnerabilities found"
echo "composer_vulnerable=true" >> "$GITHUB_ENV"
else
echo "No known vulnerabilities in composer dependencies"
fi
- name: NPM audit
if: hashFiles('package-lock.json') != ''
run: |
echo "=== NPM Security Audit ==="
npm audit --production 2>&1 | tee /tmp/npm-audit.txt || true
if npm audit --production 2>&1 | grep -q "found 0 vulnerabilities"; then
echo "No known vulnerabilities in npm dependencies"
else
echo "::warning::NPM vulnerabilities found"
echo "npm_vulnerable=true" >> "$GITHUB_ENV"
fi
- name: Notify on vulnerabilities
if: env.composer_vulnerable == 'true' || env.npm_vulnerable == 'true'
run: |
REPO="${{ github.event.repository.name }}"
curl -sS \
-H "Title: ${REPO} has vulnerable dependencies" \
-H "Tags: lock,warning" \
-H "Priority: high" \
-d "Security audit found vulnerabilities. Review dependency updates." \
"${NTFY_URL}/${NTFY_TOPIC}" || true
@@ -4,8 +4,8 @@
#
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: MokoPlatform.Universal
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
# INGROUP: mokocli.Universal
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
# PATH: /.mokogitea/workflows/workflow-sync-trigger.yml
# VERSION: 01.01.00
# BRIEF: Trigger workflow sync to live repos when a PR is merged to main
@@ -45,16 +45,16 @@ jobs:
echo "platform=$PLATFORM" >> "$GITHUB_OUTPUT"
echo "Platform: ${PLATFORM:-all}"
- name: Clone mokoplatform
- name: Clone mokocli
env:
MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
run: |
GITEA_URL="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}"
git clone --depth 1 "${GITEA_URL}/MokoConsulting/mokoplatform.git" /tmp/mokoplatform
git clone --depth 1 "${GITEA_URL}/MokoConsulting/mokocli.git" /tmp/mokocli
- name: Install dependencies
run: |
cd /tmp/mokoplatform
cd /tmp/mokocli
composer install --no-dev --no-interaction --quiet 2>/dev/null || true
- name: Run workflow sync
@@ -70,4 +70,4 @@ jobs:
ARGS="${ARGS} --platform-filter ${PLATFORM}"
fi
php /tmp/mokoplatform/cli/workflow_sync.php ${ARGS}
php /tmp/mokocli/cli/workflow_sync.php ${ARGS}
+12 -20
View File
@@ -8,35 +8,27 @@
DEFGROUP: Joomla.Template.Site
INGROUP: MokoOnyx.Documentation
PATH: ./CHANGELOG.md
VERSION: 02.22.00
VERSION: 02.27.03
BRIEF: Changelog file documenting version history of MokoOnyx
-->
# Changelog — MokoOnyx (VERSION: 02.22.00)
# Changelog — MokoOnyx (VERSION: 02.27.03)
## [Unreleased]
### Added
- Collapsible floating social bar with toggle button and localStorage persistence
- Bootstrap tooltips on all social icon links showing platform name on hover
- URL validation on social platform fields (browser, Joomla server-side, and PHP layout logging)
### Fixed
- Moved footer social icons below footer-menu and footer module positions for correct display order
### Removed
- Removed unused `automation/ci-issue-reporter.sh`
## [02.26.00] --- 2026-06-20
## [02.22.00] --- 2026-06-18
## [02.25.00] --- 2026-06-20
### Fixed
- Strip Joomla-injected `p-2` padding class from Font Awesome icons in all menu overrides (default, mainmenu, horizontal)
## [02.25.00] --- 2026-06-20
### Changed
- Migrated update server URL from raw file endpoint to Gitea Pages
- Release workflow no longer manages updates.xml (decoupled to Gitea Pages)
- Added conflict-marker guard to PR check and release workflows
- Added Joomla language file validation (syntax, duplicates, en-GB/en-US consistency)
- Added JEXEC guard, joomla.asset.json, XML well-formedness, and script file CI checks
- Removed RS_FTP_PATH_SUFFIX from repo health requirements
## [02.24.00] --- 2026-06-20
## [02.20.00] --- 2026-06-04
## [02.18.00] --- 2026-06-02
## [02.15.00] --- 2026-05-30
## [02.24.00] --- 2026-06-20
+3 -1
View File
@@ -12,7 +12,7 @@ A modern, lightweight Joomla site template built on Cassiopeia with Font Awesome
| | |
|---|---|
| **Type** | Joomla Site Template |
| **Version** | 02.07.00 |
| **Version** | 02.22.00 |
| **Joomla** | 5.x / 6.x |
| **PHP** | 8.1+ |
| **License** | GPL-3.0-or-later |
@@ -39,6 +39,7 @@ On install, MokoOnyx automatically migrates settings, content references, and cu
| **Table of Contents** | Automatic TOC generation for long articles |
| **GTM / GA4** | Google Tag Manager and Analytics integration with smart visitor detection (login status, user group, page type) |
| **Template Overrides** | Overrides for all core Joomla modules, Community Builder, and DPCalendar |
| **Social Icons** | Configurable social media links in topbar, footer, or collapsible floating sidebar with tooltips and URL validation |
| **Cassiopeia Base** | Minimal core overrides for maximum Joomla upgrade compatibility |
---
@@ -79,6 +80,7 @@ Key parameters include:
- **Google Tag Manager**: GTM container ID
- **GA4**: Measurement ID and tracking options
- **Table of Contents**: Auto-generate TOC for articles with heading threshold
- **Social Icons**: Display positions, icon style, and platform URLs
---
+1 -1
View File
@@ -10,7 +10,7 @@
INGROUP: MokoOnyx.Governance
REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
FILE: SECURITY.md
VERSION: 02.22.00
VERSION: 02.27.03
BRIEF: Security policy and vulnerability reporting process for MokoOnyx.
PATH: /SECURITY.md
NOTE: This policy is process oriented and does not replace secure engineering practices.
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: MokoOnyx
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
* PATH: /html/layouts/joomla/module/card.php
* VERSION: 02.22.00
* VERSION: 02.27.03
* BRIEF: Custom card module chrome — renders module titles for all modules
*/
@@ -11,7 +11,7 @@
* INGROUP: MokoOnyx.Layouts
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
* PATH: /src/html/layouts/mokoonyx/article-metadata.php
* VERSION: 02.22.00
* VERSION: 02.27.03
* BRIEF: Article metadata footer layout -- renders jcfields grouped by field group
*/
+33 -7
View File
@@ -52,13 +52,22 @@ $platforms = [
$active = [];
foreach ($platforms as $key => [$iconClass, $langKey]) {
$url = trim((string) $params->get('social_' . $key . '_url', ''));
if ($url !== '' && preg_match('#^(https?://|mailto:|/)#i', $url)) {
$active[] = [
'url' => $url,
'iconClass' => $iconClass,
'label' => Text::_($langKey),
];
if ($url === '') {
continue;
}
if (!preg_match('#^(https?://[^\s<>"]+|mailto:[^\s<>"]+|/[^\s<>"]*)$#i', $url)) {
\Joomla\CMS\Log\Log::add(
'MokoOnyx social: skipped invalid URL for "' . $key . '": ' . $url,
\Joomla\CMS\Log\Log::WARNING,
'template'
);
continue;
}
$active[] = [
'url' => $url,
'iconClass' => $iconClass,
'label' => Text::_($langKey),
];
}
if (empty($active)) {
@@ -84,6 +93,10 @@ if ($position === 'floating') {
$listClass .= ' moko-social-icons--floating-' . $floatingPos;
}
?>
<?php if ($position === 'floating') : ?>
<div class="moko-social-floating-wrap moko-social-floating-wrap--<?php echo htmlspecialchars($floatingPos, ENT_QUOTES, 'UTF-8'); ?>"
id="mokoSocialFloating">
<?php endif; ?>
<nav class="<?php echo $listClass; ?>" aria-label="<?php echo Text::_('TPL_MOKOONYX_SOCIAL_NAV_LABEL'); ?>">
<ul>
<?php foreach ($active as $item) : ?>
@@ -91,10 +104,23 @@ if ($position === 'floating') {
<a href="<?php echo htmlspecialchars($item['url'], ENT_QUOTES, 'UTF-8'); ?>"
target="_blank"
rel="noopener noreferrer"
aria-label="<?php echo htmlspecialchars($item['label'], ENT_QUOTES, 'UTF-8'); ?>">
aria-label="<?php echo htmlspecialchars($item['label'], ENT_QUOTES, 'UTF-8'); ?>"
data-bs-toggle="tooltip"
data-bs-placement="<?php echo $position === 'floating' ? ($floatingPos === 'left' ? 'right' : 'left') : 'top'; ?>"
title="<?php echo htmlspecialchars($item['label'], ENT_QUOTES, 'UTF-8'); ?>">
<span class="<?php echo htmlspecialchars($item['iconClass'], ENT_QUOTES, 'UTF-8'); ?>" aria-hidden="true"></span>
</a>
</li>
<?php endforeach; ?>
</ul>
</nav>
<?php if ($position === 'floating') : ?>
<button type="button"
class="moko-social-floating-toggle"
id="mokoSocialFloatingToggle"
aria-label="<?php echo Text::_('TPL_MOKOONYX_SOCIAL_FLOATING_TOGGLE'); ?>"
aria-expanded="true">
<span class="fa-solid fa-chevron-<?php echo $floatingPos === 'left' ? 'left' : 'right'; ?>" aria-hidden="true"></span>
</button>
</div>
<?php endif; ?>
+3 -2
View File
@@ -286,13 +286,14 @@ TPL_MOKOONYX_SOCIAL_FLOATING_POS_LABEL="Floating Position"
TPL_MOKOONYX_SOCIAL_FLOATING_POS_DESC="Which side of the screen the floating social bar appears on."
TPL_MOKOONYX_SOCIAL_FLOATING_POS_LEFT="Left"
TPL_MOKOONYX_SOCIAL_FLOATING_POS_RIGHT="Right"
TPL_MOKOONYX_SOCIAL_FLOATING_TOGGLE="Toggle social icons sidebar"
TPL_MOKOONYX_SOCIAL_COLOR_LABEL="Icon Colour"
TPL_MOKOONYX_SOCIAL_COLOR_DESC="Choose the colour scheme for social icons."
TPL_MOKOONYX_SOCIAL_COLOR_THEME="Theme (CSS variables)"
TPL_MOKOONYX_SOCIAL_COLOR_BRAND="Brand colours"
TPL_MOKOONYX_SOCIAL_COLOR_BLACK="Black"
TPL_MOKOONYX_SOCIAL_COLOR_WHITE="White"
TPL_MOKOONYX_SOCIAL_URLS_NOTE="<p>Enter the full URL for each platform. Leave blank to hide that icon.</p>"
TPL_MOKOONYX_SOCIAL_URLS_NOTE="<p>At least one URL is required when a social display position is enabled. Leave unused platforms blank to hide their icons.</p>"
TPL_MOKOONYX_SOCIAL_MAIL_DESC="Use a mailto: link (e.g. mailto:hello@example.com) or a contact page URL."
TPL_MOKOONYX_SOCIAL_NAV_LABEL="Social media links"
TPL_MOKOONYX_SOCIAL_FACEBOOK="Follow us on Facebook"
@@ -321,7 +322,7 @@ TPL_MOKOONYX_SOCIAL_MAIL="Email us"
; ===== CSS Variables tab (social) =====
TPL_MOKOONYX_CSS_VARS_SOCIAL_LABEL="Social Icons"
TPL_MOKOONYX_CSS_VARS_SOCIAL_DESC="<code>--social-icon-size</code> — Icon font size (overrides size preset)<br><code>--social-icon-gap</code> — Gap between icons (default: <code>0.5rem</code>)<br><code>--social-icon-color</code> — Icon colour (default: <code>currentColor</code>)<br><code>--social-icon-hover-color</code> — Hover colour (default: <code>var(--accent-color-primary)</code>)<br><code>--social-icon-bg</code> — Background for circle/rounded styles<br><code>--social-icon-hover-bg</code> — Hover background<br><code>--social-icon-radius</code> — Border radius for rounded style (default: <code>0.375rem</code>)"
TPL_MOKOONYX_CSS_VARS_SOCIAL_DESC="<code>--social-icon-size</code> — Icon font size (overrides size preset)<br><code>--social-icon-gap</code> — Gap between icons (default: <code>0.5rem</code>)<br><code>--social-icon-color</code> — Icon colour (default: <code>currentColor</code>)<br><code>--social-icon-hover-color</code> — Hover colour (default: <code>var(--accent-color-primary)</code>)<br><code>--social-icon-bg</code> — Background for circle/rounded styles<br><code>--social-icon-hover-bg</code> — Hover background<br><code>--social-icon-radius</code> — Border radius for rounded style (default: <code>0.375rem</code>)<br><br><strong>Floating bar</strong><br>The collapse toggle button inherits <code>--social-icon-bg</code>, <code>--social-icon-color</code>, and <code>--social-icon-hover-bg</code>. Tooltips appear automatically on hover showing the platform name."
; ===== Misc =====
MOD_BREADCRUMBS_HERE="YOU ARE HERE:"
+3 -2
View File
@@ -286,13 +286,14 @@ TPL_MOKOONYX_SOCIAL_FLOATING_POS_LABEL="Floating Position"
TPL_MOKOONYX_SOCIAL_FLOATING_POS_DESC="Which side of the screen the floating social bar appears on."
TPL_MOKOONYX_SOCIAL_FLOATING_POS_LEFT="Left"
TPL_MOKOONYX_SOCIAL_FLOATING_POS_RIGHT="Right"
TPL_MOKOONYX_SOCIAL_FLOATING_TOGGLE="Toggle social icons sidebar"
TPL_MOKOONYX_SOCIAL_COLOR_LABEL="Icon Color"
TPL_MOKOONYX_SOCIAL_COLOR_DESC="Choose the color scheme for social icons."
TPL_MOKOONYX_SOCIAL_COLOR_THEME="Theme (CSS variables)"
TPL_MOKOONYX_SOCIAL_COLOR_BRAND="Brand colors"
TPL_MOKOONYX_SOCIAL_COLOR_BLACK="Black"
TPL_MOKOONYX_SOCIAL_COLOR_WHITE="White"
TPL_MOKOONYX_SOCIAL_URLS_NOTE="<p>Enter the full URL for each platform. Leave blank to hide that icon.</p>"
TPL_MOKOONYX_SOCIAL_URLS_NOTE="<p>At least one URL is required when a social display position is enabled. Leave unused platforms blank to hide their icons.</p>"
TPL_MOKOONYX_SOCIAL_MAIL_DESC="Use a mailto: link (e.g. mailto:hello@example.com) or a contact page URL."
TPL_MOKOONYX_SOCIAL_NAV_LABEL="Social media links"
TPL_MOKOONYX_SOCIAL_FACEBOOK="Follow us on Facebook"
@@ -321,7 +322,7 @@ TPL_MOKOONYX_SOCIAL_MAIL="Email us"
; ===== CSS Variables tab (social) =====
TPL_MOKOONYX_CSS_VARS_SOCIAL_LABEL="Social Icons"
TPL_MOKOONYX_CSS_VARS_SOCIAL_DESC="<code>--social-icon-size</code> — Icon font size (overrides size preset)<br><code>--social-icon-gap</code> — Gap between icons (default: <code>0.5rem</code>)<br><code>--social-icon-color</code> — Icon color (default: <code>currentColor</code>)<br><code>--social-icon-hover-color</code> — Hover color (default: <code>var(--accent-color-primary)</code>)<br><code>--social-icon-bg</code> — Background for circle/rounded styles<br><code>--social-icon-hover-bg</code> — Hover background<br><code>--social-icon-radius</code> — Border radius for rounded style (default: <code>0.375rem</code>)"
TPL_MOKOONYX_CSS_VARS_SOCIAL_DESC="<code>--social-icon-size</code> — Icon font size (overrides size preset)<br><code>--social-icon-gap</code> — Gap between icons (default: <code>0.5rem</code>)<br><code>--social-icon-color</code> — Icon color (default: <code>currentColor</code>)<br><code>--social-icon-hover-color</code> — Hover color (default: <code>var(--accent-color-primary)</code>)<br><code>--social-icon-bg</code> — Background for circle/rounded styles<br><code>--social-icon-hover-bg</code> — Hover background<br><code>--social-icon-radius</code> — Border radius for rounded style (default: <code>0.375rem</code>)<br><br><strong>Floating bar</strong><br>The collapse toggle button inherits <code>--social-icon-bg</code>, <code>--social-icon-color</code>, and <code>--social-icon-hover-bg</code>. Tooltips appear automatically on hover showing the platform name."
; ===== Misc =====
MOD_BREADCRUMBS_HERE="YOU ARE HERE:"
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: MokoOnyx.Accessibility
* REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
* PATH: ./media/css/a11y-high-contrast.css
* VERSION: 02.22.00
* VERSION: 02.27.03
* BRIEF: High-contrast stylesheet for accessibility toolbar
*/
+67 -11
View File
@@ -23522,7 +23522,7 @@ font-size: 0.8125rem;
.blog-item .item-image img {
width: 100%;
height: 100%;
object-fit: cover;
object-fit: none;
}
.fa-brands {
@@ -23679,26 +23679,42 @@ font-size: 0.8125rem;
}
/* Position: floating — fixed sidebar, hidden on mobile */
.moko-social-icons--floating {
.moko-social-floating-wrap {
position: fixed;
top: 50%;
transform: translateY(-50%);
z-index: 1030;
display: flex;
align-items: center;
transition: transform 0.3s ease;
}
.moko-social-floating-wrap--left {
left: 0;
flex-direction: row;
}
.moko-social-floating-wrap--right {
right: 0;
flex-direction: row-reverse;
}
.moko-social-floating-wrap--left.is-collapsed {
transform: translateY(-50%) translateX(calc(-100% + 1.5rem));
}
.moko-social-floating-wrap--right.is-collapsed {
transform: translateY(-50%) translateX(calc(100% - 1.5rem));
}
.moko-social-icons--floating {
display: flex;
}
.moko-social-icons--floating ul {
flex-direction: column;
}
.moko-social-icons--floating-left {
left: 0;
}
.moko-social-icons--floating-right {
right: 0;
}
.moko-social-icons--floating-left a {
border-radius: 0 var(--social-icon-radius, 0.375rem) var(--social-icon-radius, 0.375rem) 0;
}
@@ -23712,8 +23728,48 @@ font-size: 0.8125rem;
border-radius: inherit;
}
/* Floating toggle button */
.moko-social-floating-toggle {
display: flex;
align-items: center;
justify-content: center;
width: 1.5rem;
height: 2.5rem;
padding: 0;
border: 1px solid var(--social-icon-bg, var(--border-color, hsl(0, 0%, 80%)));
background: var(--social-icon-bg, var(--body-bg, hsl(0, 0%, 100%)));
color: var(--social-icon-color, currentColor);
cursor: pointer;
font-size: 0.65rem;
transition: background 0.2s, color 0.2s;
flex-shrink: 0;
}
.moko-social-floating-wrap--left .moko-social-floating-toggle {
border-radius: 0 var(--social-icon-radius, 0.375rem) var(--social-icon-radius, 0.375rem) 0;
border-left: 0;
}
.moko-social-floating-wrap--right .moko-social-floating-toggle {
border-radius: var(--social-icon-radius, 0.375rem) 0 0 var(--social-icon-radius, 0.375rem);
border-right: 0;
}
.moko-social-floating-toggle:hover {
background: var(--social-icon-hover-bg, var(--accent-color-primary, hsl(220, 70%, 50%)));
color: #fff;
}
.moko-social-floating-toggle .fa-solid {
transition: transform 0.3s ease;
}
.is-collapsed .moko-social-floating-toggle .fa-solid {
transform: rotate(180deg);
}
@media (max-width: 991.98px) {
.moko-social-icons--floating {
.moko-social-floating-wrap {
display: none;
}
}
+42
View File
@@ -789,6 +789,46 @@
});
}
// ========================================================================
// FLOATING SOCIAL BAR (collapsible)
// ========================================================================
var socialStorageKey = "moko-social-collapsed";
function initSocialFloating() {
var wrap = doc.getElementById("mokoSocialFloating");
var toggle = doc.getElementById("mokoSocialFloatingToggle");
if (!wrap || !toggle) return;
// Restore saved state
try {
if (localStorage.getItem(socialStorageKey) === "1") {
wrap.classList.add("is-collapsed");
toggle.setAttribute("aria-expanded", "false");
}
} catch (e) {}
toggle.addEventListener("click", function () {
var collapsed = wrap.classList.toggle("is-collapsed");
toggle.setAttribute("aria-expanded", collapsed ? "false" : "true");
try { localStorage.setItem(socialStorageKey, collapsed ? "1" : "0"); } catch (e) {}
});
}
// ========================================================================
// SOCIAL ICON TOOLTIPS
// ========================================================================
function initSocialTooltips() {
var triggers = doc.querySelectorAll('.moko-social-icons [data-bs-toggle="tooltip"]');
if (!triggers.length) return;
// Bootstrap 5 tooltip init
if (typeof bootstrap !== "undefined" && bootstrap.Tooltip) {
triggers.forEach(function (el) {
new bootstrap.Tooltip(el, { trigger: "hover focus" });
});
}
}
/**
* Run all template JS initializations
*/
@@ -815,6 +855,8 @@
initBackTop();
initSearchToggle();
initSidebarAccordion();
initSocialFloating();
initSocialTooltips();
initVarCopy();
}
+35 -29
View File
@@ -35,7 +35,7 @@
</updateservers>
<dlid prefix="dlid=" suffix=""/>
<name>mokoonyx</name>
<version>02.22.00</version>
<version>02.27.03</version>
<scriptfile>script.php</scriptfile>
<creationDate>2026-05-16</creationDate>
<author>Jonathan Miller || Moko Consulting</author>
@@ -356,22 +356,26 @@
</field>
<!-- Style options -->
<field name="social_sep_style" type="spacer" label="Style" hr="false" class="text fw-bold" />
<field name="social_sep_style" type="spacer" label="Style" hr="false" class="text fw-bold"
showon="social_topbar:1[OR]social_footer:1[OR]social_floating:1" />
<field name="social_icon_style" type="list" default="plain"
label="TPL_MOKOONYX_SOCIAL_STYLE_LABEL" description="TPL_MOKOONYX_SOCIAL_STYLE_DESC">
label="TPL_MOKOONYX_SOCIAL_STYLE_LABEL" description="TPL_MOKOONYX_SOCIAL_STYLE_DESC"
showon="social_topbar:1[OR]social_footer:1[OR]social_floating:1">
<option value="plain">TPL_MOKOONYX_SOCIAL_STYLE_PLAIN</option>
<option value="square">TPL_MOKOONYX_SOCIAL_STYLE_SQUARE</option>
<option value="circle">TPL_MOKOONYX_SOCIAL_STYLE_CIRCLE</option>
<option value="rounded">TPL_MOKOONYX_SOCIAL_STYLE_ROUNDED</option>
</field>
<field name="social_icon_size" type="list" default="md"
label="TPL_MOKOONYX_SOCIAL_SIZE_LABEL" description="TPL_MOKOONYX_SOCIAL_SIZE_DESC">
label="TPL_MOKOONYX_SOCIAL_SIZE_LABEL" description="TPL_MOKOONYX_SOCIAL_SIZE_DESC"
showon="social_topbar:1[OR]social_footer:1[OR]social_floating:1">
<option value="sm">TPL_MOKOONYX_SOCIAL_SIZE_SM</option>
<option value="md">TPL_MOKOONYX_SOCIAL_SIZE_MD</option>
<option value="lg">TPL_MOKOONYX_SOCIAL_SIZE_LG</option>
</field>
<field name="social_icon_color" type="list" default="theme"
label="TPL_MOKOONYX_SOCIAL_COLOR_LABEL" description="TPL_MOKOONYX_SOCIAL_COLOR_DESC">
label="TPL_MOKOONYX_SOCIAL_COLOR_LABEL" description="TPL_MOKOONYX_SOCIAL_COLOR_DESC"
showon="social_topbar:1[OR]social_footer:1[OR]social_floating:1">
<option value="theme">TPL_MOKOONYX_SOCIAL_COLOR_THEME</option>
<option value="brand">TPL_MOKOONYX_SOCIAL_COLOR_BRAND</option>
<option value="black">TPL_MOKOONYX_SOCIAL_COLOR_BLACK</option>
@@ -379,30 +383,32 @@
</field>
<!-- Platform URLs -->
<field name="social_sep_urls" type="spacer" label="Platform URLs" hr="false" class="text fw-bold" />
<field name="social_urls_note" type="note" description="TPL_MOKOONYX_SOCIAL_URLS_NOTE" />
<field name="social_facebook_url" type="url" default="" label="Facebook" filter="url" />
<field name="social_twitter_url" type="url" default="" label="X / Twitter" filter="url" />
<field name="social_instagram_url" type="url" default="" label="Instagram" filter="url" />
<field name="social_linkedin_url" type="url" default="" label="LinkedIn" filter="url" />
<field name="social_youtube_url" type="url" default="" label="YouTube" filter="url" />
<field name="social_github_url" type="url" default="" label="GitHub" filter="url" />
<field name="social_bluesky_url" type="url" default="" label="Bluesky" filter="url" />
<field name="social_threads_url" type="url" default="" label="Threads" filter="url" />
<field name="social_discord_url" type="url" default="" label="Discord" filter="url" />
<field name="social_tiktok_url" type="url" default="" label="TikTok" filter="url" />
<field name="social_reddit_url" type="url" default="" label="Reddit" filter="url" />
<field name="social_pinterest_url" type="url" default="" label="Pinterest" filter="url" />
<field name="social_snapchat_url" type="url" default="" label="Snapchat" filter="url" />
<field name="social_telegram_url" type="url" default="" label="Telegram" filter="url" />
<field name="social_whatsapp_url" type="url" default="" label="WhatsApp" filter="url" />
<field name="social_tumblr_url" type="url" default="" label="Tumblr" filter="url" />
<field name="social_twitch_url" type="url" default="" label="Twitch" filter="url" />
<field name="social_spotify_url" type="url" default="" label="Spotify" filter="url" />
<field name="social_soundcloud_url" type="url" default="" label="SoundCloud" filter="url" />
<field name="social_flickr_url" type="url" default="" label="Flickr" filter="url" />
<field name="social_vimeo_url" type="url" default="" label="Vimeo" filter="url" />
<field name="social_linktree_url" type="url" default="" label="Linktree" filter="url" />
<field name="social_sep_urls" type="spacer" label="Platform URLs" hr="false" class="text fw-bold"
showon="social_topbar:1[OR]social_footer:1[OR]social_floating:1" />
<field name="social_urls_note" type="note" description="TPL_MOKOONYX_SOCIAL_URLS_NOTE"
showon="social_topbar:1[OR]social_footer:1[OR]social_floating:1" />
<field name="social_facebook_url" type="url" default="" label="Facebook" filter="url" validate="url" />
<field name="social_twitter_url" type="url" default="" label="X / Twitter" filter="url" validate="url" />
<field name="social_instagram_url" type="url" default="" label="Instagram" filter="url" validate="url" />
<field name="social_linkedin_url" type="url" default="" label="LinkedIn" filter="url" validate="url" />
<field name="social_youtube_url" type="url" default="" label="YouTube" filter="url" validate="url" />
<field name="social_github_url" type="url" default="" label="GitHub" filter="url" validate="url" />
<field name="social_bluesky_url" type="url" default="" label="Bluesky" filter="url" validate="url" />
<field name="social_threads_url" type="url" default="" label="Threads" filter="url" validate="url" />
<field name="social_discord_url" type="url" default="" label="Discord" filter="url" validate="url" />
<field name="social_tiktok_url" type="url" default="" label="TikTok" filter="url" validate="url" />
<field name="social_reddit_url" type="url" default="" label="Reddit" filter="url" validate="url" />
<field name="social_pinterest_url" type="url" default="" label="Pinterest" filter="url" validate="url" />
<field name="social_snapchat_url" type="url" default="" label="Snapchat" filter="url" validate="url" />
<field name="social_telegram_url" type="url" default="" label="Telegram" filter="url" validate="url" />
<field name="social_whatsapp_url" type="url" default="" label="WhatsApp" filter="url" validate="url" />
<field name="social_tumblr_url" type="url" default="" label="Tumblr" filter="url" validate="url" />
<field name="social_twitch_url" type="url" default="" label="Twitch" filter="url" validate="url" />
<field name="social_spotify_url" type="url" default="" label="Spotify" filter="url" validate="url" />
<field name="social_soundcloud_url" type="url" default="" label="SoundCloud" filter="url" validate="url" />
<field name="social_flickr_url" type="url" default="" label="Flickr" filter="url" validate="url" />
<field name="social_vimeo_url" type="url" default="" label="Vimeo" filter="url" validate="url" />
<field name="social_linktree_url" type="url" default="" label="Linktree" filter="url" validate="url" />
<field name="social_mail_url" type="url" default="" label="Email" description="TPL_MOKOONYX_SOCIAL_MAIL_DESC" filter="string" />
</fieldset>