Compare commits

...

138 Commits

Author SHA1 Message Date
jmiller 20c036f913 chore(docs): normalize refs — MokoStandards->org wiki, moko-platform->mokocli, residual MokoGitea/MokoSuite
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 19s
Non-workflow docs/config only (CLAUDE.md, README, branch-protection, ISSUE_TEMPLATE/config.yml,
ci-issue-reporter). Workflow files, manifest schema, and Makefile install paths left for the
forge-rebrand gate. Authored-by: Moko Consulting
2026-07-05 22:50:13 +00:00
jmiller 062b33b395 chore: sync workflow-sync-trigger.yml from Template-Generic [skip ci] 2026-07-05 21:31:17 +00:00
jmiller 2d8bb5e967 chore: sync version-set.yml from Template-Generic [skip ci] 2026-07-05 21:31:16 +00:00
jmiller a172b21b9b chore: sync repo-health.yml from Template-Generic [skip ci] 2026-07-05 21:31:14 +00:00
jmiller 2ce8caad88 chore: sync rc-revert.yml from Template-Generic [skip ci] 2026-07-05 21:31:12 +00:00
jmiller 0b97aa06c9 chore: sync pre-release.yml from Template-Generic [skip ci] 2026-07-05 21:31:10 +00:00
jmiller f2fb64ec5a chore: sync pr-check.yml from Template-Generic [skip ci] 2026-07-05 21:31:08 +00:00
jmiller eabc96b506 chore: sync notify.yml from Template-Generic [skip ci] 2026-07-05 21:31:07 +00:00
jmiller ed54dd5153 chore: sync gitleaks.yml from Template-Generic [skip ci] 2026-07-05 21:28:53 +00:00
jmiller 40ebb4774c chore: sync cleanup.yml from Template-Generic [skip ci] 2026-07-05 21:28:52 +00:00
jmiller bb2c34abbb chore: sync ci-issue-reporter.yml from Template-Generic [skip ci] 2026-07-05 21:28:51 +00:00
jmiller 5680b32e31 chore: sync ci-generic.yml from Template-Generic [skip ci] 2026-07-05 21:28:50 +00:00
jmiller 88fa860080 chore: sync cascade-dev.yml from Template-Generic [skip ci] 2026-07-05 21:28:49 +00:00
jmiller 0d9c64cd28 chore: sync branch-cleanup.yml from Template-Generic [skip ci] 2026-07-05 21:28:47 +00:00
jmiller 3dbd221c69 chore: sync auto-release.yml from Template-Generic [skip ci] 2026-07-05 21:28:46 +00:00
jmiller 2cedc0b94e chore: sync auto-bump.yml from Template-Generic [skip ci] 2026-07-05 21:28:45 +00:00
jmiller 94fde481d2 chore: sync workflow-sync-trigger.yml from Template-Generic [skip ci] 2026-07-05 21:08:00 +00:00
jmiller b5c38d76e8 chore: sync pr-check.yml from Template-Generic [skip ci] 2026-07-05 21:07:58 +00:00
jmiller ce0502e788 chore: sync version-set.yml from Template-Generic [skip ci] 2026-07-05 20:39:20 +00:00
jmiller cf29777daa chore: sync sync-on-merge.yml from Template-Generic [skip ci] 2026-07-05 20:39:19 +00:00
jmiller 61d52ce1cb chore: sync rc-revert.yml from Template-Generic [skip ci] 2026-07-05 20:39:17 +00:00
jmiller 16305623cc chore: sync pre-release.yml from Template-Generic [skip ci] 2026-07-05 20:39:16 +00:00
jmiller e5768d5e44 chore: sync gitleaks.yml from Template-Generic [skip ci] 2026-07-05 20:39:13 +00:00
jmiller 9342bdf373 chore: sync auto-bump.yml from Template-Generic [skip ci] 2026-07-05 20:39:09 +00:00
jmiller dad002cc08 chore: sync repo-health.yml from Template-Generic [skip ci] 2026-07-05 20:34:02 +00:00
jmiller 37fdef1323 chore: sync rc-revert.yml from Template-Generic [skip ci] 2026-07-05 20:34:00 +00:00
jmiller 845a377045 chore: sync pre-release.yml from Template-Generic [skip ci] 2026-07-05 20:33:58 +00:00
jmiller 1a83a2abd5 chore: sync pr-check.yml from Template-Generic [skip ci] 2026-07-05 20:33:55 +00:00
jmiller 9577ea6058 chore: sync issue-branch.yml from Template-Generic [skip ci] 2026-07-05 20:33:53 +00:00
jmiller c113f0437e chore: sync gitleaks.yml from Template-Generic [skip ci] 2026-07-05 20:33:51 +00:00
jmiller bfaab8a79e chore: sync ci-issue-reporter.yml from Template-Generic [skip ci] 2026-07-05 20:33:48 +00:00
jmiller 84e54c7567 chore: sync cascade-dev.yml from Template-Generic [skip ci] 2026-07-05 20:33:45 +00:00
jmiller f270ce6a78 chore: sync branch-cleanup.yml from Template-Generic [skip ci] 2026-07-05 20:33:43 +00:00
jmiller 7b45f7d92b chore: sync auto-release.yml from Template-Generic [skip ci] 2026-07-05 20:33:41 +00:00
jmiller 9859a06a09 chore: sync auto-bump.yml from Template-Generic [skip ci] 2026-07-05 20:33:39 +00:00
gitea-actions[bot] 926142afa9 chore: promote changelog [Unreleased] → [09.43.00] 2026-07-05 20:31:09 +00:00
gitea-actions[bot] 6e5a3b902c chore(release): build 09.43.00 [skip ci]
Sync Workflows to Repos / sync (push) Failing after 3s
Publish to Composer / Publish Package (release) Successful in 59s
Platform: mokocli CI / Gate 1: Code Quality (push) Successful in 2m11s
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (push) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: mokocli CI / CI Summary (push) Has been cancelled
2026-07-05 20:31:03 +00:00
jmiller 08130d1bf3 Merge pull request 'chore: rename all mokoplatform → mokocli references' (#338) from feat/rename-mokoplatform into main
Platform: mokocli CI / Gate 1: Code Quality (push) Successful in 1m48s
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (push) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: mokocli CI / CI Summary (push) Has been cancelled
2026-07-05 20:30:38 +00:00
jmiller 4009d68a7a chore: rename all mokoplatform -> mokocli references
Universal: PR Check / Branch Policy (pull_request) Failing after 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 3s
Universal: PR Check / Validate PR (pull_request) Failing after 14s
Universal: PR Check / Secret Scan (pull_request) Successful in 15s
Generic: Project CI / Lint & Validate (pull_request) Successful in 57s
Platform: mokocli CI / Gate 1: Code Quality (pull_request) Successful in 2m4s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 2s
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 35s
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Failing after 28m16s
Generic: Project CI / Tests (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokocli CI / CI Summary (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: Scripts Governance (pull_request) Has been cancelled
Generic: Repo Health / Report: Repository Health (pull_request) Has been cancelled
The repo was renamed mokoplatform -> mokocli; this rewrites every stale
reference across the tree (case-sensitive):

  MokoPlatform  -> MokoCLI   (DEFGROUP/INGROUP doc tags)
  mokoplatform  -> mokocli   (repo URLs, /opt & /tmp paths, clone URLs,
                              EXCLUDE lists, XML xmlns + <root> namespace)
  moko-platform -> moko-cli  (marker files)

XML namespace URIs and ManifestParser::NAMESPACE_URI are changed in
lockstep so local manifest-vs-parser validation stays consistent. The
external standards.mokoconsulting.tech namespace endpoint must be updated
to match separately (tracked in #336).

Refs #336

Claude-Session: https://claude.ai/code/session_01WbGBN9VyRK61zczYWcCQ2i
2026-07-05 15:25:45 -05:00
jmiller 2312c95dba chore: sync notify.yml from Template-Generic [skip ci] 2026-07-05 00:04:08 +00:00
jmiller 7a06bcf403 chore: sync cleanup.yml from Template-Generic [skip ci] 2026-07-05 00:04:07 +00:00
gitea-actions[bot] a8baf355c4 chore: promote changelog [Unreleased] → [09.42.00] 2026-07-04 23:27:30 +00:00
gitea-actions[bot] 9520ce3bb8 chore(release): build 09.42.00 [skip ci]
Publish to Composer / Publish Package (release) Successful in 58s
2026-07-04 23:27:15 +00:00
jmiller 120dbe3be2 Merge pull request 'fix: branch_rename force-updates target ref instead of delete+recreate' (#335) from fix/promote-rc-force-update into main
Platform: mokocli CI / Gate 1: Code Quality (push) Successful in 2m0s
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (push) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: mokocli CI / CI Summary (push) Has been cancelled
2026-07-04 23:26:39 +00:00
jmiller 657e6013de chore: sync issue-branch.yml from Template-Generic [skip ci] 2026-07-04 23:25:48 +00:00
jmiller c7a26c1ce1 fix: promote-rc force-updates target ref instead of delete+recreate
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Failing after 9s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: PR Check / Secret Scan (pull_request) Successful in 13s
Universal: PR Check / Validate PR (pull_request) Successful in 9s
Generic: Repo Health / Access control (pull_request) Successful in 3s
Generic: Repo Health / Site Health (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 3s
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 44s
Generic: Project CI / Lint & Validate (pull_request) Successful in 1m7s
Platform: mokocli CI / Gate 1: Code Quality (pull_request) Successful in 1m52s
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Failing after 8m27s
Generic: Project CI / Tests (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokocli CI / CI Summary (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: Scripts Governance (pull_request) Has been cancelled
Generic: Repo Health / Report: Repository Health (pull_request) Has been cancelled
branch_rename.php deleted the target branch then recreated it. When the target (rc) is a protected branch, the delete silently fails and the recreate returns HTTP 409 'branch already exists', breaking every PR-to-main promote-rc. Force-update the ref in place via PATCH git/refs/heads/{to} (sha+force) when the target exists; still create it when it doesn't. Requires the CI token to have force-push permission on the protected rc branch.
2026-07-04 18:25:43 -05:00
jmiller bdbabd9886 chore: sync auto-release.yml from Template-Generic [skip ci] 2026-07-04 23:25:41 +00:00
gitea-actions[bot] e061537404 chore: promote changelog [Unreleased] → [09.42.00] 2026-07-04 23:23:40 +00:00
gitea-actions[bot] 4637dab159 chore(release): build 09.42.00 [skip ci]
Sync Workflows to Repos / sync (push) Failing after 4s
Publish to Composer / Publish Package (release) Successful in 1m3s
Platform: mokocli CI / Gate 1: Code Quality (push) Successful in 2m3s
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (push) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: mokocli CI / CI Summary (push) Has been cancelled
2026-07-04 23:23:30 +00:00
jmiller b885f12ece Merge pull request 'chore(branch-protection): allow actions + moko-deploy bots on protected branches' (#334) from chore/branch-protection-bot-allowlist into main
Platform: mokocli CI / Gate 1: Code Quality (push) Successful in 2m19s
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (push) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: mokocli CI / CI Summary (push) Has been cancelled
2026-07-04 23:23:06 +00:00
jmiller e99881ad65 chore(branch-protection): allow actions + moko-deploy bots on protected branches
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 19s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Generic: Repo Health / Access control (pull_request) Successful in 3s
Universal: PR Check / Validate PR (pull_request) Failing after 10s
Universal: PR Check / Secret Scan (pull_request) Successful in 14s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 3s
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 41s
Platform: mokocli CI / Gate 1: Code Quality (pull_request) Successful in 2m0s
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Failing after 13m47s
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokocli CI / CI Summary (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: Scripts Governance (pull_request) Has been cancelled
Generic: Repo Health / Report: Repository Health (pull_request) Has been cancelled
Adds the automation identities to the branch-protection rule definitions so
release automation can operate on protected branches:
- all rules: push_whitelist_actions_user=true + moko-deploy in push whitelist
- dev, rc: enable force-push for the bots so dev can be reset to main via a
  single `git push --force origin main:dev` (delete+recreate cannot work on a
  protected branch)
- main keeps force-push disabled

moko-deploy needs org-team write access to take effect (mcp-mokogitea-api#30).
Unblocks the dev-sync + version-persist fixes (Template-Generic#53).

Claude-Session: https://claude.ai/code/session_01WbGBN9VyRK61zczYWcCQ2i
2026-07-04 18:21:50 -05:00
gitea-actions[bot] fd3c847fb1 chore: promote changelog [Unreleased] → [09.41.00] 2026-07-04 21:02:50 +00:00
gitea-actions[bot] 424fe658ba chore(release): build 09.41.00 [skip ci]
Publish to Composer / Publish Package (release) Successful in 9s
2026-07-04 21:02:47 +00:00
jmiller 0ff87f3631 Merge pull request 'fix: baseline pre-existing PHPStan level-6 findings so Gate 1 passes' (#333) from hotfix/phpstan-baseline into main
Platform: mokocli CI / Gate 1: Code Quality (push) Successful in 1m11s
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (push) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: mokocli CI / CI Summary (push) Has been cancelled
2026-07-04 21:02:34 +00:00
jmiller 3164f21ba9 fix: rename colliding printSummary() in client_provision to resolve PHPStan override errors
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Access control (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Validate PR (pull_request) Successful in 9s
Universal: PR Check / Secret Scan (pull_request) Successful in 14s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 16s
Generic: Project CI / Lint & Validate (pull_request) Successful in 54s
Platform: mokocli CI / Gate 1: Code Quality (pull_request) Successful in 1m23s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 1s
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 19s
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Successful in 2m48s
Generic: Project CI / Tests (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokocli CI / CI Summary (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: Scripts Governance (pull_request) Has been cancelled
Generic: Repo Health / Report: Repository Health (pull_request) Has been cancelled
2026-07-04 15:55:14 -05:00
jmiller 713cb61efc fix: baseline pre-existing PHPStan level-6 findings + changelog
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 20s
Universal: Build & Release / Promote to RC (pull_request) Failing after 17s
Universal: Build & Release / Build & Release Pipeline (pull_request) Has been skipped
Generic: Project CI / Lint & Validate (pull_request) Successful in 50s
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Universal: PR Check / Secret Scan (pull_request) Successful in 12s
Universal: PR Check / Validate PR (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
Platform: mokocli CI / Gate 1: Code Quality (pull_request) Failing after 2m13s
Generic: Project CI / Tests (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokocli CI / CI Summary (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: Scripts Governance (pull_request) Has been cancelled
Generic: Repo Health / Report: Repository Health (pull_request) Has been cancelled
Gate 1 static analysis reported 194 pre-existing PHPStan level-6 findings across cli/, lib/, and validate/ (missing iterable value types, override signature mismatches, etc.). Add them to phpstan-baseline.neon so Gate 1 passes; the debt stays tracked in the baseline for incremental cleanup. Also adds the changelog entry required by the PR check.
2026-07-04 15:48:06 -05:00
gitea-actions[bot] fa342a278b chore: promote changelog [Unreleased] → [09.41.00] 2026-07-04 20:41:33 +00:00
gitea-actions[bot] d91baf996e chore(release): build 09.41.00 [skip ci]
Publish to Composer / Publish Package (release) Successful in 55s
2026-07-04 20:41:23 +00:00
jmiller 2100a3bec7 Merge pull request 'fix: remove shebang from RecoverySuggestion.php (PSR-12)' (#332) from hotfix/recovery-suggestion-shebang into main
Platform: mokocli CI / Gate 1: Code Quality (push) Failing after 2m4s
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (push) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: mokocli CI / CI Summary (push) Has been cancelled
2026-07-04 20:40:58 +00:00
jmiller 8d772df3e7 fix: wrap over-length line in RecoverySuggestion.php (PSR-12)
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 2s
Universal: PR Check / Validate PR (pull_request) Failing after 9s
Universal: PR Check / Secret Scan (pull_request) Successful in 12s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 19s
Generic: Project CI / Lint & Validate (pull_request) Successful in 1m18s
Platform: mokocli CI / Gate 1: Code Quality (pull_request) Failing after 2m52s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 3s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 39s
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Successful in 8m21s
Generic: Project CI / Tests (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokocli CI / CI Summary (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: Scripts Governance (pull_request) Has been cancelled
Generic: Repo Health / Report: Repository Health (pull_request) Has been cancelled
The forMissingHeader() return was 177 chars, exceeding the 150-char
limit (Generic.Files.LineLength) that Gate 1 enforces as an error.
Split it across concatenated lines; output is unchanged. (Also keeps
the earlier shebang removal.)
2026-07-04 20:35:50 +00:00
jmiller 3972e4fb84 fix: remove shebang from RecoverySuggestion.php (PSR-12)
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Universal: PR Check / Secret Scan (pull_request) Successful in 13s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 13s
Universal: PR Check / Validate PR (pull_request) Failing after 7s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: Build & Release / Promote to RC (pull_request) Failing after 11s
Universal: Build & Release / Build & Release Pipeline (pull_request) Has been skipped
Generic: Project CI / Lint & Validate (pull_request) Successful in 42s
Platform: mokocli CI / Gate 1: Code Quality (pull_request) Failing after 1m0s
Generic: Project CI / Tests (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokocli CI / CI Summary (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: Scripts Governance (pull_request) Has been cancelled
Generic: Repo Health / Report: Repository Health (pull_request) Has been cancelled
A library class file must open with <?php as the first line; the
#!/usr/bin/env php shebang tripped the PSR-12 file-header check (Gate 1
Code Quality). Remove it.
2026-07-04 20:27:49 +00:00
jmiller 86b8449eba chore: sync pr-check.yml from Template-Generic [skip ci] 2026-07-04 20:27:18 +00:00
jmiller 601451867d chore: sync pr-check.yml from Template-Generic [skip ci] 2026-07-04 20:21:53 +00:00
jmiller 09ffcdce49 chore: sync ci-generic.yml from Template-Generic [skip ci] 2026-07-04 20:21:51 +00:00
jmiller a49e0d7b2a chore: sync sync-on-merge.yml from Template-Generic [skip ci] 2026-07-04 19:37:14 +00:00
jmiller bc1a111775 chore: sync pr-check.yml from Template-Generic [skip ci] 2026-07-04 19:37:12 +00:00
jmiller 98c41c3a53 chore: sync ci-generic.yml from Template-Generic [skip ci] 2026-07-04 19:37:09 +00:00
jmiller 52ebcde1ff chore: sync branch-cleanup.yml from Template-Generic [skip ci] 2026-07-04 19:37:07 +00:00
gitea-actions[bot] ded17c34b8 chore: promote changelog [Unreleased] → [09.41.00] 2026-07-04 19:36:22 +00:00
gitea-actions[bot] 1b79de20a9 chore(release): build 09.41.00 [skip ci]
Publish to Composer / Publish Package (release) Successful in 46s
2026-07-04 19:36:19 +00:00
jmiller bba1cbc845 Merge pull request 'fix: pr-check platform detection via metadata API, allow fix/patch to main' (#331) from hotfix/pr-check-metadata-platform into main
Sync Workflows to Repos / sync (push) Failing after 3s
Platform: mokocli CI / Gate 1: Code Quality (push) Failing after 1m3s
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (push) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: mokocli CI / CI Summary (push) Has been cancelled
2026-07-04 19:36:03 +00:00
jmiller 3f956f5661 fix: drop removed automation/ dir refs and dangling mcp submodule gitlinks
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Generic: Repo Health / Access control (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Validate PR (pull_request) Successful in 9s
Universal: PR Check / Secret Scan (pull_request) Successful in 11s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 18s
Generic: Project CI / Lint & Validate (pull_request) Successful in 1m6s
Platform: mokocli CI / Gate 1: Code Quality (pull_request) Failing after 1m17s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Failing after 2s
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 22s
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Successful in 6m14s
Generic: Project CI / Tests (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokocli CI / CI Summary (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: Scripts Governance (pull_request) Has been cancelled
Generic: Repo Health / Report: Repository Health (pull_request) Has been cancelled
The automation/ directory was removed (bulk_sync.php moved to wrappers/, others deleted) but references remained, hard-failing Gate 1 phpcs and the post-merge sync. Drop automation/ from phpcs/phpstan config and repoint sync-on-merge to wrappers/bulk_sync.php. Also remove the dangling mcp/servers/mokogitea_api and mcp/servers/windows/mcp_windows gitlinks that had no .gitmodules entry and broke submodule init at checkout.
2026-07-04 14:32:22 -05:00
jmiller 9036d20898 fix: pr-check platform detection via metadata API, allow fix/patch to main
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Failing after 6s
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 1s
Universal: PR Check / Validate PR (pull_request) Successful in 8s
Universal: PR Check / Secret Scan (pull_request) Successful in 10s
Generic: Project CI / Lint & Validate (pull_request) Successful in 25s
Platform: mokocli CI / Gate 1: Code Quality (pull_request) Failing after 48s
Generic: Project CI / Tests (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokocli CI / CI Summary (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: Scripts Governance (pull_request) Has been cancelled
Generic: Repo Health / Report: Repository Health (pull_request) Has been cancelled
Read the build platform from the MokoGitea metadata API instead of .mokogitea/manifest.xml, which is no longer used and caused the Detect platform step to abort under set -e when absent. Also allow fix/* and patch/* branches to target main per documented branch policy.
2026-07-04 14:19:06 -05:00
jmiller 7c1edcf813 chore: sync sync-on-merge.yml from Template-Generic [skip ci] 2026-07-04 19:03:10 +00:00
jmiller fec5a48b4a chore: sync pre-release.yml from Template-Generic [skip ci] 2026-07-04 19:03:08 +00:00
jmiller 468b962aaa chore: sync pr-check.yml from Template-Generic [skip ci] 2026-07-04 19:03:06 +00:00
jmiller cc66a79fea chore: sync notify.yml from Template-Generic [skip ci] 2026-07-04 19:03:05 +00:00
jmiller 660ae5bed4 chore: sync cleanup.yml from Template-Generic [skip ci] 2026-07-04 19:03:03 +00:00
jmiller 5ffaf95d20 chore: sync ci-generic.yml from Template-Generic [skip ci] 2026-07-04 19:03:02 +00:00
jmiller ddfb479bc2 chore: sync auto-release.yml from Template-Generic [skip ci] 2026-07-04 19:03:01 +00:00
jmiller 13e2729124 Merge pull request 'fix: remove orphaned deploy-manual workflow' (#330) from fix/remove-deploy-manual into main
fix: remove orphaned deploy-manual workflow [skip ci]
2026-06-30 18:33:26 +00:00
jmiller 05ee59d75e fix: remove orphaned deploy-manual workflow [skip ci] 2026-06-30 18:06:51 +00:00
jmiller c4bb08073b Merge pull request 'feat(cli): theme_vars_check governance — forbidden files, topics, protection, element naming' (#329) from feat/theme-vars-governance into main
Platform: mokocli CI / Gate 1: Code Quality (push) Failing after 1m28s
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (push) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: mokocli CI / CI Summary (push) Has been cancelled
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Failing after 5s
2026-06-29 17:03:47 +00:00
jmiller b32556fdef feat(cli): theme_vars_check governance — forbidden files, topics, protection, element naming
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Failing after 5s
Universal: PR Check / Branch Policy (pull_request) Failing after 1s
Universal: PR Check / Secret Scan (pull_request) Successful in 8s
Universal: PR Check / Validate PR (pull_request) Failing after 5s
Generic: Repo Health / Access control (pull_request) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 1s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Generic: Project CI / Lint & Validate (pull_request) Successful in 55s
Platform: mokocli CI / Gate 1: Code Quality (pull_request) Failing after 1m23s
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Successful in 3m42s
Generic: Project CI / Tests (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokocli CI / CI Summary (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: Scripts Governance (pull_request) Has been cancelled
Generic: Repo Health / Report: Repository Health (pull_request) Has been cancelled
- Forbidden committed files: .mcp.json/.mcp_*.json, sftp-config*.json,
  *.min.css/*.min.js, TODO.md, .claude/.
- Required repo topics (joomla, client-waas, mokoonyx) via Gitea API.
- main branch protection enforced via Gitea API.
- <element> naming convention (file_mokoonyx_*) for file packages.

Authored-by: Moko Consulting
2026-06-29 12:03:14 -05:00
jmiller c57a7e4b96 Merge pull request 'feat(cli): theme_vars_check manifest completeness + fileset integrity' (#328) from feat/theme-vars-manifest into main
Platform: mokocli CI / Gate 1: Code Quality (push) Failing after 1m26s
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (push) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: mokocli CI / CI Summary (push) Has been cancelled
2026-06-29 16:58:09 +00:00
jmiller 5846ccc3e8 feat(cli): theme_vars_check manifest completeness + fileset integrity
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Failing after 4s
Universal: PR Check / Branch Policy (pull_request) Failing after 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 2s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Failing after 2s
Universal: PR Check / Validate PR (pull_request) Failing after 10s
Universal: PR Check / Secret Scan (pull_request) Successful in 21s
Generic: Project CI / Lint & Validate (pull_request) Successful in 30s
Platform: mokocli CI / Gate 1: Code Quality (pull_request) Failing after 1m12s
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Successful in 4m36s
Generic: Project CI / Tests (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokocli CI / CI Summary (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: Scripts Governance (pull_request) Has been cancelled
Generic: Repo Health / Report: Repository Health (pull_request) Has been cancelled
- Verify required manifest fields: <name>, <element>, <author>, <creationDate>.
- Verify <scriptfile> target exists in src/.
- Fileset integrity: every <filename>/<folder> in <fileset> must exist in src/
  — catches the "Failed to find source folder" install failure class at CI time.

Authored-by: Moko Consulting
2026-06-29 11:57:35 -05:00
jmiller 6ba0208571 chore: sync pr-check.yml from Template-Generic [skip ci] 2026-06-29 16:50:50 +00:00
jmiller 759b04e088 chore: sync issue-branch.yml from Template-Generic [skip ci] 2026-06-29 16:50:49 +00:00
jmiller 4dfa2d9722 chore: sync ci-issue-reporter.yml from Template-Generic [skip ci] 2026-06-29 16:50:48 +00:00
jmiller 590ad7337a chore: sync branch-cleanup.yml from Template-Generic [skip ci] 2026-06-29 16:50:47 +00:00
jmiller c607966e83 chore: sync auto-release.yml from Template-Generic [skip ci] 2026-06-29 16:50:46 +00:00
jmiller 97f2226288 Merge pull request 'feat(cli): add theme_vars_check.php for client MokoOnyx themes' (#327) from feat/theme-vars-check into main
Platform: mokocli CI / Gate 1: Code Quality (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (push) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: mokocli CI / CI Summary (push) Has been cancelled
2026-06-29 16:45:42 +00:00
jmiller b1f2c391cb feat(cli): derive required vars from MokoOnyx standard theme + repo metadata
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Failing after 6s
Generic: Project CI / Lint & Validate (pull_request) Successful in 16s
Platform: mokocli CI / Gate 1: Code Quality (pull_request) Failing after 1m3s
pr-check.yml / Branch Policy (pull_request) Has been cancelled
Universal: PR Check / Secret Scan (pull_request) Has been cancelled
Universal: PR Check / Validate PR (pull_request) Has been cancelled
Generic: Repo Health / Access control (pull_request) Has been cancelled
Generic: Repo Health / Site Health (pull_request) Has been cancelled
Branch Cleanup / Delete merged branch (pull_request) Has been cancelled
RC Revert / Rename rc/ back to dev/ (pull_request) Has been cancelled
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Has been cancelled
Generic: Project CI / Tests (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokocli CI / CI Summary (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: Scripts Governance (pull_request) Has been cancelled
Generic: Repo Health / Report: Repository Health (pull_request) Has been cancelled
- Read the required CSS variable set dynamically from the MokoOnyx standard
  theme (--reference checkout) instead of a hardcoded list, so it auto-syncs.
  Verifies client light/dark custom CSS defines every standard variable.
- Add optional repo-metadata check via Gitea API (--api-base/--repo/--token):
  description, website, topics, default branch.
- Drop unused --strict flag.

Authored-by: Moko Consulting
2026-06-29 11:45:09 -05:00
jmiller 7e4d88eea5 feat(cli): add theme_vars_check.php for client MokoOnyx themes
Universal: Build & Release / Promote to RC (pull_request) Failing after 3s
Universal: Build & Release / Build & Release Pipeline (pull_request) Has been skipped
Generic: Project CI / Lint & Validate (pull_request) Successful in 31s
Platform: mokocli CI / Gate 1: Code Quality (pull_request) Failing after 56s
pr-check.yml / Branch Policy (pull_request) Has been cancelled
Universal: PR Check / Secret Scan (pull_request) Has been cancelled
Universal: PR Check / Validate PR (pull_request) Has been cancelled
Generic: Repo Health / Access control (pull_request) Has been cancelled
Generic: Repo Health / Site Health (pull_request) Has been cancelled
Generic: Project CI / Tests (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokocli CI / CI Summary (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: Scripts Governance (pull_request) Has been cancelled
Generic: Repo Health / Report: Repository Health (pull_request) Has been cancelled
Validates a client theme package: required CSS variables defined in both
light.custom.css and dark.custom.css, required files present, and
templateDetails.xml sanity (version, dynamic update server not raw/branch,
dlid). Standalone (no CliFramework dependency).

Authored-by: Moko Consulting
2026-06-29 11:36:05 -05:00
jmiller 9fdd6c5cf9 Merge pull request 'fix(security): prevent Actions script injection in workflows' (#326) from fix/workflow-actions-injection into main
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (push) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: mokocli CI / CI Summary (push) Has been cancelled
Platform: mokocli CI / Gate 1: Code Quality (push) Failing after 1m22s
2026-06-29 16:19:27 +00:00
jmiller 113af457d9 fix(security): prevent Actions script injection in workflows
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Failing after 7s
Generic: Project CI / Lint & Validate (pull_request) Successful in 23s
Platform: mokocli CI / Gate 1: Code Quality (pull_request) Failing after 1m12s
pr-check.yml / Branch Policy (pull_request) Has been cancelled
Universal: PR Check / Secret Scan (pull_request) Has been cancelled
Universal: PR Check / Validate PR (pull_request) Has been cancelled
Generic: Repo Health / Access control (pull_request) Has been cancelled
Generic: Repo Health / Site Health (pull_request) Has been cancelled
Branch Cleanup / Delete merged branch (pull_request) Has been cancelled
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Has been cancelled
Generic: Project CI / Tests (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokocli CI / CI Summary (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: Scripts Governance (pull_request) Has been cancelled
Generic: Repo Health / Report: Repository Health (pull_request) Has been cancelled
RC Revert / Rename rc/ back to dev/ (pull_request) Has been cancelled
Untrusted ${{ }} expressions (issue titles, PR head refs, reusable-workflow
inputs) were interpolated directly into run: shell bodies, allowing command
injection. Each is now passed through an env: block and referenced as a shell
variable in the script (env vars are not subject to ${{ }} expansion).

Files:
- ci-issue-reporter.yml  inputs.gate/details/severity/workflow
- issue-branch.yml       github.event.issue.title
- branch-cleanup.yml     github.event.pull_request.head.ref
- pr-check.yml           github.head_ref / github.base_ref
- auto-release.yml       github.event.pull_request.head.ref (x2)

Propagates to all template consumers via the workflow sync.
Refs MokoConsulting/Template-Joomla#35.

Authored-by: Moko Consulting
2026-06-29 11:18:23 -05:00
jmiller abd67f6c43 chore: sync auto-release.yml from Template-Generic [skip ci] 2026-06-29 06:34:23 +00:00
jmiller d3dce5d24e chore: sync ci-generic.yml from Template-Generic [skip ci] 2026-06-27 20:43:28 +00:00
jmiller c9592d8e78 chore: sync rc-revert.yml from Template-Generic [skip ci] 2026-06-27 05:31:49 +00:00
gitea-actions[bot] 6bf6251705 chore: promote changelog [Unreleased] → [09.41.00] 2026-06-27 02:17:47 +00:00
gitea-actions[bot] 520acd4fee chore(release): build 09.41.00 [skip ci]
Publish to Composer / Publish Package (release) Successful in 10s
2026-06-27 02:17:44 +00:00
jmiller a6c4fe0688 Merge pull request 'feat: nested Joomla package support in release_package.php' (#323) from fix/release-dead-variable into main
Platform: mokocli CI / Gate 1: Code Quality (push) Failing after 38s
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (push) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: mokocli CI / CI Summary (push) Has been cancelled
2026-06-27 02:17:32 +00:00
jmiller 3c420284e3 fix: harden nested package build against collisions and missing assets
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 10s
Universal: PR Check / Branch Policy (pull_request) Failing after 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 2s
Universal: PR Check / Validate PR (pull_request) Failing after 6s
Universal: PR Check / Secret Scan (pull_request) Successful in 9s
Platform: mokocli CI / Gate 1: Code Quality (pull_request) Failing after 53s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 1s
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 15s
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Failing after 2m32s
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokocli CI / CI Summary (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
- Write nested sub-extension ZIPs to subdirectory to prevent filename
  collisions with outer package ZIPs (deferred ZipArchive::addFile reads)
- Apply exclude patterns to nested top-level files (parity with outer)
- Patch nested manifest with folder="packages" so Joomla finds sub-ZIPs
- Include all top-level directories (not just language/) in nested packages

Claude-Session: https://claude.ai/code/session_01MbEjBtsSjPuTWhqqrMS2wG
2026-06-26 21:11:46 -05:00
jmiller 66543c14d3 chore: sync pre-release.yml from Template-Generic [skip ci] 2026-06-27 00:48:56 +00:00
gitea-actions[bot] d9908e264a chore: promote changelog [Unreleased] → [09.41.00] 2026-06-27 00:48:29 +00:00
gitea-actions[bot] 9206f716e1 chore(release): build 09.41.00 [skip ci]
Publish to Composer / Publish Package (release) Successful in 9s
2026-06-27 00:48:27 +00:00
jmiller 84633e22e5 Merge pull request 'fix: prevent duplicate version tags in Joomla manifests' (#322) from fix/version-bump-duplicates into main
Platform: mokocli CI / Gate 1: Code Quality (push) Failing after 39s
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (push) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: mokocli CI / CI Summary (push) Has been cancelled
2026-06-27 00:48:17 +00:00
jmiller 510d1248ab fix: prevent duplicate <version> tags in Joomla manifests
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 9s
Universal: PR Check / Branch Policy (pull_request) Failing after 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 1s
Universal: PR Check / Validate PR (pull_request) Failing after 4s
Universal: PR Check / Secret Scan (pull_request) Successful in 6s
Platform: mokocli CI / Gate 1: Code Quality (pull_request) Failing after 36s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 1s
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 15s
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Failing after 5m25s
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokocli CI / CI Summary (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: Scripts Governance (pull_request) Has been cancelled
Generic: Repo Health / Report: Repository Health (pull_request) Has been cancelled
version_bump, version_set_platform, and version_check all used
unlimited preg_replace on <version> tags. If a duplicate ever got
introduced (merge conflict, manual edit), every subsequent CI bump
faithfully updated both copies — perpetuating the duplicate forever.

Fix: use limit=1 for the primary replacement, then collapse any
remaining duplicate <version> lines in a second pass.

Claude-Session: https://claude.ai/code/session_01MbEjBtsSjPuTWhqqrMS2wG
2026-06-26 19:42:55 -05:00
jmiller 8e30fa54b3 feat: support nested Joomla packages in release_package.php
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 9s
When a sub-package directory contains its own pkg_*.xml manifest and
packages/ directory (e.g. a git submodule), recursively build each
sub-extension into ZIPs before assembling the outer package ZIP.
2026-06-26 19:26:54 -05:00
jmiller 1aaec7d8ff chore: sync repo-health.yml from Template-Generic [skip ci] 2026-06-25 19:45:44 +00:00
jmiller 5efdaf6c05 chore: sync pr-check.yml from Template-Generic [skip ci] 2026-06-25 19:45:42 +00:00
jmiller 448e11568b chore: sync ci-issue-reporter.yml from Template-Generic [skip ci] 2026-06-25 19:45:39 +00:00
jmiller dce0fe0994 feat: add ci_issue_reporter.sh CLI tool (moved from per-repo automation/) [skip ci] 2026-06-25 17:18:57 +00:00
Moko Consulting [bot] 2dc115327b fix: add PHP install step to workflow-sync-trigger for non-PHP runners [skip ci] 2026-06-25 17:08:36 +00:00
Moko Consulting [bot] 4715dba7fc fix: remove duplicate condition line in workflow-sync-trigger [skip ci] 2026-06-25 17:05:51 +00:00
Moko Consulting [bot] 5ab1782715 fix: allow workflow_dispatch to trigger sync job [skip ci] 2026-06-25 17:05:08 +00:00
Moko Consulting [bot] 08db79da17 fix: correct MOKOMOKOGITEA double prefix in workflow-sync-trigger [skip ci] 2026-06-25 17:03:25 +00:00
Moko Consulting [bot] c94564cec6 ci: add workflow_dispatch trigger to workflow-sync-trigger [skip ci] 2026-06-25 17:00:42 +00:00
Moko Consulting [bot] ac52a697e5 fix: standardize token/URL env vars to MOKOGITEA naming [skip ci] 2026-06-25 16:58:59 +00:00
Moko Consulting [bot] 57b458b79a fix: standardize token/URL env vars to MOKOGITEA naming [skip ci] 2026-06-25 16:58:05 +00:00
Moko Consulting [bot] 2a84b38194 fix: standardize token/URL env vars to MOKOGITEA naming [skip ci] 2026-06-25 16:58:01 +00:00
Moko Consulting [bot] 9d9b78b4e9 fix: standardize token/URL env vars to MOKOGITEA naming [skip ci] 2026-06-25 16:57:58 +00:00
Moko Consulting [bot] 092543db1c fix: standardize token/URL env vars to MOKOGITEA naming [skip ci] 2026-06-25 16:57:51 +00:00
Moko Consulting [bot] 2286514c59 fix: standardize token/URL env vars to MOKOGITEA naming [skip ci] 2026-06-25 16:57:47 +00:00
Moko Consulting [bot] 6993f30513 fix: standardize token/URL env vars to MOKOGITEA naming [skip ci] 2026-06-25 16:57:42 +00:00
Moko Consulting [bot] 0b30cc5a6d fix: standardize token/URL env vars to MOKOGITEA naming [skip ci] 2026-06-25 16:57:38 +00:00
Moko Consulting [bot] 7b0c239dd2 fix: standardize token/URL env vars to MOKOGITEA naming [skip ci] 2026-06-25 16:57:36 +00:00
Moko Consulting [bot] cf278cf914 fix: standardize token/URL env vars to MOKOGITEA naming [skip ci] 2026-06-25 16:57:33 +00:00
Moko Consulting [bot] fdeacc73c5 fix: standardize token/URL env vars to MOKOGITEA naming [skip ci] 2026-06-25 16:57:31 +00:00
Moko Consulting [bot] 117bba7765 fix: standardize token/URL env vars to MOKOGITEA naming [skip ci] 2026-06-25 16:57:21 +00:00
Moko Consulting [bot] 65a11a19ac fix: standardize token/URL env vars to MOKOGITEA naming [skip ci] 2026-06-25 16:57:16 +00:00
Moko Consulting [bot] fae2eab41b fix: rename GITEA_URL to MOKOGITEA_URL in workflow-sync-trigger [skip ci] 2026-06-25 16:49:06 +00:00
gitea-actions[bot] f91b05287a chore: promote changelog [Unreleased] → [09.41.00] 2026-06-25 16:48:26 +00:00
gitea-actions[bot] 43fd64a15b chore(release): build 09.41.00 [skip ci]
Publish to Composer / Publish Package (release) Successful in 11s
2026-06-25 16:48:23 +00:00
jmiller 15074fb0ae Merge pull request 'fix: remove dead $cleanupFile variable in release.php' (#320) from fix/release-dead-variable into main
Platform: mokocli CI / Gate 1: Code Quality (push) Failing after 59s
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (push) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: mokocli CI / CI Summary (push) Has been cancelled
2026-06-25 16:47:27 +00:00
jmiller 415b5403be fix: remove dead $cleanupFile variable in release.php
Universal: PR Check / Branch Policy (pull_request) Failing after 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 2s
Branch Cleanup / Delete merged branch (pull_request) Failing after 2s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Universal: PR Check / Validate PR (pull_request) Failing after 6s
Universal: PR Check / Secret Scan (pull_request) Successful in 8s
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Failing after 3s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Failing after 6s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Platform: mokocli CI / Gate 1: Code Quality (pull_request) Failing after 1m1s
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 24s
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokocli CI / CI Summary (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
Left behind when the cleanup template step was removed in #318.
2026-06-25 11:47:05 -05:00
jmiller 84fdb39d20 chore: sync issue-branch.yml from Template-Generic [skip ci] 2026-06-25 16:43:31 +00:00
gitea-actions[bot] 44b9e991b5 chore: promote changelog [Unreleased] → [09.41.00] 2026-06-25 16:43:24 +00:00
237 changed files with 4017 additions and 2473 deletions
+2 -2
View File
@@ -38,7 +38,7 @@ composer check # Run all checks
| `lib/Enterprise/Plugins/` | 11 platform plugins (Joomla, Dolibarr, Node.js, Python, etc.) | | `lib/Enterprise/Plugins/` | 11 platform plugins (Joomla, Dolibarr, Node.js, Python, etc.) |
| `deploy/` | SFTP deployment scripts (Joomla, Dolibarr, health checks) | | `deploy/` | SFTP deployment scripts (Joomla, Dolibarr, health checks) |
| `templates/` | Universal templates, configs, governance schema | | `templates/` | Universal templates, configs, governance schema |
| `.mokogitea/workflows/` | CI/CD workflows (Gitea Actions) | | `.mokogitea/workflows/` | CI/CD workflows (MokoGitea Actions) |
| `bin/moko` | Unified CLI dispatcher — `php bin/moko <command>` | | `bin/moko` | Unified CLI dispatcher — `php bin/moko <command>` |
| `monitoring/sites.json` | Sites list for mcp_mokomonitor | | `monitoring/sites.json` | Sites list for mcp_mokomonitor |
@@ -71,6 +71,6 @@ PHPStan runs with `--memory-limit=512M`. CI enforces PHPCS errors; PHPStan is `c
- **Never commit** `.claude/`, `.mcp.json`, `TODO.md`, `*.min.css`/`*.min.js` - **Never commit** `.claude/`, `.mcp.json`, `TODO.md`, `*.min.css`/`*.min.js`
- **Attribution**: `Authored-by: Moko Consulting` - **Attribution**: `Authored-by: Moko Consulting`
- **Workflow directory**: `.mokogitea/` (not `.gitea/` or `.github/`) - **Workflow directory**: `.mokogitea/` (not `.gitea/` or `.github/`)
- **Wiki**: documentation lives in the Gitea wiki, not `docs/` files - **Wiki**: documentation lives in the MokoGitea wiki, not `docs/` files
- **New CLI tools**: extend `CliFramework`, not `CLIApp` (legacy) - **New CLI tools**: extend `CliFramework`, not `CLIApp` (legacy)
- **Standards**: [MokoCli](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki/Home) - **Standards**: [MokoCli](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki/Home)
+18 -11
View File
@@ -124,7 +124,8 @@ jobs:
"rule_name": "main", "rule_name": "main",
"enable_push": true, "enable_push": true,
"enable_push_whitelist": true, "enable_push_whitelist": true,
"push_whitelist_usernames": ["jmiller"], "push_whitelist_usernames": ["jmiller", "moko-deploy"],
"push_whitelist_actions_user": true,
"enable_force_push": false, "enable_force_push": false,
"enable_force_push_allowlist": false, "enable_force_push_allowlist": false,
"force_push_allowlist_usernames": [], "force_push_allowlist_usernames": [],
@@ -140,10 +141,12 @@ jobs:
"rule_name": "dev", "rule_name": "dev",
"enable_push": true, "enable_push": true,
"enable_push_whitelist": true, "enable_push_whitelist": true,
"push_whitelist_usernames": ["jmiller"], "push_whitelist_usernames": ["jmiller", "moko-deploy"],
"enable_force_push": false, "push_whitelist_actions_user": true,
"enable_force_push_allowlist": false, "enable_force_push": true,
"force_push_allowlist_usernames": [], "enable_force_push_allowlist": true,
"force_push_allowlist_usernames": ["jmiller", "moko-deploy"],
"force_push_allowlist_actions_user": true,
"enable_merge_whitelist": false, "enable_merge_whitelist": false,
"required_approvals": 0, "required_approvals": 0,
"block_on_rejected_reviews": false, "block_on_rejected_reviews": false,
@@ -154,10 +157,12 @@ jobs:
"rule_name": "rc", "rule_name": "rc",
"enable_push": true, "enable_push": true,
"enable_push_whitelist": true, "enable_push_whitelist": true,
"push_whitelist_usernames": ["jmiller"], "push_whitelist_usernames": ["jmiller", "moko-deploy"],
"enable_force_push": false, "push_whitelist_actions_user": true,
"enable_force_push_allowlist": false, "enable_force_push": true,
"force_push_allowlist_usernames": [], "enable_force_push_allowlist": true,
"force_push_allowlist_usernames": ["jmiller", "moko-deploy"],
"force_push_allowlist_actions_user": true,
"enable_merge_whitelist": false, "enable_merge_whitelist": false,
"required_approvals": 0, "required_approvals": 0,
"block_on_rejected_reviews": false, "block_on_rejected_reviews": false,
@@ -168,7 +173,8 @@ jobs:
"rule_name": "beta", "rule_name": "beta",
"enable_push": true, "enable_push": true,
"enable_push_whitelist": true, "enable_push_whitelist": true,
"push_whitelist_usernames": ["jmiller"], "push_whitelist_usernames": ["jmiller", "moko-deploy"],
"push_whitelist_actions_user": true,
"enable_force_push": false, "enable_force_push": false,
"enable_force_push_allowlist": false, "enable_force_push_allowlist": false,
"force_push_allowlist_usernames": [], "force_push_allowlist_usernames": [],
@@ -182,7 +188,8 @@ jobs:
"rule_name": "alpha", "rule_name": "alpha",
"enable_push": true, "enable_push": true,
"enable_push_whitelist": true, "enable_push_whitelist": true,
"push_whitelist_usernames": ["jmiller"], "push_whitelist_usernames": ["jmiller", "moko-deploy"],
"push_whitelist_actions_user": true,
"enable_force_push": false, "enable_force_push": false,
"enable_force_push_allowlist": false, "enable_force_push_allowlist": false,
"force_push_allowlist_usernames": [], "force_push_allowlist_usernames": [],
+67 -66
View File
@@ -1,66 +1,67 @@
# 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: MokoGitea.Workflow
# INGROUP: mokocli.Release # INGROUP: mokocli.Release
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli # REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
# PATH: /.mokogitea/workflows/auto-bump.yml # PATH: /.mokogitea/workflows/auto-bump.yml
# VERSION: 09.02.00 # VERSION: 09.02.00
# BRIEF: Auto patch-bump version on every push to dev (skips merge commits) # BRIEF: Auto patch-bump version on every push to dev (skips merge commits)
name: "Universal: Auto Version Bump" name: "Universal: Auto Version Bump"
on: on:
push: push:
branches: branches:
- dev - dev
- rc - rc
- 'feature/**' - 'feature/**'
- 'patch/**' - 'patch/**'
env: env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
permissions: permissions:
contents: write contents: write
jobs: jobs:
bump: bump:
name: Version Bump name: Version Bump
runs-on: release runs-on: release
if: >- if: >-
!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[skip ci]') &&
!contains(github.event.head_commit.message, '[skip bump]') && !contains(github.event.head_commit.message, '[skip bump]') &&
!startsWith(github.event.head_commit.message, 'Merge pull request') !startsWith(github.event.head_commit.message, 'Merge pull request') &&
!startsWith(github.event.repository.name, 'Template-')
steps:
- name: Checkout steps:
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Checkout
with: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
token: ${{ secrets.MOKOGITEA_TOKEN }} with:
fetch-depth: 1 token: ${{ secrets.MOKOGITEA_TOKEN }}
fetch-depth: 1
- name: Setup mokocli tools
run: | - name: Setup mokocli tools
if ! command -v composer &> /dev/null; then run: |
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 ! command -v composer &> /dev/null; then
fi 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 [ -d "/opt/mokocli/cli" ]; then fi
echo "MOKO_CLI=/opt/mokocli/cli" >> "$GITHUB_ENV" if [ -d "/opt/mokocli/cli" ]; then
else echo "MOKO_CLI=/opt/mokocli/cli" >> "$GITHUB_ENV"
git clone --depth 1 --branch main --quiet \ else
"https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/mokocli.git" \ git clone --depth 1 --branch main --quiet \
/tmp/mokocli "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/MokoCLI.git" \
cd /tmp/mokocli && composer install --no-dev --no-interaction --quiet /tmp/mokocli
echo "MOKO_CLI=/tmp/mokocli/cli" >> "$GITHUB_ENV" cd /tmp/mokocli && composer install --no-dev --no-interaction --quiet
fi echo "MOKO_CLI=/tmp/mokocli/cli" >> "$GITHUB_ENV"
fi
- name: Bump version
run: | - name: Bump version
php ${MOKO_CLI}/version_auto_bump.php \ run: |
--path . --branch "${GITHUB_REF_NAME}" \ php ${MOKO_CLI}/version_auto_bump.php \
--token "${{ secrets.MOKOGITEA_TOKEN }}" \ --path . --branch "${GITHUB_REF_NAME}" \
--repo-url "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" --token "${{ secrets.MOKOGITEA_TOKEN }}" \
--repo-url "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
+497 -467
View File
@@ -1,467 +1,497 @@
# 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: MokoGitea.Workflow
# INGROUP: mokocli.Release # INGROUP: mokocli.Release
# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli # REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
# PATH: /templates/workflows/universal/auto-release.yml.template # PATH: /.mokogitea/workflows/auto-release.yml
# VERSION: 05.00.00 # VERSION: 05.01.00
# BRIEF: Universal build & release detects platform from manifest.xml # BRIEF: Universal build & release detects platform from manifest.xml
# #
# +=======================================================================+ # +=======================================================================+
# | UNIVERSAL BUILD & RELEASE PIPELINE | # | UNIVERSAL BUILD & RELEASE PIPELINE |
# +=======================================================================+ # +=======================================================================+
# | | # | |
# | 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, 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 |
# | | # | |
# +=======================================================================+ # +=======================================================================+
name: "Universal: Build & Release" name: "Universal: Build & Release"
on: on:
pull_request: pull_request:
types: [opened, synchronize, closed] types: [opened, synchronize, closed]
branches: branches:
- main - main
paths-ignore: paths-ignore:
- '.mokogitea/workflows/**' - '.mokogitea/workflows/**'
- '*.md' - '*.md'
- 'wiki/**' - 'wiki/**'
- '.editorconfig' - '.editorconfig'
- '.gitignore' - '.gitignore'
- '.gitattributes' - '.gitattributes'
- '.gitmessage' - '.gitmessage'
- 'LICENSE' - 'LICENSE'
workflow_dispatch: workflow_dispatch:
inputs: inputs:
action: action:
description: 'Action to perform' description: 'Action to perform'
required: false required: false
type: choice type: choice
default: release default: release
options: options:
- release - release
- promote-rc - promote-rc
env: env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} MOKOGITEA_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 }}
permissions: permissions:
contents: write contents: write
jobs: jobs:
# ── PR Opened → Rename branch to RC and build RC release ───────────────────────── # ── PR Opened → Rename branch to RC and build RC release ─────────────────────────
promote-rc: promote-rc:
name: Promote to RC name: Promote to RC
runs-on: release runs-on: release
if: >- # Skip on template repos (Template-*) — they scaffold other repos and do not release.
(github.event.action == 'opened' && github.event.pull_request.merged != true) || if: >-
(github.event.action == 'synchronize' && github.event.pull_request.merged != true) || !startsWith(github.event.repository.name, 'Template-') &&
(github.event_name == 'workflow_dispatch' && inputs.action == 'promote-rc') (
(github.event.action == 'opened' && github.event.pull_request.merged != true) ||
steps: (github.event.action == 'synchronize' && github.event.pull_request.merged != true) ||
- name: Checkout repository (github.event_name == 'workflow_dispatch' && inputs.action == 'promote-rc')
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 )
with:
token: ${{ secrets.MOKOGITEA_TOKEN }} steps:
fetch-depth: 1 - name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Setup mokocli tools with:
env: token: ${{ secrets.MOKOGITEA_TOKEN }}
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} fetch-depth: 1
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting submodules: recursive
run: |
if [ -f /opt/mokocli/cli/version_bump.php ] && [ -f /opt/mokocli/vendor/autoload.php ]; then - name: Setup mokocli tools
echo Using pre-installed /opt/mokocli env:
echo MOKO_CLI=/opt/mokocli/cli >> $GITHUB_ENV MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
else MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
echo Falling back to fresh clone run: |
if ! command -v composer > /dev/null 2>&1; then if [ -f /opt/mokocli/cli/version_bump.php ] && [ -f /opt/mokocli/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/mokocli
fi echo MOKO_CLI=/opt/mokocli/cli >> $GITHUB_ENV
rm -rf /tmp/mokocli else
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git echo Falling back to fresh clone
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli if ! command -v composer > /dev/null 2>&1; then
cd /tmp/mokocli 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
composer install --no-dev --no-interaction --quiet fi
echo MOKO_CLI=/tmp/mokocli/cli >> $GITHUB_ENV rm -rf /tmp/mokocli
fi 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
- name: Rename branch to rc cd /tmp/mokocli
run: | composer install --no-dev --no-interaction --quiet
php ${MOKO_CLI}/branch_rename.php \ echo MOKO_CLI=/tmp/mokocli/cli >> $GITHUB_ENV
--from "${{ github.event.pull_request.head.ref || 'dev' }}" --to rc \ fi
--token "${{ secrets.MOKOGITEA_TOKEN }}" \
--api-base "${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" \ - name: Rename branch to rc
--pr "${{ github.event.pull_request.number }}" run: |
API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
- name: Checkout rc and configure git AUTH="Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}"
run: | FROM="${{ github.event.pull_request.head.ref || 'dev' }}"
git fetch origin rc PR="${{ github.event.pull_request.number }}"
git checkout rc
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" # Resolve the source branch HEAD commit.
git config --local user.name "gitea-actions[bot]" SRC_JSON=$(curl -sf -H "$AUTH" "${API_BASE}/branches/${FROM}") \
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" || { echo "::error::Source branch ${FROM} not found"; exit 1; }
SRC_SHA=$(printf '%s' "$SRC_JSON" | python3 -c "import sys, json; print(json.load(sys.stdin)['commit']['id'])" 2>/dev/null || true)
- name: Publish RC release [ -n "$SRC_SHA" ] || { echo "::error::Could not resolve HEAD of ${FROM}"; exit 1; }
run: |
php ${MOKO_CLI}/release_publish.php \ # Point rc at the source commit. If rc already exists (a protected branch that
--path . --stability rc --bump minor --branch rc \ # cannot be deleted), force-update its ref in place instead of delete+recreate:
--token "${{ secrets.MOKOGITEA_TOKEN }}" # deleting a protected branch fails, which then makes the recreate return HTTP 409.
if curl -sf -o /dev/null -H "$AUTH" "${API_BASE}/branches/rc"; then
- name: Update RC release notes from CHANGELOG.md echo "rc exists - force-updating to ${FROM} (${SRC_SHA})"
run: | curl -sf -X PATCH -H "$AUTH" -H "Content-Type: application/json" \
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" "${API_BASE}/git/refs/heads/rc" -d "{\"sha\":\"${SRC_SHA}\",\"force\":true}" \
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" || { echo "::error::Failed to force-update rc (CI token needs force-push on the protected rc branch)"; exit 1; }
else
# Extract [Unreleased] section from changelog echo "Creating rc from ${FROM}"
NOTES="" curl -sf -X POST -H "$AUTH" -H "Content-Type: application/json" \
if [ -f "CHANGELOG.md" ]; then "${API_BASE}/branches" -d "{\"new_branch_name\":\"rc\",\"old_branch_name\":\"${FROM}\"}" \
NOTES=$(awk '/^## \[Unreleased\]/{found=1; next} /^## \[/{if(found) exit} found{print}' CHANGELOG.md) || { echo "::error::Failed to create rc from ${FROM}"; exit 1; }
fi fi
[ -z "$NOTES" ] && NOTES="Release candidate"
# Repoint the PR at rc, then delete the old source branch (non-fatal).
# Find the RC release and update its body if [ -n "$PR" ]; then
RELEASE_ID=$(curl -sf -H "Authorization: token ${TOKEN}" \ curl -s -X PATCH -H "$AUTH" -H "Content-Type: application/json" \
"${API_BASE}/releases/tags/release-candidate" \ "${API_BASE}/pulls/${PR}" -d '{"head":"rc"}' >/dev/null || true
| python3 -c "import json,sys; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true) fi
curl -s -X DELETE -H "$AUTH" "${API_BASE}/branches/${FROM}" >/dev/null || true
if [ -n "$RELEASE_ID" ]; then echo "Renamed ${FROM} -> rc"
python3 -c "
import json, urllib.request - name: Checkout rc and configure git
body = open('/dev/stdin').read() run: |
payload = json.dumps({'body': body}).encode() git fetch origin rc
req = urllib.request.Request( git checkout rc
'${API_BASE}/releases/${RELEASE_ID}', git config --local user.email "mokogitea-actions[bot]@mokoconsulting.tech"
data=payload, method='PATCH', git config --local user.name "mokogitea-actions[bot]"
headers={ git remote set-url origin "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
'Authorization': 'token ${TOKEN}',
'Content-Type': 'application/json' - name: Publish RC release
}) run: |
urllib.request.urlopen(req) php ${MOKO_CLI}/release_publish.php \
" <<< "$NOTES" --path . --stability rc --bump minor --branch rc \
echo "RC release notes updated from CHANGELOG.md" --token "${{ secrets.MOKOGITEA_TOKEN }}"
fi
- name: Update RC release notes from CHANGELOG.md
- name: Summary run: |
if: always() API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
run: | TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
echo "## Promoted to Release Candidate" >> $GITHUB_STEP_SUMMARY
echo "Branch renamed to rc, minor bump, RC release built" >> $GITHUB_STEP_SUMMARY # Extract [Unreleased] section from changelog
NOTES=""
# ── Merged PR → Build & Release (or promote RC to stable) ───────────────────────── if [ -f "CHANGELOG.md" ]; then
release: NOTES=$(awk '/^## \[Unreleased\]/{found=1; next} /^## \[/{if(found) exit} found{print}' CHANGELOG.md)
name: Build & Release Pipeline fi
runs-on: release [ -z "$NOTES" ] && NOTES="Release candidate"
if: >-
github.event.pull_request.merged == true || # Find the RC release and update its body
(github.event_name == 'workflow_dispatch' && inputs.action != 'promote-rc') RELEASE_ID=$(curl -sf -H "Authorization: token ${TOKEN}" \
"${API_BASE}/releases/tags/release-candidate" \
steps: | python3 -c "import json,sys; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true)
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 if [ -n "$RELEASE_ID" ]; then
with: python3 -c "
token: ${{ secrets.MOKOGITEA_TOKEN }} import json, urllib.request
fetch-depth: 0 body = open('/dev/stdin').read()
payload = json.dumps({'body': body}).encode()
- name: Configure git for bot pushes req = urllib.request.Request(
run: | '${API_BASE}/releases/${RELEASE_ID}',
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" data=payload, method='PATCH',
git config --local user.name "gitea-actions[bot]" headers={
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" 'Authorization': 'token ${TOKEN}',
'Content-Type': 'application/json'
- name: Check for merge conflict markers })
run: | urllib.request.urlopen(req)
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) " <<< "$NOTES"
if [ -n "$CONFLICTS" ]; then echo "RC release notes updated from CHANGELOG.md"
echo "::error::Merge conflict markers found — aborting release" fi
echo "## Release Blocked: Conflict Markers" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY - name: Summary
echo "$CONFLICTS" >> $GITHUB_STEP_SUMMARY if: always()
echo '```' >> $GITHUB_STEP_SUMMARY run: |
exit 1 echo "## Promoted to Release Candidate" >> $GITHUB_STEP_SUMMARY
fi echo "Branch renamed to rc, minor bump, RC release built" >> $GITHUB_STEP_SUMMARY
echo "No conflict markers found"
# ── Merged PR → Build & Release (or promote RC to stable) ─────────────────────────
- name: Setup mokocli tools release:
env: name: Build & Release Pipeline
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} runs-on: release
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting # Skip on template repos (Template-*) — they scaffold other repos and do not release.
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_MIRROR_TOKEN }}"}}' if: >-
run: | !startsWith(github.event.repository.name, 'Template-') &&
if [ -f /opt/mokocli/cli/version_bump.php ] && [ -f /opt/mokocli/vendor/autoload.php ]; then (
echo Using pre-installed /opt/mokocli github.event.pull_request.merged == true ||
echo MOKO_CLI=/opt/mokocli/cli >> $GITHUB_ENV (github.event_name == 'workflow_dispatch' && inputs.action != 'promote-rc')
else )
echo Falling back to fresh clone
if ! command -v composer > /dev/null 2>&1; then steps:
sudo apt-get update -qq && sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer > /dev/null 2>&1 - name: Checkout repository
fi uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
rm -rf /tmp/mokocli with:
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git token: ${{ secrets.MOKOGITEA_TOKEN }}
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli fetch-depth: 0
cd /tmp/mokocli submodules: recursive
composer install --no-dev --no-interaction --quiet
echo MOKO_CLI=/tmp/mokocli/cli >> $GITHUB_ENV - name: Configure git for bot pushes
fi run: |
git config --local user.email "mokogitea-actions[bot]@mokoconsulting.tech"
- name: "Detect platform" git config --local user.name "mokogitea-actions[bot]"
id: platform git remote set-url origin "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
run: |
php ${MOKO_CLI}/platform_detect.php --path . --github-output 2>/dev/null || true - name: Check for merge conflict markers
php ${MOKO_CLI}/manifest_read.php --path . --github-output 2>/dev/null || true 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)
- name: "Determine version bump level" if [ -n "$CONFLICTS" ]; then
id: bump echo "::error::Merge conflict markers found — aborting release"
run: | echo "## Release Blocked: Conflict Markers" >> $GITHUB_STEP_SUMMARY
# Fix/patch branches: version was already bumped by pre-release, just strip suffix echo '```' >> $GITHUB_STEP_SUMMARY
# Feature/dev branches: bump minor for the new stable release echo "$CONFLICTS" >> $GITHUB_STEP_SUMMARY
HEAD_REF="${{ github.event.pull_request.head.ref || 'dev' }}" echo '```' >> $GITHUB_STEP_SUMMARY
case "$HEAD_REF" in exit 1
fix/*|patch/*|hotfix/*|bugfix/*) BUMP="none" ;; fi
*) BUMP="minor" ;; echo "No conflict markers found"
esac
echo "level=${BUMP}" >> "$GITHUB_OUTPUT" - name: Setup mokocli tools
echo "Bump level: ${BUMP} (from branch: ${HEAD_REF})" env:
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
- name: "Publish stable release" MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
run: | COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_MIRROR_TOKEN }}"}}'
BUMP_FLAG="" run: |
if [ "${{ steps.bump.outputs.level }}" != "none" ]; then if [ -f /opt/mokocli/cli/version_bump.php ] && [ -f /opt/mokocli/vendor/autoload.php ]; then
BUMP_FLAG="--bump ${{ steps.bump.outputs.level }}" echo Using pre-installed /opt/mokocli
fi echo MOKO_CLI=/opt/mokocli/cli >> $GITHUB_ENV
php ${MOKO_CLI}/release_publish.php \ else
--path . --stability stable ${BUMP_FLAG} --branch main \ echo Falling back to fresh clone
--token "${{ secrets.MOKOGITEA_TOKEN }}" 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
- name: "Read published version" fi
id: version rm -rf /tmp/mokocli
run: | CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/MokoCLI.git
VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null || echo "") git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
VERSION=$(echo "$VERSION" | sed 's/-\(dev\|alpha\|beta\|rc\)$//') cd /tmp/mokocli
[ -z "$VERSION" ] && VERSION="00.00.00" && echo "skip=true" >> "$GITHUB_OUTPUT" composer install --no-dev --no-interaction --quiet
echo "version=${VERSION}" >> "$GITHUB_OUTPUT" echo MOKO_CLI=/tmp/mokocli/cli >> $GITHUB_ENV
PLATFORM="${{ steps.platform.outputs.platform }}" fi
if [[ "$PLATFORM" == joomla* ]]; then
echo "tag=stable" >> "$GITHUB_OUTPUT" - name: "Detect platform"
echo "release_tag=stable" >> "$GITHUB_OUTPUT" id: platform
else run: |
echo "tag=v${VERSION}" >> "$GITHUB_OUTPUT" php ${MOKO_CLI}/platform_detect.php --path . --github-output 2>/dev/null || true
echo "release_tag=v${VERSION}" >> "$GITHUB_OUTPUT" php ${MOKO_CLI}/manifest_read.php --path . --github-output 2>/dev/null || true
fi
echo "branch=main" >> "$GITHUB_OUTPUT" - name: "Determine version bump level"
echo "Published version: ${VERSION}" id: bump
run: |
- name: "Create semver tag for non-Joomla repos" # Fix/patch branches: version was already bumped by pre-release, just strip suffix
id: semver # Feature/dev branches: bump minor for the new stable release
if: | HEAD_REF="${{ github.event.pull_request.head.ref || 'dev' }}"
steps.version.outputs.skip != 'true' && case "$HEAD_REF" in
!startsWith(steps.platform.outputs.platform, 'joomla') fix/*|patch/*|hotfix/*|bugfix/*) BUMP="none" ;;
run: | *) BUMP="minor" ;;
VERSION="${{ steps.version.outputs.version }}" esac
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" echo "level=${BUMP}" >> "$GITHUB_OUTPUT"
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" echo "Bump level: ${BUMP} (from branch: ${HEAD_REF})"
SEMVER_TAG="v${VERSION}"
- name: "Publish stable release"
echo "Creating semver tag: ${SEMVER_TAG}" run: |
BUMP_FLAG=""
# Create the git tag via API if [ "${{ steps.bump.outputs.level }}" != "none" ]; then
HTTP_CODE=$(curl -sf -o /dev/null -w "%{http_code}" \ BUMP_FLAG="--bump ${{ steps.bump.outputs.level }}"
-X POST -H "Authorization: token ${TOKEN}" \ fi
-H "Content-Type: application/json" \ php ${MOKO_CLI}/release_publish.php \
"${API_BASE}/tags" \ --path . --stability stable ${BUMP_FLAG} --branch main \
-d "{\"tag_name\":\"${SEMVER_TAG}\",\"target\":\"main\",\"message\":\"Release ${VERSION}\"}" 2>/dev/null || echo "000") --token "${{ secrets.MOKOGITEA_TOKEN }}"
if [ "$HTTP_CODE" = "201" ] || [ "$HTTP_CODE" = "200" ]; then - name: "Read published version"
echo "Created semver tag: ${SEMVER_TAG}" id: version
elif [ "$HTTP_CODE" = "409" ]; then run: |
echo "Semver tag ${SEMVER_TAG} already exists (skipped)" VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null || echo "")
else VERSION=$(echo "$VERSION" | sed 's/-\(dev\|alpha\|beta\|rc\)$//')
echo "::warning::Failed to create semver tag ${SEMVER_TAG} (HTTP ${HTTP_CODE})" [ -z "$VERSION" ] && VERSION="00.00.00" && echo "skip=true" >> "$GITHUB_OUTPUT"
fi echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
PLATFORM="${{ steps.platform.outputs.platform }}"
echo "semver_tag=${SEMVER_TAG}" >> "$GITHUB_OUTPUT" if [[ "$PLATFORM" == joomla* ]]; then
echo "tag=stable" >> "$GITHUB_OUTPUT"
- name: Update release notes and promote changelog echo "release_tag=stable" >> "$GITHUB_OUTPUT"
run: | else
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" echo "tag=v${VERSION}" >> "$GITHUB_OUTPUT"
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" echo "release_tag=v${VERSION}" >> "$GITHUB_OUTPUT"
fi
# Get the stable release info (version and ID) echo "branch=main" >> "$GITHUB_OUTPUT"
RELEASE_JSON=$(curl -sf -H "Authorization: token ${TOKEN}" \ echo "Published version: ${VERSION}"
"${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) - name: "Create semver tag for non-Joomla repos"
# Extract version from release name (e.g. "06.17.00" or "v06.17.00") id: semver
VERSION=$(python3 -c " if: |
import json, sys, re steps.version.outputs.skip != 'true' &&
r = json.load(sys.stdin) !startsWith(steps.platform.outputs.platform, 'joomla')
name = r.get('name', '') run: |
m = re.search(r'(\d+\.\d+\.\d+)', name) VERSION="${{ steps.version.outputs.version }}"
print(m.group(1) if m else '') API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
" <<< "$RELEASE_JSON" 2>/dev/null || true) TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
SEMVER_TAG="v${VERSION}"
# Extract [Unreleased] section from changelog
NOTES="" echo "Creating semver tag: ${SEMVER_TAG}"
if [ -f "CHANGELOG.md" ]; then
NOTES=$(awk '/^## \[Unreleased\]/{found=1; next} /^## \[/{if(found) exit} found{print}' CHANGELOG.md) # Create the git tag via API
fi HTTP_CODE=$(curl -sf -o /dev/null -w "%{http_code}" \
[ -z "$NOTES" ] && NOTES="Stable release" -X POST -H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \
# Update release body via API "${API_BASE}/tags" \
if [ -n "$RELEASE_ID" ]; then -d "{\"tag_name\":\"${SEMVER_TAG}\",\"target\":\"main\",\"message\":\"Release ${VERSION}\"}" 2>/dev/null || echo "000")
python3 -c "
import json, urllib.request if [ "$HTTP_CODE" = "201" ] || [ "$HTTP_CODE" = "200" ]; then
body = open('/dev/stdin').read() echo "Created semver tag: ${SEMVER_TAG}"
payload = json.dumps({'body': body}).encode() elif [ "$HTTP_CODE" = "409" ]; then
req = urllib.request.Request( echo "Semver tag ${SEMVER_TAG} already exists (skipped)"
'${API_BASE}/releases/${RELEASE_ID}', else
data=payload, method='PATCH', echo "::warning::Failed to create semver tag ${SEMVER_TAG} (HTTP ${HTTP_CODE})"
headers={ fi
'Authorization': 'token ${TOKEN}',
'Content-Type': 'application/json' echo "semver_tag=${SEMVER_TAG}" >> "$GITHUB_OUTPUT"
})
urllib.request.urlopen(req) - name: Update release notes and promote changelog
" <<< "$NOTES" run: |
echo "Release notes updated from CHANGELOG.md" API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
fi TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
# Promote [Unreleased] → [version] in CHANGELOG.md and reset # Get the stable release info (version and ID)
if [ -n "$VERSION" ] && [ -f "CHANGELOG.md" ]; then RELEASE_JSON=$(curl -sf -H "Authorization: token ${TOKEN}" \
DATE=$(date +%Y-%m-%d) "${API_BASE}/releases/tags/stable" 2>/dev/null || echo '{}')
python3 -c " RELEASE_ID=$(python3 -c "import json,sys; print(json.load(sys.stdin).get('id',''))" <<< "$RELEASE_JSON" 2>/dev/null || true)
import sys # Extract version from release name (e.g. "06.17.00" or "v06.17.00")
version, date = sys.argv[1], sys.argv[2] VERSION=$(python3 -c "
content = open('CHANGELOG.md').read() import json, sys, re
old = '## [Unreleased]' r = json.load(sys.stdin)
new = f'## [Unreleased]\n\n## [{version}] --- {date}' name = r.get('name', '')
content = content.replace(old, new, 1) m = re.search(r'(\d+\.\d+\.\d+)', name)
open('CHANGELOG.md', 'w').write(content) print(m.group(1) if m else '')
" "$VERSION" "$DATE" " <<< "$RELEASE_JSON" 2>/dev/null || true)
git add CHANGELOG.md
git commit -m "chore: promote changelog [Unreleased] → [${VERSION}]" || true # Extract [Unreleased] section from changelog
git push origin main || true NOTES=""
echo "Changelog promoted: [Unreleased] → [${VERSION}]" if [ -f "CHANGELOG.md" ]; then
fi NOTES=$(awk '/^## \[Unreleased\]/{found=1; next} /^## \[/{if(found) exit} found{print}' CHANGELOG.md)
fi
# -- STEP 9: Mirror to GitHub (stable only) -------------------------------- [ -z "$NOTES" ] && NOTES="Stable release"
- name: "Step 9: Mirror release to GitHub"
if: >- # Update release body via API
steps.version.outputs.skip != 'true' && if [ -n "$RELEASE_ID" ]; then
secrets.GH_MIRROR_TOKEN != '' python3 -c "
continue-on-error: true import json, urllib.request
run: | body = open('/dev/stdin').read()
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" payload = json.dumps({'body': body}).encode()
RELEASE_TAG="${{ steps.version.outputs.release_tag }}" req = urllib.request.Request(
GH_REPO="${{ vars.GH_MIRROR_REPO || github.repository }}" '${API_BASE}/releases/${RELEASE_ID}',
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" data=payload, method='PATCH',
php ${MOKO_CLI}/release_mirror.php \ headers={
--version "$VERSION" --tag "$RELEASE_TAG" \ 'Authorization': 'token ${TOKEN}',
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \ 'Content-Type': 'application/json'
--gh-token "${{ secrets.GH_MIRROR_TOKEN }}" --gh-repo "$GH_REPO" \ })
--branch main 2>&1 || true urllib.request.urlopen(req)
echo "GitHub mirror updated" >> $GITHUB_STEP_SUMMARY " <<< "$NOTES"
echo "Release notes updated from CHANGELOG.md"
# -- STEP 10: Sync main branch to GitHub mirror ---------------------------- fi
- name: "Step 10: Push main to GitHub mirror"
if: >- # Promote [Unreleased] → [version] in CHANGELOG.md and reset
steps.version.outputs.skip != 'true' && if [ -n "$VERSION" ] && [ -f "CHANGELOG.md" ]; then
secrets.GH_MIRROR_TOKEN != '' DATE=$(date +%Y-%m-%d)
continue-on-error: true python3 -c "
run: | import sys
GH_REPO="${{ vars.GH_MIRROR_REPO || github.repository }}" version, date = sys.argv[1], sys.argv[2]
GH_ORG=$(echo "$GH_REPO" | cut -d/ -f1) content = open('CHANGELOG.md').read()
GH_NAME=$(echo "$GH_REPO" | cut -d/ -f2) old = '## [Unreleased]'
git remote add github "https://x-access-token:${{ secrets.GH_MIRROR_TOKEN }}@github.com/${GH_ORG}/${GH_NAME}.git" 2>/dev/null || \ new = f'## [Unreleased]\n\n## [{version}] --- {date}'
git remote set-url github "https://x-access-token:${{ secrets.GH_MIRROR_TOKEN }}@github.com/${GH_ORG}/${GH_NAME}.git" content = content.replace(old, new, 1)
git fetch origin main --depth=1 open('CHANGELOG.md', 'w').write(content)
git push github origin/main:refs/heads/main --force 2>/dev/null \ " "$VERSION" "$DATE"
&& echo "main branch pushed to GitHub mirror" \ git add CHANGELOG.md
|| echo "WARNING: GitHub mirror push failed" git commit -m "chore: promote changelog [Unreleased] → [${VERSION}]" || true
git push origin main || true
- name: "Step 11: Delete rc branch and recreate dev from main" echo "Changelog promoted: [Unreleased] → [${VERSION}]"
if: steps.version.outputs.skip != 'true' fi
continue-on-error: true
run: | # -- STEP 9: Mirror to GitHub (stable only) --------------------------------
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" - name: "Step 9: Mirror release to GitHub"
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" if: >-
steps.version.outputs.skip != 'true' &&
# Delete rc branch (ephemeral — created by promote-rc) secrets.GH_MIRROR_TOKEN != ''
curl -sf -X DELETE -H "Authorization: token ${TOKEN}" \ continue-on-error: true
"${API_BASE}/branches/rc" 2>/dev/null \ run: |
&& echo "Deleted rc branch" || echo "rc branch not found" VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}"
RELEASE_TAG="${{ steps.version.outputs.release_tag }}"
# Delete dev branch GH_REPO="${{ vars.GH_MIRROR_REPO || github.repository }}"
curl -sf -X DELETE -H "Authorization: token ${TOKEN}" \ API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
"${API_BASE}/branches/dev" 2>/dev/null && echo "Deleted dev branch" php ${MOKO_CLI}/release_mirror.php \
--version "$VERSION" --tag "$RELEASE_TAG" \
# Recreate dev from main (now includes version bump + changelog promotion) --token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \
curl -sf -X POST -H "Authorization: token ${TOKEN}" \ --gh-token "${{ secrets.GH_MIRROR_TOKEN }}" --gh-repo "$GH_REPO" \
-H "Content-Type: application/json" \ --branch main 2>&1 || true
"${API_BASE}/branches" \ echo "GitHub mirror updated" >> $GITHUB_STEP_SUMMARY
-d '{"new_branch_name":"dev","old_branch_name":"main"}' 2>/dev/null && echo "Recreated dev from main"
# -- STEP 10: Sync main branch to GitHub mirror ----------------------------
echo "Pre-release branches cleaned, dev reset from main" >> $GITHUB_STEP_SUMMARY - name: "Step 10: Push main to GitHub mirror"
if: >-
- name: "Step 12: Create version branch from main" steps.version.outputs.skip != 'true' &&
if: steps.version.outputs.skip != 'true' secrets.GH_MIRROR_TOKEN != ''
continue-on-error: true continue-on-error: true
run: | run: |
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}" GH_REPO="${{ vars.GH_MIRROR_REPO || github.repository }}"
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}" GH_ORG=$(echo "$GH_REPO" | cut -d/ -f1)
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" GH_NAME=$(echo "$GH_REPO" | cut -d/ -f2)
BRANCH_NAME="version/${VERSION}" git remote add github "https://x-access-token:${{ secrets.GH_MIRROR_TOKEN }}@github.com/${GH_ORG}/${GH_NAME}.git" 2>/dev/null || \
MAIN_SHA=$(git rev-parse HEAD) 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
# Delete old version branch if it exists (same version re-release) git push github origin/main:refs/heads/main --force 2>/dev/null \
curl -sf -X DELETE -H "Authorization: token ${TOKEN}" "${API_BASE}/branches/${BRANCH_NAME}" 2>/dev/null && echo "Deleted old ${BRANCH_NAME}" && echo "main branch pushed to GitHub mirror" \
|| echo "WARNING: GitHub mirror push failed"
# 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" - name: "Step 11: Delete rc branch (dev reset moved to cascade-dev.yml)"
if: steps.version.outputs.skip != 'true'
echo "Version branch created: ${BRANCH_NAME} (${MAIN_SHA})" >> $GITHUB_STEP_SUMMARY continue-on-error: true
run: |
API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
# -- Dolibarr post-release: Reset dev version -----------------------------
- name: "Post-release: Reset dev version" # Delete rc branch (ephemeral — created by promote-rc)
if: steps.version.outputs.skip != 'true' curl -sf -X DELETE -H "Authorization: token ${TOKEN}" \
continue-on-error: true "${API_BASE}/branches/rc" 2>/dev/null \
run: | && echo "Deleted rc branch" || echo "rc branch not found"
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
php ${MOKO_CLI}/version_reset_dev.php \ # dev is reset from main by the dedicated "Cascade Main -> Dev" workflow
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "${API_BASE}" \ # (cascade-dev.yml), which runs after this release completes.
--branch dev --path . 2>&1 || true echo "rc cleaned; dev reset handled by cascade-dev.yml" >> $GITHUB_STEP_SUMMARY
# -- Summary -------------------------------------------------------------- - name: "Step 12: Create version branch from main"
- name: Pipeline Summary if: steps.version.outputs.skip != 'true'
if: always() continue-on-error: true
run: | run: |
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}" API_BASE="${MOKOGITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
PLATFORM="${{ steps.platform.outputs.platform }}" TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
if [ "${{ steps.version.outputs.skip }}" = "true" ]; then VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}"
echo "## Release Skipped" >> $GITHUB_STEP_SUMMARY BRANCH_NAME="version/${VERSION}"
echo "No VERSION in README.md" >> $GITHUB_STEP_SUMMARY MAIN_SHA=$(git rev-parse HEAD)
elif [ "${{ steps.check.outputs.already_released }}" = "true" ]; then
echo "## Already Released — ${VERSION}" >> $GITHUB_STEP_SUMMARY # Delete old version branch if it exists (same version re-release)
else curl -sf -X DELETE -H "Authorization: token ${TOKEN}" "${API_BASE}/branches/${BRANCH_NAME}" 2>/dev/null && echo "Deleted old ${BRANCH_NAME}"
echo "" >> $GITHUB_STEP_SUMMARY
echo "## Build & Release Complete (${PLATFORM})" >> $GITHUB_STEP_SUMMARY # Create version/XX.YY.ZZ from main
echo "" >> $GITHUB_STEP_SUMMARY 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 "| Step | Result |" >> $GITHUB_STEP_SUMMARY
echo "|------|--------|" >> $GITHUB_STEP_SUMMARY echo "Version branch created: ${BRANCH_NAME} (${MAIN_SHA})" >> $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 # -- Dolibarr post-release: Reset dev version -----------------------------
echo "| Release | [View](${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/tag/${{ steps.version.outputs.tag }}) |" >> $GITHUB_STEP_SUMMARY - name: "Post-release: Reset dev version"
fi if: steps.version.outputs.skip != 'true'
continue-on-error: true
run: |
API_BASE="${MOKOGITEA_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](${MOKOGITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/tag/${{ steps.version.outputs.tag }}) |" >> $GITHUB_STEP_SUMMARY
fi
+4 -3
View File
@@ -3,9 +3,9 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
# #
# FILE INFORMATION # FILE INFORMATION
# DEFGROUP: Gitea.Workflow # DEFGROUP: MokoGitea.Workflow
# INGROUP: MokoStandards.Universal # INGROUP: MokoStandards.Universal
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli # REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
# PATH: /.mokogitea/workflows/branch-cleanup.yml # PATH: /.mokogitea/workflows/branch-cleanup.yml
# VERSION: 01.00.00 # VERSION: 01.00.00
# BRIEF: Delete feature branches after PR merge # BRIEF: Delete feature branches after PR merge
@@ -33,7 +33,8 @@ jobs:
run: | run: |
BRANCH="${{ github.event.pull_request.head.ref }}" BRANCH="${{ github.event.pull_request.head.ref }}"
API="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}/api/v1/repos/${{ github.repository }}/branches" API="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}/api/v1/repos/${{ github.repository }}/branches"
ENCODED=$(php -r "echo rawurlencode('${BRANCH}');") # URL-encode the branch name's slashes (no PHP dependency on the runner)
ENCODED=$(printf '%s' "${BRANCH}" | sed 's|/|%2F|g')
STATUS=$(curl -sf -o /dev/null -w "%{http_code}" -X DELETE \ STATUS=$(curl -sf -o /dev/null -w "%{http_code}" -X DELETE \
-H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \ -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \
+103 -7
View File
@@ -1,10 +1,106 @@
# DISABLED — auto-release Step 11 recreates dev from main after every release. # Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
# Cascade-dev is redundant and causes version conflicts when both main and dev #
# have different version numbers in templateDetails.xml / manifest.xml. # SPDX-License-Identifier: GPL-3.0-or-later
name: "Cascade Main → Dev (DISABLED)" #
on: workflow_dispatch # FILE INFORMATION
# DEFGROUP: MokoGitea.Workflow
# INGROUP: MokoStandards.Cascade
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
# PATH: /.mokogitea/workflows/cascade-dev.yml
# VERSION: 02.00.00
# BRIEF: Cascade main -> dev via PR; auto-merge only if conflict-free, else notify
name: "Cascade Main -> Dev"
on:
push:
branches:
- main
workflow_dispatch:
permissions:
contents: write
pull-requests: write
env:
MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
# ntfy destination is configured via repo or org variables (org vars are inherited).
NTFY_URL: ${{ vars.NTFY_URL || 'https://ntfy.mokoconsulting.tech' }}
NTFY_TOPIC: ${{ vars.CASCADE_NTFY_TOPIC || vars.NTFY_TOPIC || 'gitea-releases' }}
jobs: jobs:
noop: cascade:
name: Cascade main -> dev
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- run: echo "Cascade disabled — auto-release handles dev recreation" - name: Open main -> dev PR (auto-merge if clean, else notify)
env:
TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
REPO: ${{ github.repository }}
run: |
set -uo pipefail
API="${MOKOGITEA_URL}/api/v1/repos/${REPO}"
AUTH="Authorization: token ${TOKEN}"
jqnum() { python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('$1',''))" 2>/dev/null; }
# 0. dev must exist
if ! curl -sf -H "$AUTH" "${API}/branches/dev" >/dev/null 2>&1; then
echo "No dev branch - nothing to cascade."; exit 0
fi
# 1. is main ahead of dev?
AHEAD=$(curl -sf -H "$AUTH" "${API}/compare/dev...main" \
| python3 -c "import sys,json; print(json.load(sys.stdin).get('total_commits',0))" 2>/dev/null || echo 0)
if [ "${AHEAD:-0}" -eq 0 ]; then
echo "dev already up to date with main."; exit 0
fi
echo "main is ${AHEAD} commit(s) ahead of dev."
# 2. reuse an open main->dev PR, else create one
PR=$(curl -sf -H "$AUTH" "${API}/pulls?state=open&base=dev" \
| python3 -c "import sys,json; d=json.load(sys.stdin); print(next((str(p['number']) for p in d if p.get('head',{}).get('ref')=='main'), ''))" 2>/dev/null || echo "")
if [ -z "$PR" ]; then
RESP=$(curl -s -H "$AUTH" -H "Content-Type: application/json" -X POST "${API}/pulls" \
-d '{"head":"main","base":"dev","title":"chore(sync): cascade main -> dev","body":"Automated cascade of main into dev. Auto-merges only if conflict-free; otherwise left open for manual resolution."}')
PR=$(printf '%s' "$RESP" | jqnum number)
if [ -z "$PR" ]; then
echo "::warning::Could not open cascade PR: $RESP"; exit 0
fi
echo "Opened cascade PR #${PR}"
else
echo "Reusing open cascade PR #${PR}"
fi
# 3. wait for MokoGitea to compute mergeability (conflict detection)
MERGEABLE=""
for _ in 1 2 3 4 5 6; do
MERGEABLE=$(curl -sf -H "$AUTH" "${API}/pulls/${PR}" | jqnum mergeable)
case "$MERGEABLE" in True|False) break ;; esac
sleep 3
done
echo "mergeable=${MERGEABLE}"
notify() {
curl -sS \
-H "Title: ${REPO}: dev cascade needs manual merge" \
-H "Tags: warning,twisted_rightwards_arrows" \
-H "Priority: high" \
-H "Click: ${MOKOGITEA_URL}/${REPO}/pulls/${PR}" \
-d "main -> dev cascade PR #${PR} $1 It was NOT auto-merged; resolve it manually." \
"${NTFY_URL}/${NTFY_TOPIC}" || true
}
# 4. auto-merge only if conflict-free; otherwise notify
if [ "$MERGEABLE" = "True" ]; then
CODE=$(curl -s -o /tmp/merge.json -w "%{http_code}" -H "$AUTH" -H "Content-Type: application/json" \
-X POST "${API}/pulls/${PR}/merge" -d '{"Do":"merge","merge_when_checks_succeed":true}')
if [ "$CODE" -ge 200 ] && [ "$CODE" -lt 300 ]; then
echo "Cascade PR #${PR} merged (or scheduled to merge when checks pass)."
else
echo "::warning::Auto-merge returned HTTP ${CODE}: $(cat /tmp/merge.json)"
notify "could not be auto-merged (HTTP ${CODE})."
fi
else
echo "::warning::Cascade PR #${PR} has conflicts (mergeable=${MERGEABLE}); sending notification."
notify "has conflicts and cannot be merged automatically."
fi
+13 -2
View File
@@ -3,16 +3,22 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
# #
# FILE INFORMATION # FILE INFORMATION
# DEFGROUP: Gitea.Workflow # DEFGROUP: MokoGitea.Workflow
# INGROUP: MokoStandards.CI # INGROUP: MokoStandards.CI
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic # REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
# PATH: /.gitea/workflows/ci-generic.yml # PATH: /.mokogitea/workflows/ci-generic.yml
# VERSION: 01.00.00 # VERSION: 01.00.00
# BRIEF: CI pipeline — lint, validate, and test for generic projects (PHP + Node.js) # BRIEF: CI pipeline — lint, validate, and test for generic projects (PHP + Node.js)
name: "Generic: Project CI" name: "Generic: Project CI"
on: on:
pull_request:
branches:
- main
- dev
- dev/**
- rc/**
workflow_dispatch: workflow_dispatch:
permissions: permissions:
@@ -26,6 +32,8 @@ jobs:
lint: lint:
name: Lint & Validate name: Lint & Validate
runs-on: ubuntu-latest runs-on: ubuntu-latest
# Skip on template repos (Template-*) — they hold placeholder scaffolding, not buildable source.
if: ${{ !startsWith(github.event.repository.name, 'Template-') }}
steps: steps:
- name: Checkout - name: Checkout
@@ -124,6 +132,9 @@ jobs:
name: Tests name: Tests
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: lint needs: lint
# Run only when lint succeeded; always() forces evaluation so a skipped
# lint (e.g. template repos) skips this job cleanly instead of hanging.
if: ${{ always() && needs.lint.result == 'success' }}
steps: steps:
- name: Checkout - name: Checkout
@@ -0,0 +1,68 @@
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: MokoGitea.Workflow
# INGROUP: mokocli.Universal
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
# PATH: /.mokogitea/workflows/ci-issue-reporter.yml
# VERSION: 01.00.00
# BRIEF: Reusable workflow — creates/updates a MokoGitea issue when a CI gate fails.
# Clones MokoCLI and runs cli/ci_issue_reporter.sh.
name: "Universal: CI Issue Reporter"
on:
workflow_call:
inputs:
gate:
description: "CI gate name (e.g. PR Validation, Repository Health)"
required: true
type: string
details:
description: "Human-readable failure description"
required: true
type: string
severity:
description: "error or warning"
required: false
type: string
default: "error"
workflow:
description: "Workflow name for the issue title"
required: false
type: string
default: ""
secrets:
MOKOGITEA_TOKEN:
required: true
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
report:
name: "Report: ${{ inputs.gate }}"
runs-on: ubuntu-latest
steps:
- name: Clone MokoCLI
env:
MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
run: |
MOKOGITEA_URL="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}"
git clone --depth 1 --filter=blob:none --sparse "${MOKOGITEA_URL}/MokoConsulting/MokoCLI.git" /tmp/mokocli
cd /tmp/mokocli && git sparse-checkout set cli/ci_issue_reporter.sh
- name: Report CI failure
env:
MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
run: |
chmod +x /tmp/mokocli/cli/ci_issue_reporter.sh
/tmp/mokocli/cli/ci_issue_reporter.sh \
--gate "${{ inputs.gate }}" \
--details "${{ inputs.details }}" \
--severity "${{ inputs.severity }}" \
--workflow "${{ inputs.workflow }}"
+3 -3
View File
@@ -115,7 +115,7 @@ jobs:
- name: "PHPCS (PSR-12)" - name: "PHPCS (PSR-12)"
run: | run: |
vendor/bin/phpcs --standard=phpcs.xml --report=summary --warning-severity=0 lib/ validate/ automation/ 2>&1 || { vendor/bin/phpcs --standard=phpcs.xml --report=summary --warning-severity=0 lib/ validate/ 2>&1 || {
echo "::error::PHPCS found coding standard violations" echo "::error::PHPCS found coding standard violations"
echo "### PHPCS" >> $GITHUB_STEP_SUMMARY echo "### PHPCS" >> $GITHUB_STEP_SUMMARY
echo "Coding standard violations detected. Run \`composer phpcs\` locally." >> $GITHUB_STEP_SUMMARY echo "Coding standard violations detected. Run \`composer phpcs\` locally." >> $GITHUB_STEP_SUMMARY
@@ -453,8 +453,8 @@ jobs:
needs.governance.result == 'failure' || needs.governance.result == 'failure' ||
needs.templates.result == 'failure') needs.templates.result == 'failure')
env: env:
GITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
run: | run: |
chmod +x automation/ci-issue-reporter.sh chmod +x automation/ci-issue-reporter.sh
REPORTER="./automation/ci-issue-reporter.sh" REPORTER="./automation/ci-issue-reporter.sh"
+13 -13
View File
@@ -3,10 +3,10 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
# #
# FILE INFORMATION # FILE INFORMATION
# DEFGROUP: Gitea.Workflow # DEFGROUP: MokoGitea.Workflow
# INGROUP: MokoStandards.Maintenance # INGROUP: MokoStandards.Maintenance
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards # REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
# PATH: /.gitea/workflows/cleanup.yml # PATH: /.mokogitea/workflows/cleanup.yml
# VERSION: 01.00.00 # VERSION: 01.00.00
# BRIEF: Scheduled cleanup — delete merged branches and old workflow runs # BRIEF: Scheduled cleanup — delete merged branches and old workflow runs
@@ -21,7 +21,7 @@ permissions:
contents: write contents: write
env: env:
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
jobs: jobs:
cleanup: cleanup:
@@ -33,30 +33,30 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
token: ${{ secrets.GA_TOKEN }} token: ${{ secrets.MOKOGITEA_TOKEN }}
- name: Delete merged branches - name: Delete merged branches
env: env:
GA_TOKEN: ${{ secrets.GA_TOKEN }} MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
run: | run: |
echo "=== Merged Branch Cleanup ===" echo "=== Merged Branch Cleanup ==="
API="${GITEA_URL}/api/v1/repos/${{ github.repository }}" API="${MOKOGITEA_URL}/api/v1/repos/${{ github.repository }}"
# List branches via API # List branches via API
BRANCHES=$(curl -sS -H "Authorization: token ${GA_TOKEN}" \ BRANCHES=$(curl -sS -H "Authorization: token ${MOKOGITEA_TOKEN}" \
"${API}/branches?limit=50" | jq -r '.[].name') "${API}/branches?limit=50" | jq -r '.[].name')
DELETED=0 DELETED=0
for BRANCH in $BRANCHES; do for BRANCH in $BRANCHES; do
# Skip protected branches # Skip protected branches
case "$BRANCH" in case "$BRANCH" in
main|master|develop|release/*|hotfix/*) continue ;; main|master|dev|develop|rc|beta|alpha|release|release/*|production|stable|staging|hotfix/*|version/*) continue ;;
esac esac
# Check if branch is merged into main # Check if branch is merged into main
if git merge-base --is-ancestor "origin/${BRANCH}" origin/main 2>/dev/null; then if git merge-base --is-ancestor "origin/${BRANCH}" origin/main 2>/dev/null; then
echo " Deleting merged branch: ${BRANCH}" echo " Deleting merged branch: ${BRANCH}"
curl -sS -X DELETE -H "Authorization: token ${GA_TOKEN}" \ curl -sS -X DELETE -H "Authorization: token ${MOKOGITEA_TOKEN}" \
"${API}/branches/${BRANCH}" 2>/dev/null || true "${API}/branches/${BRANCH}" 2>/dev/null || true
DELETED=$((DELETED + 1)) DELETED=$((DELETED + 1))
fi fi
@@ -66,20 +66,20 @@ jobs:
- name: Clean old workflow runs - name: Clean old workflow runs
env: env:
GA_TOKEN: ${{ secrets.GA_TOKEN }} MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
run: | run: |
echo "=== Workflow Run Cleanup ===" echo "=== Workflow Run Cleanup ==="
API="${GITEA_URL}/api/v1/repos/${{ github.repository }}" API="${MOKOGITEA_URL}/api/v1/repos/${{ github.repository }}"
CUTOFF=$(date -d "30 days ago" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -v-30d +%Y-%m-%dT%H:%M:%SZ) CUTOFF=$(date -d "30 days ago" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -v-30d +%Y-%m-%dT%H:%M:%SZ)
# Get old completed runs # Get old completed runs
RUNS=$(curl -sS -H "Authorization: token ${GA_TOKEN}" \ RUNS=$(curl -sS -H "Authorization: token ${MOKOGITEA_TOKEN}" \
"${API}/actions/runs?status=completed&limit=50" | \ "${API}/actions/runs?status=completed&limit=50" | \
jq -r ".workflow_runs[] | select(.created_at < \"${CUTOFF}\") | .id" 2>/dev/null) jq -r ".workflow_runs[] | select(.created_at < \"${CUTOFF}\") | .id" 2>/dev/null)
DELETED=0 DELETED=0
for RUN_ID in $RUNS; do for RUN_ID in $RUNS; do
curl -sS -X DELETE -H "Authorization: token ${GA_TOKEN}" \ curl -sS -X DELETE -H "Authorization: token ${MOKOGITEA_TOKEN}" \
"${API}/actions/runs/${RUN_ID}" 2>/dev/null || true "${API}/actions/runs/${RUN_ID}" 2>/dev/null || true
DELETED=$((DELETED + 1)) DELETED=$((DELETED + 1))
done done
+2 -2
View File
@@ -13,7 +13,7 @@ on:
workflow_dispatch: workflow_dispatch:
env: env:
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
jobs: jobs:
publish: publish:
@@ -49,7 +49,7 @@ jobs:
- name: Verify Gitea registry - name: Verify Gitea registry
run: | run: |
echo "Gitea Composer registry auto-publishes from tags." echo "Gitea Composer registry auto-publishes from tags."
echo "Package available at: ${GITEA_URL}/api/packages/MokoConsulting/composer" echo "Package available at: ${MOKOGITEA_URL}/api/packages/MokoConsulting/composer"
echo "Install: composer require mokoconsulting/mokocli" echo "Install: composer require mokoconsulting/mokocli"
# Packagist — notify of new version (points to GitHub mirror which Packagist can access) # Packagist — notify of new version (points to GitHub mirror which Packagist can access)
-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
+3 -3
View File
@@ -3,10 +3,10 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
# #
# FILE INFORMATION # FILE INFORMATION
# DEFGROUP: Gitea.Workflow # DEFGROUP: MokoGitea.Workflow
# INGROUP: MokoStandards.Security # INGROUP: MokoStandards.Security
# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/MokoStandards-API # REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards-API
# PATH: /templates/workflows/gitleaks.yml.template # PATH: /.mokogitea/workflows/gitleaks.yml
# VERSION: 01.00.00 # VERSION: 01.00.00
# BRIEF: Secret scanning — detect leaked credentials, API keys, and tokens # BRIEF: Secret scanning — detect leaked credentials, API keys, and tokens
# #
+5 -5
View File
@@ -5,7 +5,7 @@
# FILE INFORMATION # FILE INFORMATION
# DEFGROUP: Gitea.Workflow # DEFGROUP: Gitea.Workflow
# INGROUP: mokocli.Automation # INGROUP: mokocli.Automation
# VERSION: 09.41.00 # VERSION: 01.00.00
# 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"
@@ -19,7 +19,7 @@ permissions:
issues: write issues: write
env: env:
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
jobs: jobs:
create-branch: create-branch:
@@ -28,8 +28,8 @@ jobs:
steps: steps:
- name: Create branch and comment - name: Create branch and comment
run: | run: |
TOKEN="${{ secrets.GA_TOKEN }}" TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
API="${GITEA_URL}/api/v1/repos/${{ github.repository }}" API="${MOKOGITEA_URL}/api/v1/repos/${{ github.repository }}"
ISSUE_NUM="${{ github.event.issue.number }}" ISSUE_NUM="${{ github.event.issue.number }}"
ISSUE_TITLE="${{ github.event.issue.title }}" ISSUE_TITLE="${{ github.event.issue.title }}"
@@ -58,7 +58,7 @@ jobs:
echo "Created branch: ${BRANCH}" echo "Created branch: ${BRANCH}"
# Comment on issue with branch link # Comment on issue with branch link
REPO_URL="${GITEA_URL}/${{ github.repository }}" REPO_URL="${MOKOGITEA_URL}/${{ github.repository }}"
BODY="Branch created: [\`${BRANCH}\`](${REPO_URL}/src/branch/${BRANCH})\n\n\`\`\`bash\ngit fetch origin\ngit checkout ${BRANCH}\n\`\`\`" BODY="Branch created: [\`${BRANCH}\`](${REPO_URL}/src/branch/${BRANCH})\n\n\`\`\`bash\ngit fetch origin\ngit checkout ${BRANCH}\n\`\`\`"
curl -sf -X POST \ curl -sf -X POST \
+5 -5
View File
@@ -3,10 +3,10 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
# #
# FILE INFORMATION # FILE INFORMATION
# DEFGROUP: Gitea.Workflow # DEFGROUP: MokoGitea.Workflow
# INGROUP: MokoStandards.Notifications # INGROUP: MokoStandards.Notifications
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards # REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
# PATH: /.gitea/workflows/notify.yml # PATH: /.mokogitea/workflows/notify.yml
# VERSION: 01.00.00 # VERSION: 01.00.00
# BRIEF: Push notifications via ntfy on release success or workflow failure # BRIEF: Push notifications via ntfy on release success or workflow failure
@@ -15,9 +15,9 @@ name: "Universal: Notifications"
on: on:
workflow_run: workflow_run:
workflows: workflows:
- "Joomla Build & Release" - "Universal: Build & Release"
- "Joomla Extension CI" - "Joomla: Extension CI"
- "Deploy" - "Generic: Project CI"
types: types:
- completed - completed
File diff suppressed because it is too large Load Diff
+18 -9
View File
@@ -3,11 +3,11 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
# #
# FILE INFORMATION # FILE INFORMATION
# DEFGROUP: Gitea.Workflow # DEFGROUP: MokoGitea.Workflow
# INGROUP: mokocli.Release # INGROUP: mokocli.Release
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli # REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
# PATH: /templates/workflows/universal/pre-release.yml.template # PATH: /.mokogitea/workflows/pre-release.yml
# VERSION: 05.01.00 # VERSION: 05.02.00
# BRIEF: Auto pre-release on push to dev/alpha/beta/rc branches # BRIEF: Auto pre-release on push to dev/alpha/beta/rc branches
name: "Universal: Pre-Release" name: "Universal: Pre-Release"
@@ -48,9 +48,13 @@ jobs:
build: build:
name: "Build Pre-Release (${{ inputs.stability || github.ref_name }})" name: "Build Pre-Release (${{ inputs.stability || github.ref_name }})"
runs-on: release runs-on: release
# Skip on template repos (Template-*) — they scaffold other repos and do not release.
if: >- if: >-
github.event_name == 'workflow_dispatch' || !startsWith(github.event.repository.name, 'Template-') &&
github.event_name == 'push' (
github.event_name == 'workflow_dispatch' ||
github.event_name == 'push'
)
steps: steps:
- name: Checkout - name: Checkout
@@ -59,6 +63,11 @@ jobs:
fetch-depth: 0 fetch-depth: 0
token: ${{ secrets.MOKOGITEA_TOKEN }} token: ${{ secrets.MOKOGITEA_TOKEN }}
ref: ${{ github.ref_name }} ref: ${{ github.ref_name }}
submodules: recursive
- name: Update submodules to main
run: |
git submodule foreach --quiet 'git checkout main && git pull --quiet origin main' 2>/dev/null || true
- name: Setup mokocli tools - name: Setup mokocli tools
env: env:
@@ -75,7 +84,7 @@ jobs:
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 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 fi
rm -rf /tmp/mokocli rm -rf /tmp/mokocli
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git 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 git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
cd /tmp/mokocli && composer install --no-dev --no-interaction --quiet cd /tmp/mokocli && composer install --no-dev --no-interaction --quiet
echo MOKO_CLI=/tmp/mokocli/cli >> $GITHUB_ENV echo MOKO_CLI=/tmp/mokocli/cli >> $GITHUB_ENV
@@ -147,8 +156,8 @@ jobs:
fi fi
# Commit version bump # Commit version bump
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech" git config --local user.email "mokogitea-actions[bot]@mokoconsulting.tech"
git config --local user.name "gitea-actions[bot]" git config --local user.name "mokogitea-actions[bot]"
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git" git remote set-url origin "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
git add -A git add -A
git diff --cached --quiet || { git diff --cached --quiet || {
+22 -16
View File
@@ -3,9 +3,9 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
# #
# FILE INFORMATION # FILE INFORMATION
# DEFGROUP: Gitea.Workflow # DEFGROUP: MokoGitea.Workflow
# INGROUP: mokocli.Universal # INGROUP: mokocli.Universal
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli # REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
# PATH: /.mokogitea/workflows/rc-revert.yml # PATH: /.mokogitea/workflows/rc-revert.yml
# VERSION: 09.23.00 # VERSION: 09.23.00
# BRIEF: Rename rc/ branch back to dev/ when PR is closed without merge # BRIEF: Rename rc/ branch back to dev/ when PR is closed without merge
@@ -25,16 +25,25 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: >- if: >-
github.event.pull_request.merged == false && github.event.pull_request.merged == false &&
startsWith(github.event.pull_request.head.ref, 'rc/') startsWith(github.event.pull_request.head.ref, 'rc/') &&
!startsWith(github.event.repository.name, 'Template-')
steps: steps:
- name: Rename branch - name: Rename branch
env:
BRANCH: ${{ github.event.pull_request.head.ref }}
REPO: ${{ github.repository }}
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
run: | run: |
BRANCH="${{ github.event.pull_request.head.ref }}" set -euo pipefail
# BRANCH is attacker-controlled (PR head ref). Strict allowlist before ANY use.
if ! printf '%s' "$BRANCH" | grep -Eq '^rc/[A-Za-z0-9._/-]+$'; then
echo "::error::Refusing unsafe branch name: $BRANCH"; exit 1
fi
SUFFIX="${BRANCH#rc/}" SUFFIX="${BRANCH#rc/}"
DEV_BRANCH="dev/${SUFFIX}" DEV_BRANCH="dev/${SUFFIX}"
API="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}/api/v1/repos/${{ github.repository }}/branches" API="${GITEA_URL}/api/v1/repos/${REPO}/branches"
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
# Create dev/ branch from rc/ branch # Create dev/ branch from rc/ branch
STATUS=$(curl -sf -o /dev/null -w "%{http_code}" -X POST \ STATUS=$(curl -sf -o /dev/null -w "%{http_code}" -X POST \
@@ -42,25 +51,22 @@ jobs:
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d "{\"new_branch_name\": \"${DEV_BRANCH}\", \"old_branch_name\": \"${BRANCH}\"}" \ -d "{\"new_branch_name\": \"${DEV_BRANCH}\", \"old_branch_name\": \"${BRANCH}\"}" \
"${API}" 2>/dev/null || true) "${API}" 2>/dev/null || true)
if [ "$STATUS" = "201" ]; then if [ "$STATUS" = "201" ]; then
echo "Created branch: ${DEV_BRANCH}" >> $GITHUB_STEP_SUMMARY echo "Created branch: ${DEV_BRANCH}" >> "$GITHUB_STEP_SUMMARY"
else else
echo "::error::Failed to create ${DEV_BRANCH} from ${BRANCH} (HTTP ${STATUS})" echo "::error::Failed to create ${DEV_BRANCH} from ${BRANCH} (HTTP ${STATUS})"; exit 1
exit 1
fi fi
# Delete rc/ branch # Read BRANCH from the environment inside PHP (getenv, no string interpolation -> no PHP injection)
ENCODED=$(php -r "echo rawurlencode('${BRANCH}');") ENCODED=$(php -r 'echo rawurlencode(getenv("BRANCH"));')
STATUS=$(curl -sf -o /dev/null -w "%{http_code}" -X DELETE \ STATUS=$(curl -sf -o /dev/null -w "%{http_code}" -X DELETE \
-H "Authorization: token ${TOKEN}" \ -H "Authorization: token ${TOKEN}" \
"${API}/${ENCODED}" 2>/dev/null || true) "${API}/${ENCODED}" 2>/dev/null || true)
if [ "$STATUS" = "204" ]; then if [ "$STATUS" = "204" ]; then
echo "Deleted branch: ${BRANCH}" >> $GITHUB_STEP_SUMMARY echo "Deleted branch: ${BRANCH}" >> "$GITHUB_STEP_SUMMARY"
else else
echo "::warning::Failed to delete ${BRANCH} (HTTP ${STATUS})" echo "::warning::Failed to delete ${BRANCH} (HTTP ${STATUS})"
fi fi
echo "### RC Reverted" >> $GITHUB_STEP_SUMMARY echo "### RC Reverted" >> "$GITHUB_STEP_SUMMARY"
echo "${BRANCH} → ${DEV_BRANCH}" >> $GITHUB_STEP_SUMMARY echo "${BRANCH} → ${DEV_BRANCH}" >> "$GITHUB_STEP_SUMMARY"
File diff suppressed because it is too large Load Diff
@@ -22,7 +22,7 @@ permissions:
contents: write contents: write
env: env:
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }} MOKOGITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
jobs: jobs:
sync: sync:
+32
View File
@@ -0,0 +1,32 @@
name: Sync Workflows to Repos
on:
push:
branches:
- main
paths:
- '.mokogitea/workflows/**'
jobs:
sync:
runs-on: ubuntu-latest
if: ${{ startsWith(github.event.repository.name, 'Template-') }}
steps:
- name: Checkout mokocli
uses: actions/checkout@v4
with:
repository: MokoConsulting/MokoCLI
token: ${{ secrets.MOKOGITEA_TOKEN }}
- name: Setup PHP
uses: https://git.mokoconsulting.tech/MokoConsulting/.mokogitea/raw/branch/main/actions/setup-php@v1
with:
php-version: '8.1'
- name: Install dependencies
run: composer install --no-dev --no-interaction
- name: Sync workflows to generic repos
run: php automation/bulk_sync.php --platform generic --org MokoConsulting --workflows-only --auto-merge --token "${{ secrets.MOKOGITEA_TOKEN }}"
env:
MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
+3 -2
View File
@@ -3,7 +3,7 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
# #
# FILE INFORMATION # FILE INFORMATION
# DEFGROUP: Gitea.Workflow.Template # DEFGROUP: MokoGitea.Workflow.Template
# INGROUP: MokoStandards.CI # INGROUP: MokoStandards.CI
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Joomla # REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Joomla
# PATH: /.mokogitea/workflows/version-set.yml # PATH: /.mokogitea/workflows/version-set.yml
@@ -34,6 +34,7 @@ jobs:
set-version: set-version:
name: Set Version to ${{ inputs.version }} name: Set Version to ${{ inputs.version }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: ${{ !startsWith(github.event.repository.name, 'Template-') }}
steps: steps:
- name: Validate version format - name: Validate version format
@@ -48,7 +49,7 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
token: ${{ secrets.MOKOGITEA_TOKEN || secrets.GA_TOKEN || github.token }} token: ${{ secrets.MOKOGITEA_TOKEN || github.token }}
ref: ${{ inputs.branch || github.ref }} ref: ${{ inputs.branch || github.ref }}
fetch-depth: 1 fetch-depth: 1
+15 -6
View File
@@ -3,9 +3,9 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
# #
# FILE INFORMATION # FILE INFORMATION
# DEFGROUP: Gitea.Workflow # DEFGROUP: MokoGitea.Workflow
# INGROUP: mokocli.Universal # INGROUP: mokocli.Universal
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli # REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Generic
# PATH: /.mokogitea/workflows/workflow-sync-trigger.yml # PATH: /.mokogitea/workflows/workflow-sync-trigger.yml
# VERSION: 01.01.00 # VERSION: 01.01.00
# BRIEF: Trigger workflow sync to live repos when a PR is merged to main # BRIEF: Trigger workflow sync to live repos when a PR is merged to main
@@ -13,6 +13,7 @@
name: "Universal: Workflow Sync Trigger" name: "Universal: Workflow Sync Trigger"
on: on:
workflow_dispatch:
pull_request: pull_request:
types: [closed] types: [closed]
branches: branches:
@@ -26,8 +27,10 @@ jobs:
name: Sync workflows to live repos name: Sync workflows to live repos
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: >- if: >-
github.event.pull_request.merged == true && startsWith(github.event.repository.name, 'Template-') &&
!contains(github.event.pull_request.title, '[skip sync]') (github.event_name == 'workflow_dispatch' ||
(github.event.pull_request.merged == true &&
!contains(github.event.pull_request.title, '[skip sync]')))
steps: steps:
- name: Determine platform from repo name - name: Determine platform from repo name
@@ -49,8 +52,14 @@ jobs:
env: env:
MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }} MOKOGITEA_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
run: | run: |
GITEA_URL="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}" MOKOGITEA_URL="${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}"
git clone --depth 1 "${GITEA_URL}/MokoConsulting/mokocli.git" /tmp/mokocli git clone --depth 1 "${MOKOGITEA_URL}/MokoConsulting/MokoCLI.git" /tmp/mokocli
- name: Install PHP
run: |
if ! command -v php &> /dev/null; then
apt-get update -qq && apt-get install -y -qq php-cli php-json php-curl > /dev/null 2>&1
fi
- name: Install dependencies - name: Install dependencies
run: | run: |
+11 -6
View File
@@ -4,7 +4,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
FILE INFORMATION FILE INFORMATION
DEFGROUP: MokoCli.Root DEFGROUP: MokoCli.Root
INGROUP: MokoCli INGROUP: MokoCli
REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
PATH: /CHANGELOG.md PATH: /CHANGELOG.md
BRIEF: Release changelog BRIEF: Release changelog
--> -->
@@ -12,12 +12,17 @@ BRIEF: Release changelog
# Changelog # Changelog
## [Unreleased] ## [Unreleased]
## [09.41.00] --- 2026-06-25 ## [09.43.00] --- 2026-07-05
## [09.40.00] --- 2026-06-25 ## [09.43.00] --- 2026-07-05
## [09.40.00] --- 2026-06-25 ## [09.42.00] --- 2026-07-04
## [09.39.00] --- 2026-06-25 ## [09.42.00] --- 2026-07-04
## [09.39.00] --- 2026-06-25 ### Fixed
- branch_rename.php: force-update the target branch ref in place instead of delete+recreate, so `moko repo:rename-branch` works when the target (e.g. `rc`) is a protected branch that cannot be deleted — previously the delete silently failed and the recreate returned HTTP 409
## [09.42.00] --- 2026-07-04
## [09.42.00] --- 2026-07-04
+1 -1
View File
@@ -34,7 +34,7 @@ feature/* ──PR──> dev ──draft PR──> (renamed to rc) ──merge
7. **Merging to main** triggers the stable release pipeline: 7. **Merging to main** triggers the stable release pipeline:
- Minor version bump (e.g., `02.09.xx` → `02.10.00`) - Minor version bump (e.g., `02.09.xx` → `02.10.00`)
- Stability suffix stripped (clean version) - Stability suffix stripped (clean version)
- Gitea release created with ZIP/tar.gz packages - MokoGitea release created with ZIP/tar.gz packages
- `updates.xml` updated (Joomla extensions) - `updates.xml` updated (Joomla extensions)
- `dev` branch recreated from `main` - `dev` branch recreated from `main`
+2 -2
View File
@@ -2,8 +2,8 @@
Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech> Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-or-later
FILE INFORMATION FILE INFORMATION
DEFGROUP: MokoPlatform.Root DEFGROUP: MokoCLI.Root
INGROUP: MokoPlatform INGROUP: MokoCLI
REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
PATH: /PLUGIN_SCRIPTS.md PATH: /PLUGIN_SCRIPTS.md
BRIEF: Plugin system CLI documentation BRIEF: Plugin system CLI documentation
+9 -9
View File
@@ -2,11 +2,11 @@
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: MokoPlatform.Root DEFGROUP: MokoCLI.Root
INGROUP: MokoPlatform INGROUP: MokoCLI
REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
PATH: /README.md PATH: /README.md
VERSION: 09.41.00 VERSION: 09.43.00
BRIEF: Project overview and documentation BRIEF: Project overview and documentation
--> -->
@@ -16,7 +16,7 @@ BRIEF: Project overview and documentation
PHP implementation of mokocli — enterprise standards, automation framework, workflow templates, and bulk sync tooling. PHP implementation of mokocli — enterprise standards, automation framework, workflow templates, and bulk sync tooling.
> **Primary platform**: [Gitea — git.mokoconsulting.tech](https://git.mokoconsulting.tech/MokoConsulting/MokoCli-API) > **Primary platform**: [MokoGitea — git.mokoconsulting.tech](https://git.mokoconsulting.tech/MokoConsulting/MokoCli-API)
> **Backup mirror**: [GitHub](https://github.com/MokoConsulting/MokoCli-API) *(read-only mirror)* > **Backup mirror**: [GitHub](https://github.com/MokoConsulting/MokoCli-API) *(read-only mirror)*
## What Lives Here ## What Lives Here
@@ -25,7 +25,7 @@ PHP implementation of mokocli — enterprise standards, automation framework, wo
|-----------|---------| |-----------|---------|
| `lib/Enterprise/` | 38 PHP enterprise library classes (platform adapters, sync, validation, plugins) | | `lib/Enterprise/` | 38 PHP enterprise library classes (platform adapters, sync, validation, plugins) |
| `cli/` | CLI scripts (archive, create, release, sync rulesets, version management) | | `cli/` | CLI scripts (archive, create, release, sync rulesets, version management) |
| `automation/` | Bulk sync, push files, repo cleanup, Gitea migration | | `automation/` | Bulk sync, push files, repo cleanup, MokoGitea migration |
| `validate/` | 18 validation scripts (health, structure, secrets, syntax, drift) | | `validate/` | 18 validation scripts (health, structure, secrets, syntax, drift) |
| `templates/` | **Workflow templates** and config templates synced to governed repos | | `templates/` | **Workflow templates** and config templates synced to governed repos |
| `definitions/` | Repository structure definitions (`.tf` format) | | `definitions/` | Repository structure definitions (`.tf` format) |
@@ -42,7 +42,7 @@ composer require mokoconsulting-tech/enterprise
### Composer Registry ### Composer Registry
This package is served from Gitea package registry. Add this to your `composer.json`: This package is served from MokoGitea package registry. Add this to your `composer.json`:
```json ```json
{ {
@@ -73,10 +73,10 @@ vendor/bin/moko inventory -- --path .
| Variable | Purpose | | Variable | Purpose |
|----------|---------| |----------|---------|
| `GIT_PLATFORM` | `gitea` (default) or `github` | | `GIT_PLATFORM` | `gitea` (default) or `github` |
| `GA_TOKEN` | Gitea API / Gitea Actions token | | `GA_TOKEN` | MokoGitea API / MokoGitea Actions token |
| `GH_TOKEN` | GitHub API token (for mirror sync) | | `GH_TOKEN` | GitHub API token (for mirror sync) |
| `GITEA_URL` | Gitea instance URL (default: `https://git.mokoconsulting.tech`) | | `GITEA_URL` | MokoGitea instance URL (default: `https://git.mokoconsulting.tech`) |
| `GITEA_ORG` | Gitea organization (default: `MokoConsulting`) | | `GITEA_ORG` | MokoGitea organization (default: `MokoConsulting`) |
## License ## License
+2 -2
View File
@@ -2,8 +2,8 @@
Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech> Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-or-later
FILE INFORMATION FILE INFORMATION
DEFGROUP: MokoPlatform.Index DEFGROUP: MokoCLI.Index
INGROUP: MokoPlatform.Analysis INGROUP: MokoCLI.Analysis
REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
PATH: /analysis/index.md PATH: /analysis/index.md
BRIEF: Analysis directory index BRIEF: Analysis directory index
+2 -2
View File
@@ -14,8 +14,8 @@
* (at your option) any later version. * (at your option) any later version.
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.CLI * DEFGROUP: MokoCLI.Enterprise.CLI
* INGROUP: MokoPlatform.Enterprise * INGROUP: MokoCLI.Enterprise
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/audit_query.php * PATH: /cli/audit_query.php
* BRIEF: Search, filter, and export audit logs * BRIEF: Search, filter, and export audit logs
+37 -17
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/branch_rename.php * PATH: /cli/branch_rename.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Rename a git branch via Gitea API (create new, update PR, delete old) * BRIEF: Rename a git branch via Gitea API (create new, update PR, delete old)
*/ */
@@ -64,26 +64,46 @@ class BranchRenameCli extends CliFramework
return 1; return 1;
} }
// Step 2: Delete target branch if it already exists // Step 2: Point the target branch at the source commit.
// If the target already exists (e.g. a protected `rc` branch that cannot be
// deleted), force-update its ref in place instead of delete+recreate: deleting a
// protected branch fails, which then makes the recreate return HTTP 409.
$sourceSha = '';
if (isset($check['body']['commit']['id']) && is_string($check['body']['commit']['id'])) {
$sourceSha = $check['body']['commit']['id'];
}
$targetCheck = $this->apiRequest('GET', "{$apiBase}/branches/{$to}", $headers); $targetCheck = $this->apiRequest('GET', "{$apiBase}/branches/{$to}", $headers);
if ($targetCheck['code'] === 200) { if ($targetCheck['code'] === 200) {
echo "Target branch '{$to}' already exists — deleting\n"; echo "Target branch '{$to}' already exists - force-updating to {$from}
";
if (!$this->dryRun) { if (!$this->dryRun) {
$this->apiRequest('DELETE', "{$apiBase}/branches/{$to}", $headers); if ($sourceSha === '') {
$this->log('ERROR', "Cannot resolve HEAD commit of source '{$from}'");
return 1;
}
$ref = $this->apiRequest('PATCH', "{$apiBase}/git/refs/heads/{$to}", $headers, [
'sha' => $sourceSha,
'force' => true,
]);
if ($ref['code'] < 200 || $ref['code'] >= 300) {
$this->log('ERROR', "Failed to force-update '{$to}': HTTP {$ref['code']} (needs force-push perm)");
$this->log('ERROR', json_encode($ref['body']));
return 1;
}
} }
} } else {
echo "Creating branch: {$to} (from {$from})
// Step 3: Create new branch from source ";
echo "Creating branch: {$to} (from {$from})\n"; if (!$this->dryRun) {
if (!$this->dryRun) { $create = $this->apiRequest('POST', "{$apiBase}/branches", $headers, [
$create = $this->apiRequest('POST', "{$apiBase}/branches", $headers, [ 'new_branch_name' => $to,
'new_branch_name' => $to, 'old_branch_name' => $from,
'old_branch_name' => $from, ]);
]); if ($create['code'] < 200 || $create['code'] >= 300) {
if ($create['code'] < 200 || $create['code'] >= 300) { $this->log('ERROR', "Failed to create branch '{$to}': HTTP {$create['code']}");
$this->log('ERROR', "Failed to create branch '{$to}': HTTP {$create['code']}"); $this->log('ERROR', json_encode($create['body']));
$this->log('ERROR', json_encode($create['body'])); return 1;
return 1; }
} }
} }
+1 -1
View File
@@ -12,7 +12,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/bulk_workflow_push.php * PATH: /cli/bulk_workflow_push.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Push a workflow file to all governed repos via the Gitea Contents API * BRIEF: Push a workflow file to all governed repos via the Gitea Contents API
*/ */
+1 -1
View File
@@ -12,7 +12,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/bulk_workflow_trigger.php * PATH: /cli/bulk_workflow_trigger.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Trigger a workflow across multiple repos at once * BRIEF: Trigger a workflow across multiple repos at once
*/ */
+230
View File
@@ -0,0 +1,230 @@
#!/usr/bin/env bash
# ============================================================================
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# FILE INFORMATION
# DEFGROUP: Automation.CI
# INGROUP: mokocli.CLI
# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCLI
# PATH: /cli/ci_issue_reporter.sh
# VERSION: 10.00.00
# BRIEF: Creates or updates a Gitea issue when a CI gate fails.
# Deduplicates by searching open issues with the "ci-auto" label
# whose title matches the gate. If a matching issue exists, a comment
# is appended instead of opening a duplicate.
# ============================================================================
set -euo pipefail
# ── Defaults ────────────────────────────────────────────────────────────────
MOKOGITEA_URL="${MOKOGITEA_URL:-https://git.mokoconsulting.tech}"
MOKOGITEA_TOKEN="${MOKOGITEA_TOKEN:-}"
REPO="${GITHUB_REPOSITORY:-}"
RUN_URL="${GITHUB_SERVER_URL:-${MOKOGITEA_URL}}/${REPO}/actions/runs/${GITHUB_RUN_ID:-0}"
LABEL_NAME="ci-auto"
LABEL_COLOR="#e11d48"
GATE=""
DETAILS=""
SEVERITY="error"
WORKFLOW=""
# ── Parse arguments ─────────────────────────────────────────────────────────
usage() {
cat <<EOF
Usage: ci_issue_reporter.sh --gate NAME --details TEXT [OPTIONS]
Required:
--gate CI gate name (e.g. "Code Quality", "Self-Health")
--details Human-readable failure description
Optional:
--severity "error" (default) or "warning"
--workflow Workflow name for the issue title
--repo owner/repo (default: \$GITHUB_REPOSITORY)
--run-url URL to the CI run (auto-detected from env)
--token Gitea API token (default: \$MOKOGITEA_TOKEN)
--url Gitea base URL (default: \$MOKOGITEA_URL)
EOF
exit 1
}
while [[ $# -gt 0 ]]; do
case "$1" in
--gate) GATE="$2"; shift 2 ;;
--details) DETAILS="$2"; shift 2 ;;
--severity) SEVERITY="$2"; shift 2 ;;
--workflow) WORKFLOW="$2"; shift 2 ;;
--repo) REPO="$2"; shift 2 ;;
--run-url) RUN_URL="$2"; shift 2 ;;
--token) MOKOGITEA_TOKEN="$2"; shift 2 ;;
--url) MOKOGITEA_URL="$2"; shift 2 ;;
-h|--help) usage ;;
*) echo "Unknown option: $1"; usage ;;
esac
done
[[ -z "$GATE" ]] && { echo "ERROR: --gate is required"; usage; }
[[ -z "$DETAILS" ]] && { echo "ERROR: --details is required"; usage; }
[[ -z "$MOKOGITEA_TOKEN" ]] && { echo "ERROR: MOKOGITEA_TOKEN not set"; exit 1; }
[[ -z "$REPO" ]] && { echo "ERROR: GITHUB_REPOSITORY not set"; exit 1; }
API="${MOKOGITEA_URL}/api/v1/repos/${REPO}"
# ── Build title ─────────────────────────────────────────────────────────────
if [[ -n "$WORKFLOW" ]]; then
TITLE="[CI] ${WORKFLOW}: ${GATE} failed"
else
TITLE="[CI] ${GATE} failed"
fi
# ── Ensure label exists ─────────────────────────────────────────────────────
ensure_label() {
local exists
exists=$(curl -sf -o /dev/null -w '%{http_code}' \
-H "Authorization: token ${MOKOGITEA_TOKEN}" \
"${API}/labels" 2>/dev/null || echo "000")
if [[ "$exists" == "200" ]]; then
local found
found=$(curl -sf \
-H "Authorization: token ${MOKOGITEA_TOKEN}" \
"${API}/labels" 2>/dev/null \
| grep -o "\"name\":\"${LABEL_NAME}\"" || true)
if [[ -z "$found" ]]; then
curl -sf -X POST \
-H "Authorization: token ${MOKOGITEA_TOKEN}" \
-H "Content-Type: application/json" \
"${API}/labels" \
-d "{\"name\":\"${LABEL_NAME}\",\"color\":\"${LABEL_COLOR}\",\"description\":\"Auto-created by CI issue reporter\"}" \
> /dev/null 2>&1 || true
fi
fi
}
# ── Search for existing open issue ──────────────────────────────────────────
find_existing_issue() {
local query
query=$(printf '%s' "[CI] ${GATE}" | sed 's/ /%20/g; s/\[/%5B/g; s/\]/%5D/g')
local response
response=$(curl -sf \
-H "Authorization: token ${MOKOGITEA_TOKEN}" \
"${API}/issues?type=issues&state=open&labels=${LABEL_NAME}&q=${query}&limit=5" \
2>/dev/null || echo "[]")
echo "$response" \
| grep -oP '"number":\s*\K[0-9]+' \
| head -1
}
# ── Build issue body ────────────────────────────────────────────────────────
build_body() {
local severity_badge
if [[ "$SEVERITY" == "error" ]]; then
severity_badge="**Severity:** Error"
else
severity_badge="**Severity:** Warning"
fi
cat <<BODY
## CI Gate Failure: ${GATE}
${severity_badge}
**Workflow:** ${WORKFLOW:-unknown}
**Branch:** ${GITHUB_REF_NAME:-unknown}
**Commit:** \`${GITHUB_SHA:0:8}\`
**Run:** [View CI run](${RUN_URL})
### Details
${DETAILS}
### Resolution
Fix the issue described above and push a new commit. This issue will be closed automatically when the gate passes, or can be closed manually.
---
*Auto-created by [ci-issue-reporter](${MOKOGITEA_URL}/MokoConsulting/MokoCLI/src/branch/main/cli/ci_issue_reporter.sh)*
BODY
}
# ── Build comment body (for existing issues) ────────────────────────────────
build_comment() {
cat <<COMMENT
### CI failure recurrence
**Branch:** ${GITHUB_REF_NAME:-unknown}
**Commit:** \`${GITHUB_SHA:0:8}\`
**Run:** [View CI run](${RUN_URL})
${DETAILS}
COMMENT
}
# ── Main ────────────────────────────────────────────────────────────────────
ensure_label
EXISTING=$(find_existing_issue)
if [[ -n "$EXISTING" ]]; then
COMMENT_BODY=$(build_comment)
COMMENT_JSON=$(printf '%s' "$COMMENT_BODY" | python3 -c "
import sys, json
print(json.dumps({'body': sys.stdin.read()}))" 2>/dev/null)
HTTP=$(curl -sf -o /dev/null -w '%{http_code}' -X POST \
-H "Authorization: token ${MOKOGITEA_TOKEN}" \
-H "Content-Type: application/json" \
"${API}/issues/${EXISTING}/comments" \
-d "${COMMENT_JSON}" 2>/dev/null || echo "000")
if [[ "$HTTP" == "201" ]]; then
echo "Commented on existing issue #${EXISTING}"
else
echo "WARNING: Failed to comment on issue #${EXISTING} (HTTP ${HTTP})"
fi
else
ISSUE_BODY=$(build_body)
ISSUE_JSON=$(python3 -c "
import sys, json
body = sys.stdin.read()
print(json.dumps({
'title': sys.argv[1],
'body': body,
'labels': []
}))" "$TITLE" <<< "$ISSUE_BODY" 2>/dev/null)
RESPONSE=$(curl -sf -X POST \
-H "Authorization: token ${MOKOGITEA_TOKEN}" \
-H "Content-Type: application/json" \
"${API}/issues" \
-d "${ISSUE_JSON}" 2>/dev/null || echo "{}")
ISSUE_NUM=$(echo "$RESPONSE" | grep -oP '"number":\s*\K[0-9]+' | head -1)
if [[ -n "$ISSUE_NUM" ]]; then
LABEL_ID=$(curl -sf \
-H "Authorization: token ${MOKOGITEA_TOKEN}" \
"${API}/labels" 2>/dev/null \
| grep -oP "\"id\":\s*\K[0-9]+(?=[^}]*\"name\":\s*\"${LABEL_NAME}\")" \
| head -1 || true)
if [[ -n "$LABEL_ID" ]]; then
curl -sf -X POST \
-H "Authorization: token ${MOKOGITEA_TOKEN}" \
-H "Content-Type: application/json" \
"${API}/issues/${ISSUE_NUM}/labels" \
-d "{\"labels\":[${LABEL_ID}]}" \
> /dev/null 2>&1 || true
fi
echo "Created issue #${ISSUE_NUM}: ${TITLE}"
else
echo "WARNING: Failed to create issue"
echo "Response: ${RESPONSE}"
fi
fi
+1 -1
View File
@@ -12,7 +12,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/client_dashboard.php * PATH: /cli/client_dashboard.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Generate unified client dashboard HTML * BRIEF: Generate unified client dashboard HTML
*/ */
+1 -1
View File
@@ -12,7 +12,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/client_inventory.php * PATH: /cli/client_inventory.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Discover and list all client-waas repos with their server configuration status * BRIEF: Discover and list all client-waas repos with their server configuration status
*/ */
+3 -3
View File
@@ -12,7 +12,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/client_provision.php * PATH: /cli/client_provision.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Provision a new client environment end-to-end * BRIEF: Provision a new client environment end-to-end
*/ */
@@ -104,7 +104,7 @@ class ClientProvisionCli extends CliFramework
'variables' => 'setVariables', 'variables' => 'setVariables',
'secrets' => 'setSecrets', 'secrets' => 'setSecrets',
'monitoring' => 'setupMonitoring', 'monitoring' => 'setupMonitoring',
'summary' => 'printSummary', 'summary' => 'printProvisioningSummary',
]; ];
$exitCode = 0; $exitCode = 0;
@@ -383,7 +383,7 @@ class ClientProvisionCli extends CliFramework
return 0; return 0;
} }
private function printSummary(): int private function printProvisioningSummary(): int
{ {
$vars = $this->config['variables'] ?? []; $vars = $this->config['variables'] ?? [];
$secrets = $this->config['secrets'] ?? []; $secrets = $this->config['secrets'] ?? [];
+2 -2
View File
@@ -8,8 +8,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.CLI * DEFGROUP: MokoCLI.CLI
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/deploy_joomla.php * PATH: /cli/deploy_joomla.php
* BRIEF: Smart Joomla deploy — routes files to correct server directories by extension type * BRIEF: Smart Joomla deploy — routes files to correct server directories by extension type
+1 -1
View File
@@ -12,7 +12,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/grafana_dashboard.php * PATH: /cli/grafana_dashboard.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Manage Grafana dashboards via API * BRIEF: Manage Grafana dashboards via API
*/ */
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/joomla_build.php * PATH: /cli/joomla_build.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Build a Joomla extension ZIP from manifest — all types supported * BRIEF: Build a Joomla extension ZIP from manifest — all types supported
* NOTE: Called by pre-release and auto-release workflows. * NOTE: Called by pre-release and auto-release workflows.
*/ */
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/joomla_metadata_validate.php * PATH: /cli/joomla_metadata_validate.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Validate MokoGitea repo metadata against Joomla extension manifest XML * BRIEF: Validate MokoGitea repo metadata against Joomla extension manifest XML
*/ */
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/manifest_detect.php * PATH: /cli/manifest_detect.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Auto-detect manifest fields from source files and optionally push to API * BRIEF: Auto-detect manifest fields from source files and optionally push to API
*/ */
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/manifest_integrity.php * PATH: /cli/manifest_integrity.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Cross-check manifest API fields against repo contents across the org * BRIEF: Cross-check manifest API fields against repo contents across the org
*/ */
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/manifest_licensing.php * PATH: /cli/manifest_licensing.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Ensure licensing tags (updateservers, dlid) in Joomla extension manifests * BRIEF: Ensure licensing tags (updateservers, dlid) in Joomla extension manifests
*/ */
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/manifest_read.php * PATH: /cli/manifest_read.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Read repo metadata from Gitea manifest API, auto-detect the rest * BRIEF: Read repo metadata from Gitea manifest API, auto-detect the rest
*/ */
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/platform_detect.php * PATH: /cli/platform_detect.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Auto-detect repository platform type and optionally update manifest * BRIEF: Auto-detect repository platform type and optionally update manifest
*/ */
-1
View File
@@ -40,7 +40,6 @@ class ReleaseCli extends CliFramework
$bulkSyncFile = file_exists("{$repoRoot}/.mokogitea/workflows/bulk-repo-sync.yml") $bulkSyncFile = file_exists("{$repoRoot}/.mokogitea/workflows/bulk-repo-sync.yml")
? "{$repoRoot}/.mokogitea/workflows/bulk-repo-sync.yml" ? "{$repoRoot}/.mokogitea/workflows/bulk-repo-sync.yml"
: "{$repoRoot}/.github/workflows/bulk-repo-sync.yml"; : "{$repoRoot}/.github/workflows/bulk-repo-sync.yml";
$cleanupFile = "{$repoRoot}/templates/workflows/shared/repository-cleanup.yml.template";
// -- Step 1: Read current version -- // -- Step 1: Read current version --
$readme = "{$repoRoot}/README.md"; $readme = "{$repoRoot}/README.md";
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/release_cascade.php * PATH: /cli/release_cascade.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Cascade release zip to all lower stability channels * BRIEF: Cascade release zip to all lower stability channels
*/ */
+79 -1
View File
@@ -270,12 +270,90 @@ class ReleasePackageCli extends CliFramework
} }
} }
// Check if sub-source is itself a Joomla package (nested package)
$nestedPkgManifests = glob("{$subSourceDir}/pkg_*.xml") ?: [];
$isNestedPackage = !empty($nestedPkgManifests) && is_dir("{$subSourceDir}/packages");
$subZip = new \ZipArchive(); $subZip = new \ZipArchive();
if ($subZip->open($subZipPath, \ZipArchive::CREATE | \ZipArchive::OVERWRITE) !== true) { if ($subZip->open($subZipPath, \ZipArchive::CREATE | \ZipArchive::OVERWRITE) !== true) {
$this->log('ERROR', "Failed to create sub-package ZIP: {$subZipPath}"); $this->log('ERROR', "Failed to create sub-package ZIP: {$subZipPath}");
continue; continue;
} }
$this->addDirToZip($subZip, $subSourceDir, '', $this->excludePatterns);
if ($isNestedPackage) {
// Build nested package: zip each sub-extension, then assemble
echo " Building nested package: {$subName}\n";
$nestedPkgDirs = glob("{$subSourceDir}/packages/*", GLOB_ONLYDIR) ?: [];
$nestedManifested = [];
foreach ($nestedPkgManifests as $npmf) {
$npmXml = @simplexml_load_file($npmf);
if ($npmXml && isset($npmXml->files)) {
foreach ($npmXml->files->file as $fn) {
$nzn = pathinfo((string) $fn, PATHINFO_FILENAME);
if (!empty($nzn)) {
$nestedManifested[$nzn] = true;
}
}
}
}
// Use a subdirectory to avoid filename collisions with outer ZIPs
$nestedOutputDir = "{$outputDir}/nested_{$subName}";
@mkdir($nestedOutputDir, 0755, true);
foreach ($nestedPkgDirs as $npd) {
$nestedSubName = basename($npd);
if (!empty($nestedManifested) && !isset($nestedManifested[$nestedSubName])) {
continue;
}
$nestedSubZipPath = "{$nestedOutputDir}/{$nestedSubName}.zip";
$nsZip = new \ZipArchive();
if ($nsZip->open($nestedSubZipPath, \ZipArchive::CREATE | \ZipArchive::OVERWRITE) !== true) {
continue;
}
$this->addDirToZip($nsZip, $npd, '', $this->excludePatterns);
$nsZip->close();
$subZip->addFile($nestedSubZipPath, "packages/{$nestedSubName}.zip");
echo " Nested sub: {$nestedSubName}.zip\n";
}
// Patch nested manifest: ensure folder="packages" so Joomla finds sub-ZIPs
foreach ($nestedPkgManifests as $npmf) {
$npmContent = file_get_contents($npmf);
if ($npmContent !== false
&& strpos($npmContent, '<files>') !== false
&& strpos($npmContent, 'folder="packages"') === false
) {
$npmContent = str_replace('<files>', '<files folder="packages">', $npmContent);
file_put_contents($npmf, $npmContent);
echo " Fixed: added folder=\"packages\" to " . basename($npmf) . "\n";
}
}
// Add top-level files (manifest, script, etc.) with exclude filter
$nestedTopFiles = array_merge(
glob("{$subSourceDir}/*.xml") ?: [],
glob("{$subSourceDir}/*.php") ?: []
);
foreach ($nestedTopFiles as $ntf) {
if (!$this->isExcluded(basename($ntf), $this->excludePatterns)) {
$subZip->addFile($ntf, basename($ntf));
}
}
// Add all top-level directories except packages/
$nestedTopDirs = glob("{$subSourceDir}/*", GLOB_ONLYDIR) ?: [];
foreach ($nestedTopDirs as $ntd) {
$ndName = basename($ntd);
if ($ndName === 'packages') {
continue;
}
$this->addDirToZip($subZip, $ntd, $ndName, $this->excludePatterns);
}
} else {
$this->addDirToZip($subZip, $subSourceDir, '', $this->excludePatterns);
}
$subZip->close(); $subZip->close();
$zip->addFile($subZipPath, "packages/{$subName}.zip"); $zip->addFile($subZipPath, "packages/{$subName}.zip");
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/release_publish.php * PATH: /cli/release_publish.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Publish a release and create copies for all lesser stability streams. * BRIEF: Publish a release and create copies for all lesser stability streams.
*/ */
+1 -1
View File
@@ -12,7 +12,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/scaffold_client.php * PATH: /cli/scaffold_client.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Scaffold a new client-waas repo from Template-Client-WaaS with pre-configured settings * BRIEF: Scaffold a new client-waas repo from Template-Client-WaaS with pre-configured settings
*/ */
+294
View File
@@ -0,0 +1,294 @@
#!/usr/bin/env php
<?php
/* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
* FILE INFORMATION
* DEFGROUP: mokocli.CLI
* INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/theme_vars_check.php
* BRIEF: Validate a client MokoOnyx theme package — required CSS variables
* (derived dynamically from the MokoOnyx standard theme) are defined in
* the client's light/dark custom CSS, required files exist, the manifest
* is sane, and (optionally) the repo's Gitea metadata is set.
*
* Standalone (no CliFramework dependency) so it runs even when the shared
* framework autoloader is unavailable.
*
* Usage:
* php theme_vars_check.php --path . --reference /tmp/mokoonyx [--github-output]
* [--api-base <url> --repo <owner/repo> --token <token>]
*/
declare(strict_types=1);
$opts = getopt('', ['path:', 'reference:', 'github-output', 'api-base:', 'repo:', 'token:']);
$path = isset($opts['path']) && is_string($opts['path']) && $opts['path'] !== '' ? $opts['path'] : '.';
$ref = isset($opts['reference']) && is_string($opts['reference']) ? $opts['reference'] : '';
$gh = array_key_exists('github-output', $opts);
$root = realpath($path);
if ($root === false) { $root = $path; }
$src = is_dir("$root/src") ? "$root/src" : (is_dir("$root/source") ? "$root/source" : null);
if ($src === null) {
fwrite(STDERR, "ERROR: no src/ or source/ directory under $root\n");
exit(1);
}
$errors = 0;
$summary = [];
$fail = function (string $msg) use (&$errors, &$summary): void {
echo " [FAIL] $msg\n";
$summary[] = "FAIL: $msg";
$errors++;
};
$ok = function (string $msg): void { echo " [ok] $msg\n"; };
$note = function (string $msg): void { echo " [note] $msg\n"; };
/** Extract the set of CSS custom-property names DEFINED in a CSS string. */
$definedVars = static function (string $css): array {
// Matches "--name:" at a declaration position (not var(--name) uses).
preg_match_all('/(?:^|[\s;{])(--[a-z0-9_-]+)\s*:/i', $css, $m);
return array_values(array_unique(array_map('strtolower', $m[1] ?? [])));
};
/** Find the MokoOnyx standard theme file for a mode inside a reference checkout. */
$findStandard = static function (string $ref, string $mode): ?string {
if ($ref === '') { return null; }
foreach ([
"$ref/source/media/css/theme/$mode.standard.css",
"$ref/media/templates/site/mokoonyx/css/theme/$mode.standard.css",
"$ref/$mode.standard.css",
] as $cand) {
if (is_file($cand)) { return $cand; }
}
return null;
};
$cssDir = "$src/media/templates/site/mokoonyx/css";
$themeDir = "$cssDir/theme";
$manifest = "$src/templateDetails.xml";
$customs = ['light' => "$themeDir/light.custom.css", 'dark' => "$themeDir/dark.custom.css"];
echo "MokoOnyx theme validation: $src\n\n";
// 1) Required files -------------------------------------------------------
echo "=== Required files ===\n";
$requiredFiles = [
'templateDetails.xml' => $manifest,
'theme/light.custom.css' => $customs['light'],
'theme/dark.custom.css' => $customs['dark'],
'user.css' => "$cssDir/user.css",
];
foreach ($requiredFiles as $label => $file) {
is_file($file) ? $ok("$label present") : $fail("missing required file: $label");
}
// 1b) Forbidden committed files ------------------------------------------
echo "\n=== Forbidden files ===\n";
$scan = static function (string $dir, array $skip) use (&$scan): array {
$out = [];
foreach (scandir($dir) ?: [] as $e) {
if ($e === '.' || $e === '..') { continue; }
$p = "$dir/$e";
if (is_dir($p)) {
if (in_array($e, $skip, true)) { continue; }
$out = array_merge($out, $scan($p, $skip));
} else {
$out[] = $p;
}
}
return $out;
};
$forbidden = [];
if (is_dir("$root/.claude")) { $forbidden[] = '.claude/'; }
foreach ($scan($root, ['.git', 'vendor', 'node_modules']) as $f) {
$b = basename($f);
$rel = ltrim(str_replace('\\', '/', substr($f, strlen($root))), '/');
if ($b === '.mcp.json' || $b === 'TODO.md'
|| fnmatch('.mcp_*.json', $b) || fnmatch('sftp-config*.json', $b)
|| fnmatch('*.min.css', $b) || fnmatch('*.min.js', $b)) {
$forbidden[] = $rel;
}
}
$forbidden = array_values(array_unique($forbidden));
if ($forbidden) {
$shown = array_slice($forbidden, 0, 10);
$more = count($forbidden) - count($shown);
$fail('forbidden file(s) committed: ' . implode(', ', $shown) . ($more > 0 ? " (+$more more)" : ''));
} else {
$ok('no forbidden files committed');
}
// 2) CSS variables — required set derived from the MokoOnyx standard theme
echo "\n=== CSS variables vs MokoOnyx standard theme ===\n";
if ($ref === '') {
$note('no --reference given; skipping variable parity check');
} else {
foreach ($customs as $mode => $customFile) {
$std = $findStandard($ref, $mode);
if ($std === null) {
$fail("$mode: standard theme not found under reference '$ref'");
continue;
}
if (!is_file($customFile)) {
continue; // already reported missing
}
$required = $definedVars((string) file_get_contents($std));
$defined = $definedVars((string) file_get_contents($customFile));
$missing = array_values(array_diff($required, $defined));
if ($missing) {
$shown = array_slice($missing, 0, 15);
$more = count($missing) - count($shown);
$fail("$mode mode missing " . count($missing) . '/' . count($required)
. ' standard variable(s): ' . implode(', ', $shown) . ($more > 0 ? " (+$more more)" : ''));
} else {
$ok("$mode mode defines all " . count($required) . ' standard variables');
}
}
}
// 3) Manifest sanity ------------------------------------------------------
echo "\n=== Manifest (templateDetails.xml) ===\n";
if (is_file($manifest)) {
$xml = @simplexml_load_file($manifest);
if ($xml === false) {
$fail('templateDetails.xml is not well-formed XML');
} else {
$version = isset($xml->version) ? trim((string) $xml->version) : '';
$version !== '' ? $ok("version $version") : $fail('<version> is missing or empty');
$server = isset($xml->updateservers->server) ? trim((string) $xml->updateservers->server) : '';
if ($server === '') {
$fail('<updateservers><server> is missing');
} elseif (strpos($server, '/raw/branch/') !== false) {
$fail('update server uses a legacy raw/branch URL; use the dynamic MokoGitea feed');
} else {
$ok("update server: $server");
}
isset($xml->dlid) ? $ok('<dlid> license-key field present')
: $fail('<dlid prefix="dlid=" suffix=""/> is missing');
// Element naming convention (MokoOnyx client theme file package)
$type = trim((string) ($xml['type'] ?? ''));
$element = isset($xml->element) ? trim((string) $xml->element) : '';
if ($type === 'file' && $element !== '') {
strpos($element, 'file_mokoonyx_') === 0
? $ok("element naming ok ($element)")
: $fail("element '$element' should start with 'file_mokoonyx_' for a MokoOnyx client theme package");
}
// Required manifest fields
foreach (['name', 'element', 'author', 'creationDate'] as $field) {
(isset($xml->$field) && trim((string) $xml->$field) !== '')
? $ok("<$field> present")
: $fail("<$field> is missing or empty");
}
// scriptfile (if declared) must exist
if (isset($xml->scriptfile)) {
$sf = trim((string) $xml->scriptfile);
is_file("$src/$sf") ? $ok("scriptfile '$sf' present")
: $fail("<scriptfile> references '$sf' which is not in src/");
}
// Fileset integrity — every referenced file/folder must exist in src/
if (isset($xml->fileset)) {
$missingFs = [];
foreach ($xml->fileset->files as $files) {
$folder = trim((string) ($files['folder'] ?? ''));
$baseDir = $folder !== '' ? "$src/$folder" : $src;
foreach ($files->filename as $fn) {
$rel = ($folder !== '' ? "$folder/" : '') . trim((string) $fn);
if (!is_file("$baseDir/" . trim((string) $fn))) { $missingFs[] = $rel; }
}
foreach ($files->folder as $fd) {
$rel = ($folder !== '' ? "$folder/" : '') . trim((string) $fd) . '/';
if (!is_dir("$baseDir/" . trim((string) $fd))) { $missingFs[] = $rel; }
}
}
if ($missingFs) {
$shown = array_slice($missingFs, 0, 10);
$more = count($missingFs) - count($shown);
$fail('fileset references ' . count($missingFs) . ' missing path(s): '
. implode(', ', $shown) . ($more > 0 ? " (+$more more)" : ''));
} else {
$ok('all fileset paths exist in src/');
}
}
}
}
// 4) Repository metadata via Gitea API (optional) -------------------------
$apiBase = isset($opts['api-base']) && is_string($opts['api-base']) ? rtrim($opts['api-base'], '/') : '';
$repoSlug = isset($opts['repo']) && is_string($opts['repo']) ? trim($opts['repo']) : '';
$token = isset($opts['token']) && is_string($opts['token']) ? trim($opts['token']) : '';
if ($apiBase !== '' && $repoSlug !== '' && $token !== '') {
echo "\n=== Repository metadata (Gitea API) ===\n";
$url = "$apiBase/repos/$repoSlug";
$ctx = stream_context_create(['http' => [
'method' => 'GET',
'header' => "Authorization: token $token\r\nAccept: application/json\r\n",
'ignore_errors' => true,
'timeout' => 15,
]]);
$resp = @file_get_contents($url, false, $ctx);
$data = $resp !== false ? json_decode($resp, true) : null;
if (!is_array($data) || !isset($data['name'])) {
$fail("could not read repo metadata from Gitea API ($url)");
} else {
trim((string) ($data['description'] ?? '')) !== '' ? $ok('description set')
: $fail('repo description is empty');
trim((string) ($data['website'] ?? '')) !== '' ? $ok('website set: ' . $data['website'])
: $fail('repo website is empty');
$topics = $data['topics'] ?? [];
(is_array($topics) && count($topics) > 0) ? $ok(count($topics) . ' topic(s) set')
: $fail('repo has no topics');
// Required topics
$requiredTopics = ['joomla', 'client-waas', 'mokoonyx'];
$haveTopics = array_map('strtolower', is_array($topics) ? $topics : []);
$missingTopics = array_values(array_diff($requiredTopics, $haveTopics));
$missingTopics
? $fail('missing required topic(s): ' . implode(', ', $missingTopics))
: $ok('required topics present (' . implode(', ', $requiredTopics) . ')');
((string) ($data['default_branch'] ?? '')) === 'main' ? $ok('default branch is main')
: $fail("default branch is '" . ($data['default_branch'] ?? '') . "' (expected main)");
// Branch protection on main
$bresp = @file_get_contents("$apiBase/repos/$repoSlug/branches/main", false, $ctx);
$bdata = $bresp !== false ? json_decode($bresp, true) : null;
if (is_array($bdata) && array_key_exists('protected', $bdata)) {
$bdata['protected'] ? $ok('main branch is protected')
: $fail('main branch is not protected');
} else {
$note('could not read branch protection state for main');
}
}
} else {
echo "\n=== Repository metadata (Gitea API) ===\n";
$note('API args not provided; skipping repo metadata check');
}
// Output / exit -----------------------------------------------------------
echo "\n";
if ($gh && ($f = getenv('GITHUB_STEP_SUMMARY'))) {
$md = "## MokoOnyx Theme Validation\n\n";
$md .= $errors === 0
? "All checks passed.\n"
: implode("\n", array_map(static fn ($l) => "- $l", $summary)) . "\n";
@file_put_contents($f, $md, FILE_APPEND);
}
if ($errors > 0) {
echo "FAILED: $errors issue(s) found.\n";
exit(1);
}
echo "All MokoOnyx theme validation checks passed.\n";
exit(0);
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/updates_xml_sync.php * PATH: /cli/updates_xml_sync.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Sync updates.xml to target branches via Gitea API * BRIEF: Sync updates.xml to target branches via Gitea API
* NOTE: Called by pre-release and auto-release workflows after updates.xml * NOTE: Called by pre-release and auto-release workflows after updates.xml
* is modified on the current branch. Pushes the file to other branches * is modified on the current branch. Pushes the file to other branches
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/version_auto_bump.php * PATH: /cli/version_auto_bump.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Auto patch-bump, set stability suffix, and commit — single CLI replacing inline workflow bash * BRIEF: Auto patch-bump, set stability suffix, and commit — single CLI replacing inline workflow bash
*/ */
+8 -3
View File
@@ -214,7 +214,8 @@ class VersionBumpCli extends CliFramework
$newContent = preg_replace( $newContent = preg_replace(
$xmlPattern, $xmlPattern,
'${1}' . $newBase . '</version>', '${1}' . $newBase . '</version>',
$content $content,
1
); );
} else { } else {
$xmlPattern = '#<version>\d{2}\.\d{2}\.\d{2}' $xmlPattern = '#<version>\d{2}\.\d{2}\.\d{2}'
@@ -222,9 +223,13 @@ class VersionBumpCli extends CliFramework
$newContent = preg_replace( $newContent = preg_replace(
$xmlPattern, $xmlPattern,
"<version>{$newFull}</version>", "<version>{$newFull}</version>",
$content $content,
1
); );
} }
if ($newContent !== null) {
$newContent = preg_replace('#(\s*<version>[^<]*</version>)\s*<version>[^<]*</version>#', '$1', $newContent);
}
if ($newContent !== null && $newContent !== $content) { if ($newContent !== null && $newContent !== $content) {
file_put_contents($xmlFile, $newContent); file_put_contents($xmlFile, $newContent);
$updatedFiles[] = substr($xmlFile, strlen($root) + 1); $updatedFiles[] = substr($xmlFile, strlen($root) + 1);
@@ -384,7 +389,7 @@ class VersionBumpCli extends CliFramework
/** /**
* Scan git release tags for the highest version across all channels. * Scan git release tags for the highest version across all channels.
* *
* Checks release names like "MokoSuiteClient (VERSION: 09.41.00)" in * Checks release names like "MokoSuiteClient (VERSION: 09.43.00)" in
* git tags (stable, release-candidate, development, etc.) to find the * git tags (stable, release-candidate, development, etc.) to find the
* highest version that has been released on any channel. * highest version that has been released on any channel.
*/ */
+6 -3
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/version_check.php * PATH: /cli/version_check.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Validate version consistency across README, manifests, and sub-packages * BRIEF: Validate version consistency across README, manifests, and sub-packages
*/ */
@@ -131,9 +131,11 @@ class VersionCheckCli extends CliFramework
$updated = preg_replace( $updated = preg_replace(
$vPat, $vPat,
"<version>{$highestVersion}</version>", "<version>{$highestVersion}</version>",
$content $content,
1
); );
if ($updated !== null) { if ($updated !== null) {
$updated = preg_replace('#(\s*<version>[^<]*</version>)\s*<version>[^<]*</version>#', '$1', $updated);
file_put_contents($mokoManifest, $updated); file_put_contents($mokoManifest, $updated);
} echo " Fixed: .mokogitea/manifest.xml -> {$highestVersion}\n"; } echo " Fixed: .mokogitea/manifest.xml -> {$highestVersion}\n";
} }
@@ -185,8 +187,9 @@ class VersionCheckCli extends CliFramework
if (!file_exists($file)) { if (!file_exists($file)) {
continue; continue;
} $content = file_get_contents($file); } $content = file_get_contents($file);
$updated = preg_replace('#<version>[^<]*</version>#', "<version>{$highestVersion}</version>", $content); $updated = preg_replace('#<version>[^<]*</version>#', "<version>{$highestVersion}</version>", $content, 1);
if ($updated !== null) { if ($updated !== null) {
$updated = preg_replace('#(\s*<version>[^<]*</version>)\s*<version>[^<]*</version>#', '$1', $updated);
file_put_contents($file, $updated); file_put_contents($file, $updated);
} echo " Fixed: {$source} -> {$highestVersion}\n"; } echo " Fixed: {$source} -> {$highestVersion}\n";
} }
+5 -1
View File
@@ -164,8 +164,12 @@ class VersionSetPlatformCli extends CliFramework
$updated = preg_replace( $updated = preg_replace(
'|<version>[^<]*</version>|', '|<version>[^<]*</version>|',
"<version>{$version}</version>", "<version>{$version}</version>",
$content $content,
1
); );
if ($updated !== null) {
$updated = preg_replace('#(\s*<version>[^<]*</version>)\s*<version>[^<]*</version>#', '$1', $updated);
}
if ($updated !== null && $updated !== $content) { if ($updated !== null && $updated !== $content) {
file_put_contents($file, $updated); file_put_contents($file, $updated);
$relPath = str_replace($root . '/', '', $file); $relPath = str_replace($root . '/', '', $file);
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/wiki_sync.php * PATH: /cli/wiki_sync.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Sync select wiki pages from mokocli to all template repos * BRIEF: Sync select wiki pages from mokocli to all template repos
*/ */
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli * INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/workflow_sync.php * PATH: /cli/workflow_sync.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Sync workflows from Generic → platform templates → live repos based on manifest.platform * BRIEF: Sync workflows from Generic → platform templates → live repos based on manifest.platform
*/ */
+2 -2
View File
@@ -71,8 +71,8 @@
], ],
"scripts": { "scripts": {
"test": "phpunit", "test": "phpunit",
"phpcs": "phpcs --standard=phpcs.xml lib/ validate/ automation/", "phpcs": "phpcs --standard=phpcs.xml lib/ validate/",
"phpstan": "phpstan analyse -c phpstan.neon lib/ validate/ automation/", "phpstan": "phpstan analyse -c phpstan.neon lib/ validate/",
"psalm": "psalm --config=psalm.xml", "psalm": "psalm --config=psalm.xml",
"check": [ "check": [
"@phpcs", "@phpcs",
+3 -3
View File
@@ -8,11 +8,11 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Scripts.Deploy * DEFGROUP: MokoCLI.Scripts.Deploy
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /deploy/backup-before-deploy.php * PATH: /deploy/backup-before-deploy.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Snapshot Joomla directories before deployment for rollback capability * BRIEF: Snapshot Joomla directories before deployment for rollback capability
*/ */
+2 -2
View File
@@ -4,8 +4,8 @@
/* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech> /* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Scripts.Deploy * DEFGROUP: MokoCLI.Scripts.Deploy
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /deploy/deploy-and-verify.php * PATH: /deploy/deploy-and-verify.php
* BRIEF: Deploy with automatic health check and rollback on failure * BRIEF: Deploy with automatic health check and rollback on failure
+3 -3
View File
@@ -8,11 +8,11 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Scripts.Deploy * DEFGROUP: MokoCLI.Scripts.Deploy
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /deploy/deploy-dolibarr.php * PATH: /deploy/deploy-dolibarr.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Deploy Dolibarr module files to a remote server via SFTP/rsync * BRIEF: Deploy Dolibarr module files to a remote server via SFTP/rsync
*/ */
+2 -2
View File
@@ -8,8 +8,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Scripts.Deploy * DEFGROUP: MokoCLI.Scripts.Deploy
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /deploy/deploy-joomla.php * PATH: /deploy/deploy-joomla.php
* BRIEF: Smart Joomla deploy — routes files to correct Joomla directories based on XML manifest * BRIEF: Smart Joomla deploy — routes files to correct Joomla directories based on XML manifest
+2 -2
View File
@@ -8,8 +8,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Scripts.Deploy * DEFGROUP: MokoCLI.Scripts.Deploy
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /deploy/deploy-sftp.php * PATH: /deploy/deploy-sftp.php
* BRIEF: Deploy a repository src/ directory to a remote web server via SFTP * BRIEF: Deploy a repository src/ directory to a remote web server via SFTP
+3 -3
View File
@@ -8,11 +8,11 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Scripts.Deploy * DEFGROUP: MokoCLI.Scripts.Deploy
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /deploy/health-check.php * PATH: /deploy/health-check.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Post-deploy health check — verify a Joomla site is responding correctly * BRIEF: Post-deploy health check — verify a Joomla site is responding correctly
*/ */
+3 -3
View File
@@ -8,11 +8,11 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Scripts.Deploy * DEFGROUP: MokoCLI.Scripts.Deploy
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /deploy/rollback-joomla.php * PATH: /deploy/rollback-joomla.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Rollback a Joomla deployment by restoring from a pre-deploy snapshot * BRIEF: Rollback a Joomla deployment by restoring from a pre-deploy snapshot
*/ */
+3 -3
View File
@@ -8,11 +8,11 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Scripts.Deploy * DEFGROUP: MokoCLI.Scripts.Deploy
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /deploy/sync-joomla.php * PATH: /deploy/sync-joomla.php
* VERSION: 09.41.00 * VERSION: 09.43.00
* BRIEF: Sync Joomla site directories between two servers via rsync over SSH * BRIEF: Sync Joomla site directories between two servers via rsync over SSH
*/ */
+2 -2
View File
@@ -7,8 +7,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Scripts.Fix * DEFGROUP: MokoCLI.Scripts.Fix
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /fix/fix_line_endings.php * PATH: /fix/fix_line_endings.php
* BRIEF: CLI script to normalise CRLF/CR to LF in tracked source files * BRIEF: CLI script to normalise CRLF/CR to LF in tracked source files
+2 -2
View File
@@ -7,8 +7,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Scripts.Fix * DEFGROUP: MokoCLI.Scripts.Fix
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /fix/fix_permissions.php * PATH: /fix/fix_permissions.php
* BRIEF: CLI script to normalise file permissions (dirs 755, files 644, scripts 755) * BRIEF: CLI script to normalise file permissions (dirs 755, files 644, scripts 755)
+2 -2
View File
@@ -7,8 +7,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Scripts.Fix * DEFGROUP: MokoCLI.Scripts.Fix
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /fix/fix_tabs.php * PATH: /fix/fix_tabs.php
* BRIEF: CLI script to convert tabs to spaces in tracked source files * BRIEF: CLI script to convert tabs to spaces in tracked source files
+2 -2
View File
@@ -7,8 +7,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Scripts.Fix * DEFGROUP: MokoCLI.Scripts.Fix
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /fix/fix_trailing_spaces.php * PATH: /fix/fix_trailing_spaces.php
* BRIEF: CLI script to remove trailing whitespace from tracked source files * BRIEF: CLI script to remove trailing whitespace from tracked source files
+2 -2
View File
@@ -2,8 +2,8 @@
Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech> Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-or-later
FILE INFORMATION FILE INFORMATION
DEFGROUP: MokoPlatform.Index DEFGROUP: MokoCLI.Index
INGROUP: MokoPlatform.Fix INGROUP: MokoCLI.Fix
REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
PATH: /fix/index.md PATH: /fix/index.md
BRIEF: Fix directory index BRIEF: Fix directory index
+3 -3
View File
@@ -2,8 +2,8 @@
Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech> Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-or-later
FILE INFORMATION FILE INFORMATION
DEFGROUP: MokoPlatform.Root DEFGROUP: MokoCLI.Root
INGROUP: MokoPlatform INGROUP: MokoCLI
REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
PATH: /index.md PATH: /index.md
BRIEF: Scripts directory index BRIEF: Scripts directory index
@@ -61,7 +61,7 @@ Shared library code
- GitHub client - GitHub client
### [Wiki](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki) ### [Wiki](https://git.mokoconsulting.tech/MokoConsulting/mokocli/wiki)
All documentation lives in the Gitea wiki. All documentation lives in the MokoGitea wiki.
### [Tests](tests/) ### [Tests](tests/)
Test scripts Test scripts
+2 -2
View File
@@ -7,8 +7,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Lib * DEFGROUP: MokoCLI.Lib
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/CliBase.php * PATH: /lib/CliBase.php
* BRIEF: Standalone base CLI class for scripts that do not use CliFramework * BRIEF: Standalone base CLI class for scripts that do not use CliFramework
+2 -2
View File
@@ -7,8 +7,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Lib * DEFGROUP: MokoCLI.Lib
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Common.php * PATH: /lib/Common.php
* BRIEF: Common utility functions for scripts * BRIEF: Common utility functions for scripts
+3 -3
View File
@@ -9,8 +9,8 @@ declare(strict_types=1);
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.Plugins * DEFGROUP: MokoCLI.Enterprise.Plugins
* INGROUP: MokoPlatform.Enterprise * INGROUP: MokoCLI.Enterprise
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/AbstractProjectPlugin.php * PATH: /lib/Enterprise/AbstractProjectPlugin.php
* BRIEF: Abstract base class for project plugins * BRIEF: Abstract base class for project plugins
@@ -23,7 +23,7 @@ namespace MokoCli;
* *
* Provides common functionality for all project type plugins * Provides common functionality for all project type plugins
* *
* @package MokoPlatform\Enterprise * @package MokoCLI\Enterprise
* @version 1.0.0 * @version 1.0.0
*/ */
abstract class AbstractProjectPlugin implements ProjectPluginInterface abstract class AbstractProjectPlugin implements ProjectPluginInterface
+3 -3
View File
@@ -9,8 +9,8 @@ declare(strict_types=1);
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.API * DEFGROUP: MokoCLI.Enterprise.API
* INGROUP: MokoPlatform.Enterprise * INGROUP: MokoCLI.Enterprise
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/ApiClient.php * PATH: /lib/Enterprise/ApiClient.php
* BRIEF: HTTP API client library * BRIEF: HTTP API client library
@@ -31,7 +31,7 @@ declare(strict_types=1);
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* @package MokoPlatform\Enterprise * @package MokoCLI\Enterprise
* @version 04.00.04 * @version 04.00.04
* @author mokocli Team * @author mokocli Team
* @license GPL-3.0-or-later * @license GPL-3.0-or-later
+3 -3
View File
@@ -22,13 +22,13 @@ declare(strict_types=1);
* (at your option) any later version. * (at your option) any later version.
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.Audit * DEFGROUP: MokoCLI.Enterprise.Audit
* INGROUP: MokoPlatform.Enterprise * INGROUP: MokoCLI.Enterprise
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/AuditLogger.php * PATH: /lib/Enterprise/AuditLogger.php
* BRIEF: Enterprise audit logging * BRIEF: Enterprise audit logging
* *
* @package MokoPlatform\Enterprise * @package MokoCLI\Enterprise
* @version 04.00.04 * @version 04.00.04
* @author mokocli Team * @author mokocli Team
* @license GPL-3.0-or-later * @license GPL-3.0-or-later
+3 -3
View File
@@ -10,13 +10,13 @@ declare(strict_types=1);
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.Checkpoint * DEFGROUP: MokoCLI.Enterprise.Checkpoint
* INGROUP: MokoPlatform.Enterprise * INGROUP: MokoCLI.Enterprise
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/CheckpointManager.php * PATH: /lib/Enterprise/CheckpointManager.php
* BRIEF: Checkpoint manager for resumable operations * BRIEF: Checkpoint manager for resumable operations
* *
* @package MokoPlatform\Enterprise * @package MokoCLI\Enterprise
* @version 04.00.04 * @version 04.00.04
* @author mokocli Team * @author mokocli Team
* @license GPL-3.0-or-later * @license GPL-3.0-or-later
+2 -2
View File
@@ -7,8 +7,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.CLI * DEFGROUP: MokoCLI.Enterprise.CLI
* INGROUP: MokoPlatform.Enterprise * INGROUP: MokoCLI.Enterprise
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/CliFramework.php * PATH: /lib/Enterprise/CliFramework.php
* BRIEF: CliFramework — unified base class for all mokocli CLI scripts * BRIEF: CliFramework — unified base class for all mokocli CLI scripts
+3 -3
View File
@@ -9,8 +9,8 @@ declare(strict_types=1);
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.Config * DEFGROUP: MokoCLI.Enterprise.Config
* INGROUP: MokoPlatform.Enterprise * INGROUP: MokoCLI.Enterprise
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/Config.php * PATH: /lib/Enterprise/Config.php
* BRIEF: Configuration manager * BRIEF: Configuration manager
@@ -32,7 +32,7 @@ declare(strict_types=1);
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* @package MokoPlatform\Enterprise * @package MokoCLI\Enterprise
* @version 04.00.04 * @version 04.00.04
* @author mokocli Team * @author mokocli Team
* @license GPL-3.0-or-later * @license GPL-3.0-or-later
+2 -2
View File
@@ -7,8 +7,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise * DEFGROUP: MokoCLI.Enterprise
* INGROUP: MokoPlatform.Enterprise * INGROUP: MokoCLI.Enterprise
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/ConfigValidator.php * PATH: /lib/Enterprise/ConfigValidator.php
* BRIEF: Validate project config against plugin JSON schema * BRIEF: Validate project config against plugin JSON schema
@@ -8,8 +8,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise * DEFGROUP: MokoCLI.Enterprise
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/EnterpriseReadinessValidator.php * PATH: /lib/Enterprise/EnterpriseReadinessValidator.php
* BRIEF: Enterprise readiness validation library * BRIEF: Enterprise readiness validation library
+3 -3
View File
@@ -17,13 +17,13 @@ declare(strict_types=1);
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.Recovery * DEFGROUP: MokoCLI.Enterprise.Recovery
* INGROUP: MokoPlatform.Enterprise * INGROUP: MokoCLI.Enterprise
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/ErrorRecovery.php * PATH: /lib/Enterprise/ErrorRecovery.php
* BRIEF: Error recovery framework * BRIEF: Error recovery framework
* *
* @package MokoPlatform\Enterprise * @package MokoCLI\Enterprise
* @version 04.00.04 * @version 04.00.04
* @author mokocli Team * @author mokocli Team
* @license GPL-3.0-or-later * @license GPL-3.0-or-later
+2 -2
View File
@@ -7,8 +7,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise * DEFGROUP: MokoCLI.Enterprise
* INGROUP: MokoPlatform.Lib * INGROUP: MokoCLI.Lib
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/FileFixUtility.php * PATH: /lib/Enterprise/FileFixUtility.php
* BRIEF: Utility class for fixing file formatting issues (line endings, permissions, tabs, trailing spaces) * BRIEF: Utility class for fixing file formatting issues (line endings, permissions, tabs, trailing spaces)
+3 -3
View File
@@ -7,8 +7,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.Platform * DEFGROUP: MokoCLI.Enterprise.Platform
* INGROUP: MokoPlatform.Enterprise * INGROUP: MokoCLI.Enterprise
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/GitHubAdapter.php * PATH: /lib/Enterprise/GitHubAdapter.php
* BRIEF: GitHub implementation of GitPlatformAdapter * BRIEF: GitHub implementation of GitPlatformAdapter
@@ -31,7 +31,7 @@ use RuntimeException;
* - Topics: PUT with {"names": [...]} * - Topics: PUT with {"names": [...]}
* - Workflow dir: .github/workflows * - Workflow dir: .github/workflows
* *
* @package MokoPlatform\Enterprise * @package MokoCLI\Enterprise
* @since 04.06.10 * @since 04.06.10
* @see GitPlatformAdapter * @see GitPlatformAdapter
*/ */
+3 -3
View File
@@ -7,8 +7,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.Platform * DEFGROUP: MokoCLI.Enterprise.Platform
* INGROUP: MokoPlatform.Enterprise * INGROUP: MokoCLI.Enterprise
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/GitPlatformAdapter.php * PATH: /lib/Enterprise/GitPlatformAdapter.php
* BRIEF: Interface defining all git platform operations for GitHub/Gitea abstraction * BRIEF: Interface defining all git platform operations for GitHub/Gitea abstraction
@@ -25,7 +25,7 @@ namespace MokoCli;
* Implementations exist for GitHub (GitHubAdapter) and Gitea (MokoGiteaAdapter), * Implementations exist for GitHub (GitHubAdapter) and Gitea (MokoGiteaAdapter),
* allowing scripts to work against either platform transparently. * allowing scripts to work against either platform transparently.
* *
* @package MokoPlatform\Enterprise * @package MokoCLI\Enterprise
* @version 04.06.10 * @version 04.06.10
*/ */
interface GitPlatformAdapter interface GitPlatformAdapter
+3 -3
View File
@@ -9,8 +9,8 @@ declare(strict_types=1);
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.Validation * DEFGROUP: MokoCLI.Enterprise.Validation
* INGROUP: MokoPlatform.Enterprise * INGROUP: MokoCLI.Enterprise
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/InputValidator.php * PATH: /lib/Enterprise/InputValidator.php
* BRIEF: Input validation library * BRIEF: Input validation library
@@ -31,7 +31,7 @@ declare(strict_types=1);
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* @package MokoPlatform\Enterprise * @package MokoCLI\Enterprise
* @version 04.00.04 * @version 04.00.04
* @author mokocli Team * @author mokocli Team
* @license GPL-3.0-or-later * @license GPL-3.0-or-later
+3 -3
View File
@@ -8,8 +8,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise * DEFGROUP: MokoCLI.Enterprise
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/ManifestParser.php * PATH: /lib/Enterprise/ManifestParser.php
* BRIEF: Parser for the XML-based manifest.xml repository manifest * BRIEF: Parser for the XML-based manifest.xml repository manifest
@@ -28,7 +28,7 @@ use SimpleXMLElement;
* Reads, writes, and validates the manifest.xml repository manifest. * Reads, writes, and validates the manifest.xml repository manifest.
* The file uses XML format (no file extension) and lives at .mokogitea/manifest.xml. * The file uses XML format (no file extension) and lives at .mokogitea/manifest.xml.
* *
* @package MokoPlatform\Enterprise * @package MokoCLI\Enterprise
* @version 04.07.00 * @version 04.07.00
*/ */
class ManifestParser class ManifestParser
+3 -3
View File
@@ -9,8 +9,8 @@ declare(strict_types=1);
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.Metrics * DEFGROUP: MokoCLI.Enterprise.Metrics
* INGROUP: MokoPlatform.Enterprise * INGROUP: MokoCLI.Enterprise
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/MetricsCollector.php * PATH: /lib/Enterprise/MetricsCollector.php
* BRIEF: Metrics collection framework * BRIEF: Metrics collection framework
@@ -46,7 +46,7 @@ declare(strict_types=1);
* *
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* @package MokoPlatform\Enterprise * @package MokoCLI\Enterprise
* @version 04.00.04 * @version 04.00.04
* @author mokocli Team * @author mokocli Team
* @license GPL-3.0-or-later * @license GPL-3.0-or-later
+3 -3
View File
@@ -7,8 +7,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.Platform * DEFGROUP: MokoCLI.Enterprise.Platform
* INGROUP: MokoPlatform.Enterprise * INGROUP: MokoCLI.Enterprise
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/MokoGiteaAdapter.php * PATH: /lib/Enterprise/MokoGiteaAdapter.php
* BRIEF: Gitea implementation of GitPlatformAdapter * BRIEF: Gitea implementation of GitPlatformAdapter
@@ -33,7 +33,7 @@ use RuntimeException;
* - Branch protection: flat API (not rulesets) * - Branch protection: flat API (not rulesets)
* - Workflow dir: .mokogitea/workflows * - Workflow dir: .mokogitea/workflows
* *
* @package MokoPlatform\Enterprise * @package MokoCLI\Enterprise
* @since 04.06.10 * @since 04.06.10
* @see GitPlatformAdapter * @see GitPlatformAdapter
*/ */
+2 -2
View File
@@ -7,8 +7,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise * DEFGROUP: MokoCLI.Enterprise
* INGROUP: MokoPlatform.Lib * INGROUP: MokoCLI.Lib
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/PackageBuilder.php * PATH: /lib/Enterprise/PackageBuilder.php
* BRIEF: Builds release packages for generic, Dolibarr module, and Joomla component projects * BRIEF: Builds release packages for generic, Dolibarr module, and Joomla component projects
+3 -3
View File
@@ -7,8 +7,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.Platform * DEFGROUP: MokoCLI.Enterprise.Platform
* INGROUP: MokoPlatform.Enterprise * INGROUP: MokoCLI.Enterprise
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/PlatformAdapterFactory.php * PATH: /lib/Enterprise/PlatformAdapterFactory.php
* BRIEF: Factory for creating platform-specific GitPlatformAdapter instances * BRIEF: Factory for creating platform-specific GitPlatformAdapter instances
@@ -33,7 +33,7 @@ use RuntimeException;
* $repos = $adapter->listOrgRepos('mokoconsulting-tech'); * $repos = $adapter->listOrgRepos('mokoconsulting-tech');
* ``` * ```
* *
* @package MokoPlatform\Enterprise * @package MokoCLI\Enterprise
* @version 04.06.10 * @version 04.06.10
* *
* @since 04.00.00 * @since 04.00.00
+3 -3
View File
@@ -9,8 +9,8 @@ declare(strict_types=1);
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.Plugins * DEFGROUP: MokoCLI.Enterprise.Plugins
* INGROUP: MokoPlatform.Enterprise * INGROUP: MokoCLI.Enterprise
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/PluginFactory.php * PATH: /lib/Enterprise/PluginFactory.php
* BRIEF: Plugin factory for project type detection * BRIEF: Plugin factory for project type detection
@@ -23,7 +23,7 @@ namespace MokoCli;
* *
* Provides convenient methods for plugin instantiation with dependency injection * Provides convenient methods for plugin instantiation with dependency injection
* *
* @package MokoPlatform\Enterprise * @package MokoCLI\Enterprise
* @version 1.0.0 * @version 1.0.0
*/ */
class PluginFactory class PluginFactory
+3 -3
View File
@@ -9,8 +9,8 @@ declare(strict_types=1);
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.Plugins * DEFGROUP: MokoCLI.Enterprise.Plugins
* INGROUP: MokoPlatform.Enterprise * INGROUP: MokoCLI.Enterprise
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/PluginRegistry.php * PATH: /lib/Enterprise/PluginRegistry.php
* BRIEF: Plugin registry for available project plugins * BRIEF: Plugin registry for available project plugins
@@ -35,7 +35,7 @@ use MokoCli\Plugins\McpServerPlugin;
* *
* Manages plugin discovery, registration, and lifecycle * Manages plugin discovery, registration, and lifecycle
* *
* @package MokoPlatform\Enterprise * @package MokoCLI\Enterprise
* @version 1.0.0 * @version 1.0.0
*/ */
class PluginRegistry class PluginRegistry
+2 -2
View File
@@ -8,8 +8,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.Plugins * DEFGROUP: MokoCLI.Enterprise.Plugins
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/Plugins/ApiPlugin.php * PATH: /lib/Enterprise/Plugins/ApiPlugin.php
* BRIEF: Enterprise plugin for API/Microservices projects * BRIEF: Enterprise plugin for API/Microservices projects
@@ -8,8 +8,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.Plugins * DEFGROUP: MokoCLI.Enterprise.Plugins
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/Plugins/DocumentationPlugin.php * PATH: /lib/Enterprise/Plugins/DocumentationPlugin.php
* BRIEF: Enterprise plugin for documentation projects * BRIEF: Enterprise plugin for documentation projects
+2 -2
View File
@@ -8,8 +8,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.Plugins * DEFGROUP: MokoCLI.Enterprise.Plugins
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/Plugins/DolibarrPlugin.php * PATH: /lib/Enterprise/Plugins/DolibarrPlugin.php
* BRIEF: Enterprise plugin for Dolibarr modules * BRIEF: Enterprise plugin for Dolibarr modules
+2 -2
View File
@@ -8,8 +8,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.Plugins * DEFGROUP: MokoCLI.Enterprise.Plugins
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/Plugins/GenericPlugin.php * PATH: /lib/Enterprise/Plugins/GenericPlugin.php
* BRIEF: Enterprise plugin for generic projects * BRIEF: Enterprise plugin for generic projects
+2 -2
View File
@@ -8,8 +8,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
* *
* FILE INFORMATION * FILE INFORMATION
* DEFGROUP: MokoPlatform.Enterprise.Plugins * DEFGROUP: MokoCLI.Enterprise.Plugins
* INGROUP: MokoPlatform * INGROUP: MokoCLI
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /lib/Enterprise/Plugins/JoomlaPlugin.php * PATH: /lib/Enterprise/Plugins/JoomlaPlugin.php
* BRIEF: Enterprise plugin for Joomla projects * BRIEF: Enterprise plugin for Joomla projects

Some files were not shown because too many files have changed in this diff Show More