@mokoenterprises/mokossh-mcp 3.8.1 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.mokogit/ISSUE_TEMPLATE/config.yml +4 -4
- package/.mokogit/ISSUE_TEMPLATE/feature_request.md +1 -1
- package/.mokogit/ISSUE_TEMPLATE/security.md +1 -1
- package/.mokogit/actions/resolve-source-dir/action.yml +1 -1
- package/.mokogit/workflows/apidocs.yml +6 -6
- package/.mokogit/workflows/auto-assign.yml +1 -1
- package/.mokogit/workflows/auto-dev-issue.yml +2 -2
- package/.mokogit/workflows/auto-release.yml +202 -33
- package/.mokogit/workflows/branch-cleanup.yml +3 -3
- package/.mokogit/workflows/ci-issue-reporter.yml +5 -5
- package/.mokogit/workflows/cleanup.yml +3 -3
- package/.mokogit/workflows/makefile-lint.yml +48 -17
- package/.mokogit/workflows/npm-build-test.yml +8 -8
- package/.mokogit/workflows/npm-sdk-check.yml +1 -1
- package/.mokogit/workflows/npm-tool-inventory.yml +2 -2
- package/.mokogit/workflows/pr-branch-check.yml +92 -92
- package/.mokogit/workflows/pre-release.yml +208 -15
- package/.mokogit/workflows/rc-revert.yml +3 -3
- package/AGENTS.md +3 -3
- package/CHANGELOG.md +1 -1
- package/CONTRIBUTING.md +6 -6
- package/Makefile +3 -2
- package/README.md +20 -20
- package/SECURITY.md +2 -2
- package/package.json +9 -8
- package/source/token-reader.js +1 -1
- package/tools/deploy.mjs +27 -0
- package/.mokogit/workflows/cascade.yml +0 -645
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
blank_issues_enabled: true
|
|
3
3
|
contact_links:
|
|
4
4
|
- name: 💼 Enterprise Support
|
|
5
|
-
url: https://
|
|
5
|
+
url: https://mokoenterprises.us/enterprise
|
|
6
6
|
about: Enterprise-level support and consultation services
|
|
7
7
|
- name: 💬 Ask a Question
|
|
8
|
-
url: https://
|
|
8
|
+
url: https://mokoenterprises.us/
|
|
9
9
|
about: Get help or ask questions through our website
|
|
10
10
|
- name: 📚 MokoCLI Documentation
|
|
11
|
-
url: https://git.
|
|
11
|
+
url: https://git.mokoenterprises.us/MokoEnterprises/mokocli
|
|
12
12
|
about: View our coding standards and best practices
|
|
13
13
|
- name: 🔒 Report a Security Vulnerability
|
|
14
|
-
url: https://git.
|
|
14
|
+
url: https://git.mokoenterprises.us/MokoEnterprises/.github-private/security/advisories/new
|
|
15
15
|
about: Report security vulnerabilities privately (for critical issues)
|
|
16
16
|
- name: 💡 Community Discussions
|
|
17
17
|
url: https://github.com/orgs/mokoconsulting-tech/discussions
|
|
@@ -37,7 +37,7 @@ If you have ideas about how this could be implemented, share them here:
|
|
|
37
37
|
Add any other context, mockups, or screenshots about the feature request here.
|
|
38
38
|
|
|
39
39
|
## Relevant Standards
|
|
40
|
-
Does this relate to any standards in [MokoCLI](https://git.
|
|
40
|
+
Does this relate to any standards in [MokoCLI](https://git.mokoenterprises.us/MokoEnterprises/mokocli)?
|
|
41
41
|
- [ ] Accessibility (WCAG 2.1 AA)
|
|
42
42
|
- [ ] Localization (en_US/en_GB)
|
|
43
43
|
- [ ] Security best practices
|
|
@@ -35,7 +35,7 @@ Use this template only for:
|
|
|
35
35
|
<!-- Describe how this could be addressed -->
|
|
36
36
|
|
|
37
37
|
## Standards Reference
|
|
38
|
-
Does this relate to security standards in [MokoCLI](https://git.
|
|
38
|
+
Does this relate to security standards in [MokoCLI](https://git.mokoenterprises.us/MokoEnterprises/mokocli)?
|
|
39
39
|
- [ ] SPDX license identifiers
|
|
40
40
|
- [ ] Secret management
|
|
41
41
|
- [ ] Dependency security
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# Copyright (C) 2026 Moko
|
|
1
|
+
# Copyright (C) 2026 Moko Enterprises <hello@mokoenterprises.us>
|
|
2
2
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
3
3
|
#
|
|
4
4
|
# FILE INFORMATION
|
|
5
5
|
# DEFGROUP: MokoGIT.Workflow
|
|
6
6
|
# INGROUP: MokoCLI.Universal
|
|
7
|
-
# REPO: https://git.
|
|
7
|
+
# REPO: https://git.mokoenterprises.us/MokoEnterprises/Template-Generic
|
|
8
8
|
# PATH: /.mokogit/workflows/apidocs.yml
|
|
9
9
|
#
|
|
10
10
|
# apidocs.yml — UNIVERSAL API-docs → wiki (synced to every repo via the universal
|
|
@@ -62,9 +62,9 @@ jobs:
|
|
|
62
62
|
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 || true
|
|
63
63
|
fi
|
|
64
64
|
rm -rf /tmp/mokocli
|
|
65
|
-
REG='{"type":"composer","url":"https://git.
|
|
65
|
+
REG='{"type":"composer","url":"https://git.mokoenterprises.us/api/packages/MokoEnterprises/composer"}'
|
|
66
66
|
if composer create-project --no-install --no-interaction --no-progress --quiet \
|
|
67
|
-
--repository="${REG}"
|
|
67
|
+
--repository="${REG}" mokoenterprises/mokocli /tmp/mokocli >/dev/null 2>&1 \
|
|
68
68
|
&& [ -f /tmp/mokocli/cli/docs_php_reference.php ]; then
|
|
69
69
|
echo "MOKO_CLI=/tmp/mokocli/cli" >> "$GITHUB_ENV"
|
|
70
70
|
echo "Installed mokocli fresh from the Composer registry."
|
|
@@ -128,12 +128,12 @@ jobs:
|
|
|
128
128
|
if [ -z "$TOKEN" ]; then echo "::warning::no MOKOGIT_TOKEN — skipping wiki publish"; exit 0; fi
|
|
129
129
|
REPO="${{ github.event.repository.name }}"; OWNER="${{ github.repository_owner }}"
|
|
130
130
|
rm -rf /tmp/wiki
|
|
131
|
-
if ! git clone -q "https://x-access-token:${TOKEN}@git.
|
|
131
|
+
if ! git clone -q "https://x-access-token:${TOKEN}@git.mokoenterprises.us/${OWNER}/${REPO}.wiki.git" /tmp/wiki 2>/dev/null; then
|
|
132
132
|
echo "::warning::wiki clone failed (wiki may not be initialised) — skipping"; exit 0
|
|
133
133
|
fi
|
|
134
134
|
cp "$FILE" "/tmp/wiki/${PAGE}.md"
|
|
135
135
|
cd /tmp/wiki
|
|
136
|
-
git config user.name "Moko
|
|
136
|
+
git config user.name "Moko Enterprises"; git config user.email "hello@mokoenterprises.us"
|
|
137
137
|
git add -A
|
|
138
138
|
if git diff --cached --quiet; then echo "wiki already up to date"; exit 0; fi
|
|
139
139
|
git commit -q -m "docs(wiki): update ${PAGE} (moko ${{ steps.gen.outputs.kind }} docs) [skip ci]"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Copyright (C) 2026 Moko
|
|
1
|
+
# Copyright (C) 2026 Moko Enterprises <hello@mokoenterprises.us>
|
|
2
2
|
#
|
|
3
|
-
# This file is part of a Moko
|
|
3
|
+
# This file is part of a Moko Enterprises project.
|
|
4
4
|
#
|
|
5
5
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
6
6
|
#
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
# Copyright (C) 2026 Moko
|
|
1
|
+
# Copyright (C) 2026 Moko Enterprises <hello@mokoenterprises.us>
|
|
2
2
|
#
|
|
3
3
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
4
|
#
|
|
5
5
|
# FILE INFORMATION
|
|
6
6
|
# DEFGROUP: MokoGIT.Workflow
|
|
7
7
|
# INGROUP: MokoCLI.Release
|
|
8
|
-
# REPO: https://git.
|
|
8
|
+
# REPO: https://git.mokoenterprises.us/MokoEnterprises/Template-Generic
|
|
9
9
|
# PATH: /.mokogit/workflows/auto-release.yml
|
|
10
|
-
# VERSION: 07.
|
|
11
|
-
# BRIEF: NEW (07.24.00): npmjs.org publish now FAILS LOUD (::error:: + exit $rc) on an AUTHORIZATION error (404 "not in this registry" / 401 / 403 / ENEEDAUTH / EOTP) instead of swallowing EVERY failure as a non-failing ::warning:: — a missing-scope / unauthorized / revoked / expired NPM_TOKEN previously hid behind a green release fleet-wide (the "secondary registry, not failing the run" catch masked a 404 PUT, which is exactly how npm reports an unauthorized scoped write; CI had in fact NEVER successfully published any MCP package to npmjs while every run reported success). Transient/5xx/network failures still stay a non-failing ::warning:: (npmjs is the SECONDARY mirror; the MokoGIT registry is primary and already hard-fails), and an unset NPM_TOKEN still skips cleanly — so repos that do not publish to npmjs are 100% unaffected. PREVIOUS (07.23.00): "Vendor PHP dependencies (build-time)" added to BOTH publish legs (promote-rc + stable) — this workflow had NO build-time composer vendoring at all, so any component declaring runtime PHP deps via a sub-package composer.json (vendor-dir admin/vendor, e.g. mPDF in MokonyxCRM/MokonyxCRMDCM) shipped its rc/stable zip WITHOUT admin/vendor while the component manifest lists <folder>vendor</folder> — JInstaller then aborts the ENTIRE package install on-site ("File does not exist [ROOT][TMP]/.../admin/vendor" → "Failed to copy administrator files"). The step mirrors pre-release.yml 07.15.00: no-op without a sub-package composer.json; provisions ext-gd when missing (the release runners' php-cli lacks it, which failed mpdf dependency RESOLUTION outright); verifies the CONFIGURED vendor-dir (composer config vendor-dir) materialized autoload.php; FAILS the build loud when vendoring fails for a package whose manifest ships <folder>vendor</folder> (a green build with an install-bricking artifact is strictly worse than a red build); fail-soft warning for packages whose manifests do not reference vendor/. Runs before `moko publish` (release_publish.php → release_package.php zips the plain working tree; vendor/ was never excluded — the tree simply never had it in CI). PREVIOUS (07.22.00): #498 — the #469 SRC_DIR gate no longer self-traps, and the fast-merge guard is MINOR-identity aware (fixes stable version never advancing; MokoCLI stuck re-publishing v10.20.00). (1) The gate read SRC_DIR with grep|sed, capturing the LITERAL unexpanded `$(shell …)` from the fleet-standard `SRC_DIR := $(shell [ -d src ] && echo src || echo source)` — an unmatchable directory that forced should_bump=false on EVERY push even when source changed. It now resolves SRC_DIR via `make --eval` expansion, falls back to the grep|sed read only if make is unavailable, nulls out a still-unexpanded `$(...)`/backtick value, and treats a declared-but-NONEXISTENT SRC_DIR (repos with code in cli/lib/bin, not src/source) as the non-source denylist fallback instead of an unmatchable INCLUSION prefix. (2) The "Guarantee monotonic release version (fast-merge bump guard)" compared the FULL version, so dev's per-merge PATCH bumps (10.20.00→10.20.04) fooled it into "normal path, no heal" and it re-published the already-released vMAJOR.MINOR.00. It now compares the MINOR identity (MAJOR.MINOR), so a fast dev→stable merge with no promote-rc cuts a new MINOR. Fleet-wide release-semantics change — validate on one repo before syncing. PREVIOUS (07.21.00): #469 — gate the version BUMP on whether the push touched the Makefile SRC_DIR. The former non-code paths-ignore denylist on the push trigger is REMOVED: a docs/workflow/sample push no longer skips the pipeline, it now RUNS in no-bump "update the existing stable release in place" mode (re-stamps the UNCHANGED current version via the existing `moko publish --bump none --no-commit`, refreshes notes/assets, no version advance, no new vNN tag). A new early step "Resolve SRC_DIR bump gate (#469)" (id: srcgate) decides should_bump: (1) ELECTRON (file-detected) or opt-out vars.RELEASE_SRCDIR_GATE=off -> BYPASS, always bump as today (electron has NO source dir, so a naive SRC_DIR test would never bump — a release-breaking trap); (2) else SRC_DIR is REQUIRED — a non-electron repo with no resolvable SRC_DIR FAILS LOUD (::error:: + exit 1), never silently never-bump; (3) else diff the push range (github.event.before..GITHUB_SHA, with a HEAD^1 / merge-base fallback) intersected with ${SRC_DIR}/ — source hit -> should_bump=true, none -> should_bump=false. workflow_dispatch always bumps. The self-heal monotonic bump + the new vNN semver tag are now gated on should_bump!='false' so no-bump mode keeps the version PUT; the publish + "Update release notes and reconcile changelog" (channel-pointer resolution) run on BOTH paths to refresh the current release. Loop-safety is unchanged: the job if: still re-checks [skip ci]/[skip sync], so the workflow's own commits never re-trigger. Fleet-wide release-semantics change — validate on one repo before syncing. PREVIOUS (07.20.00): the dev/promote bump + release steps now name the per-run token env var GITHUB_TOKEN (was the misleadingly-named MOKOGIT_TOKEN; the VALUE was always ${{ github.token }}). All token use in this workflow is SAME-REPO (release API, the release_bump_dev dev base bump, pushes to its own repo) — the org MOKOGIT_TOKEN secret is not referenced here. Naming-only; no behavior change. Mirrors the pre-release.yml fix (MokoGIT#1721). PREVIOUS: NEW (07.19.00): #1621 Phase 6 / .mokogit-private#76 — resolve the CURRENT stable release by its CHANNEL POINTER, not by a fixed tag_name=stable. Under version-primary releases (a release is born with the immutable tag_name=vNN and `stable`/`rc` attached as movable is_channel tags), GET /releases/tags/stable no longer resolves the current stable release, which would break two steps that read "the last released version". Both now call GET /repos/{owner}/{repo}/releases/channel/stable (#1702 — resolves whichever release the `stable` channel points at via ReleaseStreamMap) with a GRACEFUL FALLBACK to the legacy GET /releases/tags/stable for forges predating #1702 (the channel route 404s pre-rollout and the rolling `stable` tag still exists). (1) The monotonic-version guard ("Guarantee monotonic release version") resolves ROLLING_LAST by parsing the same `VERSION: NN.NN.NN` out of the channel-resolved release NAME. (2) "Update release notes and reconcile changelog" resolves the stable RELEASE_ID + VERSION the same channel-first way. The #386 integrity gate is UNCHANGED (it already keys off the immutable vNN version tag). SEQUENCING unchanged: do NOT enable in prod until #1702 server support is on stable/prod; works pre-#1702 via the fallback. PREVIOUS (07.18.00): #1621 Phase 6 — version/* BRANCHES retired in favor of dual-tagged version RELEASES. REMOVED three now-redundant steps: "Step 12: Create version branch from main", "Step 13: Prune superseded-major version branches", and "Advance rolling channel tag via git". A release's permanent version identity is now the git tag v<version>, attached by the publish as a MOVABLE channel tag on the dual-tagged release (MokoCLI release_publish -> release_create channel_tags[]/update_stream; the forge attaches/moves the tag at the release commit via AttachChannelTag server-side) — so a new cut is born dual-tagged (rolling `stable`/`release-candidate` primary tag + permanent v<version> channel tag) and the channel tag MOVES onto the new release instead of a new version/* branch being created. The rolling `stable` tag is still pinned by release_create forceTagRef() (#808), so the "Advance rolling channel tag" force-push was redundant. KEPT UNCHANGED: "Create semver tag" (v<version>), the #386 integrity gate (still resolves tags/stable to the built commit), and the monotonic guard (still reads the stable release name VERSION: NN.NN.NN). Pruning EXISTING version/* branches is a SEPARATE one-time manual reconcile — not done here. SEQUENCING: do NOT enable in prod until the #1621 SERVER channel_tags support is on stable/prod. PREVIOUS (07.17.00): Setup MokoCLI tools no longer installs a STALE mokocli during the registry publish-lag window (#1671). After the fresh registry install, the step now compares the installed /tmp/mokocli PROJECT_VERSION against the /opt/mokocli failsafe and PREFERS whichever is NEWER (sort -V), and the opportunistic /opt refresh is gated to only move FORWARD (never downgrade /opt when it is the newer, just-deployed copy). Backward-compatible: runners with no /opt/mokocli use the registry copy exactly as before. PREVIOUS (07.16.00): release-integrity + dev-channel fixes. (1) A new pre-publish "no stale (pre-merge) tree" guard (#428/MokoCLI#901) hard-FAILS the release if the triggering GITHUB_SHA is an ANCESTOR of the current branch tip (a concurrent merge landed mid-run) -- otherwise a green, version-bumped release silently ships old code missing that merge (reproduced: built ef8c1a5d while tip was 2740342). Fail-open on any unresolved/replica-lagged tip so a good release is never falsely blocked. Complements the mokocli engine assertion (packaged-tree == GITHUB_SHA), which cannot see that GITHUB_SHA itself trails the tip. (2) The "Post-release: Reset dev version" safety-net (#309/MokoCLI#900) no longer swallows failure: a failed dev-advance now emits ::error:: + a job-summary block (dev-channel would trail stable), and a SUCCESSFUL advance dispatches pre-release.yml (development) to actually publish the leading dev build -- the advance commit is [skip ci]+paths-ignored and never auto-fires. Stays green (continue-on-error) since stable already published. NEW (07.15.00): the rolling stable channel tag is now advanced via a git force-push BEFORE the #386 integrity gate. MokoGIT's tags API 405s on the release-attached `stable` tag, so release_publish.php could not move it ("Could not pin tag stable ... HTTP 405") and every Joomla/electron stable cut left the tag lagging the freshly-built commit -- red-failing a correct release on the integrity gate. A new step git-force-pushes refs/tags/stable to the built HEAD (force-push allowlist -- the same escape hatch the rc BRANCH pin already uses), so the gate passes and no manual tag repoint is needed. PREVIOUS (07.14.00): integrity gate #386 no longer false-fails. It compared the published tag against GITHUB_SHA (the triggering commit), but the publish step commits the CHANGELOG entry ("build NN.NN.NN [skip ci]") and mokocli pins the channel tag + semver tag to that POST-PUBLISH HEAD -- so every cut whose CHANGELOG wasn't pre-seeded on dev (e.g. a version set straight on the release branch) diverged by one commit and red-failed a correct release. The gate now compares against the actual built/published HEAD (git rev-parse HEAD, falling back to GITHUB_SHA), which equals what the tag is pinned to in both the commit and no-commit cases while still catching a tag pinned to a commit we did NOT build; the semver tag is pinned to the same built HEAD for consistency. PREVIOUS (07.13.00): RC is ON-DEMAND ONLY. The `pull_request` trigger (RC-preview on a PR to main/stable) is REMOVED and the promote-rc job now runs solely on workflow_dispatch action=promote-rc. Only dev + stable release automatically (dev via pre-release.yml push->dev; stable via the push->main release job here); alpha/beta/rc never auto-cut. PREVIOUS (07.12.00): electron repos create NO release on ANY channel (RC enabled=false + stable publish/tag/notes/integrity guarded on is_electron; opt back in with vars.ELECTRON_CI_BUILD=true) and build NO installer in CI — always built locally + uploaded manually; the dev/promote version BUMP still runs. Template-Generic #390. NEW (07.11.00): the electron installer build/attach steps (electron-builder via Wine/Xvfb) are gated to MANUAL workflow_dispatch only (`&& github.event_name == 'workflow_dispatch'`). An automatic push no longer auto-builds electron installers (heavy ~90m, runner-fragile — OOM/Wine-zombie; migrating to mokocli ElectronPackager, MokoCLI #756/#758). The version bump, CHANGELOG, tag and npm publish STILL run on push — only the electron installer is skipped and pushed MANUALLY via dispatch. Non-electron platforms (joomla/go/npm) unaffected. Template-Generic #390. Universal build & release - BUMP-ON-DEV: base version + CHANGELOG promoted on dev pre-promotion (promote-rc), main publishes --bump none --no-commit so it never diverges from dev. MokoCLI build agent (moko publish). NEW (07.06.00): npm stable publishing ABSORBED here from Template-NPM's retired npm-publish.yml as npm-gated dual-registry steps (MokoGIT registry via per-run token + npmjs.org best-effort), replacing the former npm-publish.yml dispatch. No-Makefile repos SKIP the release job gracefully (green) instead of failing. Conflict-marker scan reads git-tracked files only (git ls-files | xargs grep) so vendored/generated trees can't false-match. NEW (07.07.00): npm stamp normalizes the zero-padded Makefile PROJECT_VERSION (NN.NN.NN) to strict semver via awk before `npm version`, and an unstampable version now HARD-FAILS instead of silently keeping the old package.json version (#382). NEW (07.00.00): `moko assets:optimize` artifact-time step added before publish (graceful-skip on non-asset repos); Setup MokoCLI tools makes the fresh `moko` executable + first on PATH to fix exit-126 (mokocli #650).
|
|
10
|
+
# VERSION: 07.25.01
|
|
11
|
+
# BRIEF: NEW (07.25.01): consistency follow-up to 07.25.00 — the monotonic self-heal's DEV CARRY-FORWARD now also bumps PATCH, not MINOR. After the self-heal patch-bumps the stable base, it carries that bump forward to dev via `release_bump_dev.php --path . --branch dev --bump patch` (was `--bump minor`), so a direct-push / fast-merge hotfix does NOT inflate the dev base by a full minor — dev and stable stay aligned on the PATCH heal. UNCHANGED: the promote-rc job's planned-release dev PRE-bump (`release_bump_dev.php --path . --branch dev --bump minor`) still stays MINOR; only the self-heal carry-forward inside the fast-merge bump guard changes minor->patch. PREVIOUS (07.25.00): the "Guarantee monotonic release version (fast-merge bump guard)" self-heal now bumps PATCH, not MINOR. On a push to stable whose version was NOT pre-bumped on dev — a direct admin push, or a fast dev->stable merge that landed before promote-rc ran its dev pre-bump — the monotonic guard previously self-healed with a MINOR bump (`version_bump.php --minor --min-version "$LAST"`), minting a new MINOR for an unplanned change. It now self-heals with a PATCH bump (`version_bump.php --patch --min-version "$LAST"`), matching hotfix / direct-admin-push semantics: `--min-version "$LAST"` still guarantees the healed version is strictly above the last release, so monotonicity is preserved. PLANNED ladder releases are UNCHANGED — the promote-rc dev pre-bump (`release_bump_dev.php --bump minor`) and the stable `moko publish --bump none --no-commit` are untouched; only the non-pre-bumped self-heal path changes minor->patch. The dev side already patch-bumps per push (pre-release.yml `release_bump_dev.php --branch dev --bump patch`), so the healed PATCH carries forward consistently. PREVIOUS (07.24.00): npmjs.org publish now FAILS LOUD (::error:: + exit $rc) on an AUTHORIZATION error (404 "not in this registry" / 401 / 403 / ENEEDAUTH / EOTP) instead of swallowing EVERY failure as a non-failing ::warning:: — a missing-scope / unauthorized / revoked / expired NPM_TOKEN previously hid behind a green release fleet-wide (the "secondary registry, not failing the run" catch masked a 404 PUT, which is exactly how npm reports an unauthorized scoped write; CI had in fact NEVER successfully published any MCP package to npmjs while every run reported success). Transient/5xx/network failures still stay a non-failing ::warning:: (npmjs is the SECONDARY mirror; the MokoGIT registry is primary and already hard-fails), and an unset NPM_TOKEN still skips cleanly — so repos that do not publish to npmjs are 100% unaffected. PREVIOUS (07.23.00): "Vendor PHP dependencies (build-time)" added to BOTH publish legs (promote-rc + stable) — this workflow had NO build-time composer vendoring at all, so any component declaring runtime PHP deps via a sub-package composer.json (vendor-dir admin/vendor, e.g. mPDF in MokonyxCRM/MokonyxCRMDCM) shipped its rc/stable zip WITHOUT admin/vendor while the component manifest lists <folder>vendor</folder> — JInstaller then aborts the ENTIRE package install on-site ("File does not exist [ROOT][TMP]/.../admin/vendor" → "Failed to copy administrator files"). The step mirrors pre-release.yml 07.15.00: no-op without a sub-package composer.json; provisions ext-gd when missing (the release runners' php-cli lacks it, which failed mpdf dependency RESOLUTION outright); verifies the CONFIGURED vendor-dir (composer config vendor-dir) materialized autoload.php; FAILS the build loud when vendoring fails for a package whose manifest ships <folder>vendor</folder> (a green build with an install-bricking artifact is strictly worse than a red build); fail-soft warning for packages whose manifests do not reference vendor/. Runs before `moko publish` (release_publish.php → release_package.php zips the plain working tree; vendor/ was never excluded — the tree simply never had it in CI). PREVIOUS (07.22.00): #498 — the #469 SRC_DIR gate no longer self-traps, and the fast-merge guard is MINOR-identity aware (fixes stable version never advancing; MokoCLI stuck re-publishing v10.20.00). (1) The gate read SRC_DIR with grep|sed, capturing the LITERAL unexpanded `$(shell …)` from the fleet-standard `SRC_DIR := $(shell [ -d src ] && echo src || echo source)` — an unmatchable directory that forced should_bump=false on EVERY push even when source changed. It now resolves SRC_DIR via `make --eval` expansion, falls back to the grep|sed read only if make is unavailable, nulls out a still-unexpanded `$(...)`/backtick value, and treats a declared-but-NONEXISTENT SRC_DIR (repos with code in cli/lib/bin, not src/source) as the non-source denylist fallback instead of an unmatchable INCLUSION prefix. (2) The "Guarantee monotonic release version (fast-merge bump guard)" compared the FULL version, so dev's per-merge PATCH bumps (10.20.00→10.20.04) fooled it into "normal path, no heal" and it re-published the already-released vMAJOR.MINOR.00. It now compares the MINOR identity (MAJOR.MINOR), so a fast dev→stable merge with no promote-rc cuts a new MINOR. Fleet-wide release-semantics change — validate on one repo before syncing. PREVIOUS (07.21.00): #469 — gate the version BUMP on whether the push touched the Makefile SRC_DIR. The former non-code paths-ignore denylist on the push trigger is REMOVED: a docs/workflow/sample push no longer skips the pipeline, it now RUNS in no-bump "update the existing stable release in place" mode (re-stamps the UNCHANGED current version via the existing `moko publish --bump none --no-commit`, refreshes notes/assets, no version advance, no new vNN tag). A new early step "Resolve SRC_DIR bump gate (#469)" (id: srcgate) decides should_bump: (1) ELECTRON (file-detected) or opt-out vars.RELEASE_SRCDIR_GATE=off -> BYPASS, always bump as today (electron has NO source dir, so a naive SRC_DIR test would never bump — a release-breaking trap); (2) else SRC_DIR is REQUIRED — a non-electron repo with no resolvable SRC_DIR FAILS LOUD (::error:: + exit 1), never silently never-bump; (3) else diff the push range (github.event.before..GITHUB_SHA, with a HEAD^1 / merge-base fallback) intersected with ${SRC_DIR}/ — source hit -> should_bump=true, none -> should_bump=false. workflow_dispatch always bumps. The self-heal monotonic bump + the new vNN semver tag are now gated on should_bump!='false' so no-bump mode keeps the version PUT; the publish + "Update release notes and reconcile changelog" (channel-pointer resolution) run on BOTH paths to refresh the current release. Loop-safety is unchanged: the job if: still re-checks [skip ci]/[skip sync], so the workflow's own commits never re-trigger. Fleet-wide release-semantics change — validate on one repo before syncing. PREVIOUS (07.20.00): the dev/promote bump + release steps now name the per-run token env var GITHUB_TOKEN (was the misleadingly-named MOKOGIT_TOKEN; the VALUE was always ${{ github.token }}). All token use in this workflow is SAME-REPO (release API, the release_bump_dev dev base bump, pushes to its own repo) — the org MOKOGIT_TOKEN secret is not referenced here. Naming-only; no behavior change. Mirrors the pre-release.yml fix (MokoGIT#1721). PREVIOUS: NEW (07.19.00): #1621 Phase 6 / .mokogit-private#76 — resolve the CURRENT stable release by its CHANNEL POINTER, not by a fixed tag_name=stable. Under version-primary releases (a release is born with the immutable tag_name=vNN and `stable`/`rc` attached as movable is_channel tags), GET /releases/tags/stable no longer resolves the current stable release, which would break two steps that read "the last released version". Both now call GET /repos/{owner}/{repo}/releases/channel/stable (#1702 — resolves whichever release the `stable` channel points at via ReleaseStreamMap) with a GRACEFUL FALLBACK to the legacy GET /releases/tags/stable for forges predating #1702 (the channel route 404s pre-rollout and the rolling `stable` tag still exists). (1) The monotonic-version guard ("Guarantee monotonic release version") resolves ROLLING_LAST by parsing the same `VERSION: NN.NN.NN` out of the channel-resolved release NAME. (2) "Update release notes and reconcile changelog" resolves the stable RELEASE_ID + VERSION the same channel-first way. The #386 integrity gate is UNCHANGED (it already keys off the immutable vNN version tag). SEQUENCING unchanged: do NOT enable in prod until #1702 server support is on stable/prod; works pre-#1702 via the fallback. PREVIOUS (07.18.00): #1621 Phase 6 — version/* BRANCHES retired in favor of dual-tagged version RELEASES. REMOVED three now-redundant steps: "Step 12: Create version branch from main", "Step 13: Prune superseded-major version branches", and "Advance rolling channel tag via git". A release's permanent version identity is now the git tag v<version>, attached by the publish as a MOVABLE channel tag on the dual-tagged release (MokoCLI release_publish -> release_create channel_tags[]/update_stream; the forge attaches/moves the tag at the release commit via AttachChannelTag server-side) — so a new cut is born dual-tagged (rolling `stable`/`release-candidate` primary tag + permanent v<version> channel tag) and the channel tag MOVES onto the new release instead of a new version/* branch being created. The rolling `stable` tag is still pinned by release_create forceTagRef() (#808), so the "Advance rolling channel tag" force-push was redundant. KEPT UNCHANGED: "Create semver tag" (v<version>), the #386 integrity gate (still resolves tags/stable to the built commit), and the monotonic guard (still reads the stable release name VERSION: NN.NN.NN). Pruning EXISTING version/* branches is a SEPARATE one-time manual reconcile — not done here. SEQUENCING: do NOT enable in prod until the #1621 SERVER channel_tags support is on stable/prod. PREVIOUS (07.17.00): Setup MokoCLI tools no longer installs a STALE mokocli during the registry publish-lag window (#1671). After the fresh registry install, the step now compares the installed /tmp/mokocli PROJECT_VERSION against the /opt/mokocli failsafe and PREFERS whichever is NEWER (sort -V), and the opportunistic /opt refresh is gated to only move FORWARD (never downgrade /opt when it is the newer, just-deployed copy). Backward-compatible: runners with no /opt/mokocli use the registry copy exactly as before. PREVIOUS (07.16.00): release-integrity + dev-channel fixes. (1) A new pre-publish "no stale (pre-merge) tree" guard (#428/MokoCLI#901) hard-FAILS the release if the triggering GITHUB_SHA is an ANCESTOR of the current branch tip (a concurrent merge landed mid-run) -- otherwise a green, version-bumped release silently ships old code missing that merge (reproduced: built ef8c1a5d while tip was 2740342). Fail-open on any unresolved/replica-lagged tip so a good release is never falsely blocked. Complements the mokocli engine assertion (packaged-tree == GITHUB_SHA), which cannot see that GITHUB_SHA itself trails the tip. (2) The "Post-release: Reset dev version" safety-net (#309/MokoCLI#900) no longer swallows failure: a failed dev-advance now emits ::error:: + a job-summary block (dev-channel would trail stable), and a SUCCESSFUL advance dispatches pre-release.yml (development) to actually publish the leading dev build -- the advance commit is [skip ci]+paths-ignored and never auto-fires. Stays green (continue-on-error) since stable already published. NEW (07.15.00): the rolling stable channel tag is now advanced via a git force-push BEFORE the #386 integrity gate. MokoGIT's tags API 405s on the release-attached `stable` tag, so release_publish.php could not move it ("Could not pin tag stable ... HTTP 405") and every Joomla/electron stable cut left the tag lagging the freshly-built commit -- red-failing a correct release on the integrity gate. A new step git-force-pushes refs/tags/stable to the built HEAD (force-push allowlist -- the same escape hatch the rc BRANCH pin already uses), so the gate passes and no manual tag repoint is needed. PREVIOUS (07.14.00): integrity gate #386 no longer false-fails. It compared the published tag against GITHUB_SHA (the triggering commit), but the publish step commits the CHANGELOG entry ("build NN.NN.NN [skip ci]") and mokocli pins the channel tag + semver tag to that POST-PUBLISH HEAD -- so every cut whose CHANGELOG wasn't pre-seeded on dev (e.g. a version set straight on the release branch) diverged by one commit and red-failed a correct release. The gate now compares against the actual built/published HEAD (git rev-parse HEAD, falling back to GITHUB_SHA), which equals what the tag is pinned to in both the commit and no-commit cases while still catching a tag pinned to a commit we did NOT build; the semver tag is pinned to the same built HEAD for consistency. PREVIOUS (07.13.00): RC is ON-DEMAND ONLY. The `pull_request` trigger (RC-preview on a PR to main/stable) is REMOVED and the promote-rc job now runs solely on workflow_dispatch action=promote-rc. Only dev + stable release automatically (dev via pre-release.yml push->dev; stable via the push->main release job here); alpha/beta/rc never auto-cut. PREVIOUS (07.12.00): electron repos create NO release on ANY channel (RC enabled=false + stable publish/tag/notes/integrity guarded on is_electron; opt back in with vars.ELECTRON_CI_BUILD=true) and build NO installer in CI — always built locally + uploaded manually; the dev/promote version BUMP still runs. Template-Generic #390. NEW (07.11.00): the electron installer build/attach steps (electron-builder via Wine/Xvfb) are gated to MANUAL workflow_dispatch only (`&& github.event_name == 'workflow_dispatch'`). An automatic push no longer auto-builds electron installers (heavy ~90m, runner-fragile — OOM/Wine-zombie; migrating to mokocli ElectronPackager, MokoCLI #756/#758). The version bump, CHANGELOG, tag and npm publish STILL run on push — only the electron installer is skipped and pushed MANUALLY via dispatch. Non-electron platforms (joomla/go/npm) unaffected. Template-Generic #390. Universal build & release - BUMP-ON-DEV: base version + CHANGELOG promoted on dev pre-promotion (promote-rc), main publishes --bump none --no-commit so it never diverges from dev. MokoCLI build agent (moko publish). NEW (07.06.00): npm stable publishing ABSORBED here from Template-NPM's retired npm-publish.yml as npm-gated dual-registry steps (MokoGIT registry via per-run token + npmjs.org best-effort), replacing the former npm-publish.yml dispatch. No-Makefile repos SKIP the release job gracefully (green) instead of failing. Conflict-marker scan reads git-tracked files only (git ls-files | xargs grep) so vendored/generated trees can't false-match. NEW (07.07.00): npm stamp normalizes the zero-padded Makefile PROJECT_VERSION (NN.NN.NN) to strict semver via awk before `npm version`, and an unstampable version now HARD-FAILS instead of silently keeping the old package.json version (#382). NEW (07.00.00): `moko assets:optimize` artifact-time step added before publish (graceful-skip on non-asset repos); Setup MokoCLI tools makes the fresh `moko` executable + first on PATH to fix exit-126 (mokocli #650).
|
|
12
12
|
#
|
|
13
13
|
# +=======================================================================+
|
|
14
14
|
# | UNIVERSAL BUILD & RELEASE PIPELINE |
|
|
@@ -57,9 +57,20 @@ on:
|
|
|
57
57
|
|
|
58
58
|
env:
|
|
59
59
|
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
60
|
-
MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.
|
|
60
|
+
MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoenterprises.us' }}
|
|
61
61
|
GIT_ORG: ${{ vars.MOKOGIT_ORG || github.repository_owner }}
|
|
62
62
|
GIT_REPO: ${{ vars.MOKOGIT_REPO || github.event.repository.name }}
|
|
63
|
+
# #546: PIN the mokocli version installed by "Setup MokoCLI tools" below. The
|
|
64
|
+
# install was UNPINNED (composer create-project ... mokoenterprises/mokocli with
|
|
65
|
+
# no constraint => latest every run), so a bad mokocli release silently breaks
|
|
66
|
+
# EVERY repo's release at build time. This single pin is the version both the
|
|
67
|
+
# install step AND any future bump reference. BUMP THIS DELIBERATELY — do not
|
|
68
|
+
# auto-roll. In particular it MUST be bumped by hand once MokoCLI #1120's
|
|
69
|
+
# installer-inline capability ships (folding inlineInstallerScriptBase() into
|
|
70
|
+
# release_package.php), which is gated behind MOKO_JOOMLA_INLINE; pair the bump
|
|
71
|
+
# with that flag so an un-updated mokocli is a no-op, not an error, for one
|
|
72
|
+
# release. Allow a per-repo override via vars.MOKOCLI_VERSION for pilots.
|
|
73
|
+
MOKOCLI_VERSION: ${{ vars.MOKOCLI_VERSION || '10.34.00' }}
|
|
63
74
|
|
|
64
75
|
permissions:
|
|
65
76
|
contents: write
|
|
@@ -132,7 +143,7 @@ jobs:
|
|
|
132
143
|
run: |
|
|
133
144
|
set -u
|
|
134
145
|
TOK="$(printf '%s' "$GITHUB_TOKEN" | tr -d '[:space:]')"; echo "::add-mask::$TOK"
|
|
135
|
-
SERVER="${GITHUB_SERVER_URL:-https://git.
|
|
146
|
+
SERVER="${GITHUB_SERVER_URL:-https://git.mokoenterprises.us}"
|
|
136
147
|
CLONE_URL="https://x-access-token:${TOK}@${SERVER#https://}/${GITHUB_REPOSITORY}.git"
|
|
137
148
|
REF="${GITHUB_SHA:-${GITHUB_REF_NAME:-}}"
|
|
138
149
|
echo "Retrying checkout of ${GITHUB_REPOSITORY}@${REF:-<HEAD>} into ${GITHUB_WORKSPACE}"
|
|
@@ -177,11 +188,16 @@ jobs:
|
|
|
177
188
|
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
|
|
178
189
|
fi
|
|
179
190
|
rm -rf /tmp/mokocli
|
|
180
|
-
REG='{"type":"composer","url":"https://git.
|
|
191
|
+
REG='{"type":"composer","url":"https://git.mokoenterprises.us/api/packages/MokoEnterprises/composer"}'
|
|
192
|
+
# #546: install the PINNED mokocli (env MOKOCLI_VERSION) rather than
|
|
193
|
+
# latest — an exact `name:version` constraint on composer create-project.
|
|
194
|
+
# Roll this forward deliberately (see the env-block note). /opt/mokocli
|
|
195
|
+
# stays the stale-tolerant FAILSAFE below if the pinned registry install
|
|
196
|
+
# fails.
|
|
181
197
|
if composer create-project --no-install --no-interaction --no-progress --quiet \
|
|
182
|
-
--repository="${REG}"
|
|
198
|
+
--repository="${REG}" "mokoenterprises/mokocli:${MOKOCLI_VERSION}" /tmp/mokocli >/dev/null 2>&1 \
|
|
183
199
|
&& [ -f /tmp/mokocli/cli/version_bump.php ]; then
|
|
184
|
-
echo "Installed mokocli fresh from the Composer registry (primary)"
|
|
200
|
+
echo "Installed mokocli ${MOKOCLI_VERSION} (pinned, #546) fresh from the Composer registry (primary)"
|
|
185
201
|
# #1671: registry-publish LAG race. The registry install "succeeds" but can
|
|
186
202
|
# serve the PREVIOUS package for ~tens of seconds after a MokoCLI release
|
|
187
203
|
# (publish finishes AFTER the release run reports success). Meanwhile the
|
|
@@ -320,7 +336,7 @@ jobs:
|
|
|
320
336
|
# the push + force-push allowlists and creates rc if it is absent.
|
|
321
337
|
PUSH_URL="https://x-access-token:${PUSH_TOK}@${MOKOGIT_URL#https://}/${GIT_ORG}/${GIT_REPO}.git"
|
|
322
338
|
git config --global user.name "mokogit-actions[bot]"
|
|
323
|
-
git config --global user.email "actions@
|
|
339
|
+
git config --global user.email "actions@mokoenterprises.us"
|
|
324
340
|
git fetch --no-tags "$PUSH_URL" "${FROM}"
|
|
325
341
|
git push --force "$PUSH_URL" "FETCH_HEAD:refs/heads/rc" \
|
|
326
342
|
|| { echo "::error::Failed to point rc at ${FROM} (${SRC_SHA}) via git push"; exit 1; }
|
|
@@ -355,9 +371,9 @@ jobs:
|
|
|
355
371
|
# `git fetch origin rc` / `git checkout rc` is ambiguous and could grab the tag.
|
|
356
372
|
git fetch origin "+refs/heads/rc:refs/remotes/origin/rc"
|
|
357
373
|
git checkout -B rc origin/rc
|
|
358
|
-
git config --local user.email "mokogit-actions[bot]@
|
|
374
|
+
git config --local user.email "mokogit-actions[bot]@mokoenterprises.us"
|
|
359
375
|
git config --local user.name "mokogit-actions[bot]"
|
|
360
|
-
git remote set-url origin "https://x-access-token:${PUSH_TOK}@git.
|
|
376
|
+
git remote set-url origin "https://x-access-token:${PUSH_TOK}@git.mokoenterprises.us/${{ github.repository }}.git"
|
|
361
377
|
|
|
362
378
|
# Build-time PHP dependency vendoring (universal, guarded — mirrors
|
|
363
379
|
# pre-release.yml 07.15.00). If a sub-package ships a composer.json, fetch its
|
|
@@ -589,7 +605,7 @@ jobs:
|
|
|
589
605
|
run: |
|
|
590
606
|
set -u
|
|
591
607
|
TOK="$(printf '%s' "$GITHUB_TOKEN" | tr -d '[:space:]')"; echo "::add-mask::$TOK"
|
|
592
|
-
SERVER="${GITHUB_SERVER_URL:-https://git.
|
|
608
|
+
SERVER="${GITHUB_SERVER_URL:-https://git.mokoenterprises.us}"
|
|
593
609
|
CLONE_URL="https://x-access-token:${TOK}@${SERVER#https://}/${GITHUB_REPOSITORY}.git"
|
|
594
610
|
REF="${GITHUB_SHA:-${GITHUB_REF_NAME:-}}"
|
|
595
611
|
echo "Retrying full-history checkout of ${GITHUB_REPOSITORY}@${REF:-<HEAD>} into ${GITHUB_WORKSPACE}"
|
|
@@ -647,15 +663,34 @@ jobs:
|
|
|
647
663
|
echo "is_electron=false" >> "$GITHUB_OUTPUT"
|
|
648
664
|
fi
|
|
649
665
|
|
|
666
|
+
# -- Download-stub opt-in detection (#544) ---------------------------------
|
|
667
|
+
# ADDITIVE + GATED. An electron repo opts into the branded download-stub
|
|
668
|
+
# installer build by shipping BOTH tools/build-release.mjs (the combined
|
|
669
|
+
# build+publish driver) AND moko-installer.config.mjs (the stub config) at
|
|
670
|
+
# the repo root. When present, the stub build below REPLACES the factory
|
|
671
|
+
# electron-builder leg (mutually exclusive via the is_stub gate). A plain
|
|
672
|
+
# electron repo keeps its existing vars.ELECTRON_CI_BUILD factory path; a
|
|
673
|
+
# non-electron repo sets is_stub=false and runs nothing new.
|
|
674
|
+
- name: "Detect download-stub installer (opt-in, #544)"
|
|
675
|
+
id: stub
|
|
676
|
+
if: steps.gate.outputs.has_makefile == 'true' && steps.electron.outputs.is_electron == 'true'
|
|
677
|
+
run: |
|
|
678
|
+
if [ -f tools/build-release.mjs ] && [ -f moko-installer.config.mjs ]; then
|
|
679
|
+
echo "is_stub=true" >> "$GITHUB_OUTPUT"
|
|
680
|
+
echo "download-stub opt-in detected (tools/build-release.mjs + moko-installer.config.mjs) -- stub build enabled, factory electron-builder leg disabled."
|
|
681
|
+
else
|
|
682
|
+
echo "is_stub=false" >> "$GITHUB_OUTPUT"
|
|
683
|
+
fi
|
|
684
|
+
|
|
650
685
|
- name: Configure git for bot pushes
|
|
651
686
|
if: steps.gate.outputs.has_makefile == 'true'
|
|
652
687
|
env:
|
|
653
688
|
GITHUB_TOKEN: ${{ github.token }}
|
|
654
689
|
run: |
|
|
655
690
|
PUSH_TOK="$(printf '%s' "$GITHUB_TOKEN" | tr -d '[:space:]')"; [ -z "$PUSH_TOK" ] && PUSH_TOK="${{ github.token }}"; echo "::add-mask::$PUSH_TOK"
|
|
656
|
-
git config --local user.email "mokogit-actions[bot]@
|
|
691
|
+
git config --local user.email "mokogit-actions[bot]@mokoenterprises.us"
|
|
657
692
|
git config --local user.name "mokogit-actions[bot]"
|
|
658
|
-
git remote set-url origin "https://x-access-token:${PUSH_TOK}@git.
|
|
693
|
+
git remote set-url origin "https://x-access-token:${PUSH_TOK}@git.mokoenterprises.us/${{ github.repository }}.git"
|
|
659
694
|
|
|
660
695
|
- name: Check for merge conflict markers
|
|
661
696
|
if: steps.gate.outputs.has_makefile == 'true'
|
|
@@ -689,11 +724,16 @@ jobs:
|
|
|
689
724
|
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
|
|
690
725
|
fi
|
|
691
726
|
rm -rf /tmp/mokocli
|
|
692
|
-
REG='{"type":"composer","url":"https://git.
|
|
727
|
+
REG='{"type":"composer","url":"https://git.mokoenterprises.us/api/packages/MokoEnterprises/composer"}'
|
|
728
|
+
# #546: install the PINNED mokocli (env MOKOCLI_VERSION) rather than
|
|
729
|
+
# latest — an exact `name:version` constraint on composer create-project.
|
|
730
|
+
# Roll this forward deliberately (see the env-block note). /opt/mokocli
|
|
731
|
+
# stays the stale-tolerant FAILSAFE below if the pinned registry install
|
|
732
|
+
# fails.
|
|
693
733
|
if composer create-project --no-install --no-interaction --no-progress --quiet \
|
|
694
|
-
--repository="${REG}"
|
|
734
|
+
--repository="${REG}" "mokoenterprises/mokocli:${MOKOCLI_VERSION}" /tmp/mokocli >/dev/null 2>&1 \
|
|
695
735
|
&& [ -f /tmp/mokocli/cli/version_bump.php ]; then
|
|
696
|
-
echo "Installed mokocli fresh from the Composer registry (primary)"
|
|
736
|
+
echo "Installed mokocli ${MOKOCLI_VERSION} (pinned, #546) fresh from the Composer registry (primary)"
|
|
697
737
|
# #1671: registry-publish LAG race. The registry install "succeeds" but can
|
|
698
738
|
# serve the PREVIOUS package for ~tens of seconds after a MokoCLI release
|
|
699
739
|
# (publish finishes AFTER the release run reports success). Meanwhile the
|
|
@@ -1026,7 +1066,7 @@ jobs:
|
|
|
1026
1066
|
- name: "Guarantee monotonic release version (fast-merge bump guard)"
|
|
1027
1067
|
id: monotonic
|
|
1028
1068
|
# #469: in no-bump mode (a non-source push updating the existing release in
|
|
1029
|
-
# place) the version must stay PUT, so the self-healing
|
|
1069
|
+
# place) the version must stay PUT, so the self-healing patch bump must not
|
|
1030
1070
|
# run — skip this guard when steps.srcgate decided should_bump=false. On the
|
|
1031
1071
|
# bump path (should_bump=true, or electron/opt-out/dispatch where srcgate is
|
|
1032
1072
|
# bypassed/true) it runs exactly as before.
|
|
@@ -1078,20 +1118,26 @@ jobs:
|
|
|
1078
1118
|
# already-released vMAJOR.MINOR.00 forever (observed: MokoCLI stuck at
|
|
1079
1119
|
# v10.20.00 while dev reached 10.20.04), violating this guard's own "never
|
|
1080
1120
|
# re-publish an already-released base" intent. Compare the MINOR identity
|
|
1081
|
-
# (MAJOR.MINOR): heal (
|
|
1082
|
-
# the last release's minor.
|
|
1083
|
-
#
|
|
1121
|
+
# (MAJOR.MINOR): heal (PATCH-bump above --min-version LAST) whenever CUR's
|
|
1122
|
+
# minor has NOT advanced past the last release's minor. An unplanned /
|
|
1123
|
+
# non-pre-bumped stable change (a direct admin push, or a fast dev->stable
|
|
1124
|
+
# merge that skipped the promote-rc dev pre-bump) is a hotfix-shaped event,
|
|
1125
|
+
# so it bumps PATCH, not MINOR — --min-version "$LAST" still guarantees the
|
|
1126
|
+
# healed version is strictly above the last release, and the dev carry-forward
|
|
1127
|
+
# below is ALSO --bump patch (consistent with the stable patch heal, so a
|
|
1128
|
+
# direct-push hotfix does not inflate dev by a full minor). The normal
|
|
1129
|
+
# promote-rc path (dev already minor-bumped) still no-ops.
|
|
1084
1130
|
CUR_MI=$(printf '%s' "$CUR" | awk -F. '{printf "%s.%s", $1, $2}')
|
|
1085
1131
|
LAST_MI=$(printf '%s' "$LAST" | awk -F. '{printf "%s.%s", $1, $2}')
|
|
1086
1132
|
GREATEST_MI=$( { echo "$CUR_MI"; echo "$LAST_MI"; } | sort -V | tail -n1 || true)
|
|
1087
1133
|
if [ "$CUR_MI" = "$LAST_MI" ] || [ "$GREATEST_MI" = "$LAST_MI" ]; then
|
|
1088
|
-
echo "::warning::inherited minor ${CUR_MI} <= last release minor ${LAST_MI} (CUR=${CUR} LAST=${LAST});
|
|
1089
|
-
if ! php ${MOKO_CLI}/version_bump.php --
|
|
1134
|
+
echo "::warning::inherited minor ${CUR_MI} <= last release minor ${LAST_MI} (CUR=${CUR} LAST=${LAST}); pre-bump skipped -> self-healing PATCH bump"
|
|
1135
|
+
if ! php ${MOKO_CLI}/version_bump.php --patch --min-version "$LAST" --path .; then
|
|
1090
1136
|
echo "::error::monotonic bump guard failed to advance the base"; exit 1
|
|
1091
1137
|
fi
|
|
1092
1138
|
NEW=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null | sed 's/-\(dev\|alpha\|beta\|rc\)$//')
|
|
1093
|
-
echo "healed ${CUR} -> ${NEW} (publishing fresh; carrying forward to dev)"
|
|
1094
|
-
php ${MOKO_CLI}/release_bump_dev.php --path . --branch dev --bump
|
|
1139
|
+
echo "healed ${CUR} -> ${NEW} (publishing fresh; carrying the PATCH forward to dev)"
|
|
1140
|
+
php ${MOKO_CLI}/release_bump_dev.php --path . --branch dev --bump patch \n --repo "${{ github.repository }}" --token "${GITHUB_TOKEN:-${{ github.token }}}" \n || echo "::warning::dev carry-forward failed (non-fatal; release still publishes the healed version)"
|
|
1095
1141
|
else
|
|
1096
1142
|
echo "base ${CUR} > last release ${LAST}: normal path, no heal"
|
|
1097
1143
|
fi
|
|
@@ -1239,6 +1285,37 @@ jobs:
|
|
|
1239
1285
|
echo "branch=main" >> "$GITHUB_OUTPUT"
|
|
1240
1286
|
echo "Published version: ${VERSION}"
|
|
1241
1287
|
|
|
1288
|
+
- name: Deploy over SFTP to stable/prod (generic, presence-gated)
|
|
1289
|
+
# SECURITY: this is an unattended PROD deploy. Gate it as tightly as the
|
|
1290
|
+
# sibling "Deploy to prod" step: (1) presence of SFTP_STABLE_HOST,
|
|
1291
|
+
# (2) a successful release (version.skip != true), (3) the protected
|
|
1292
|
+
# stable/main ref (never a feature branch), and (4) the makefile gate the
|
|
1293
|
+
# prod step uses — so a repo without a build never SFTP-ships its raw tree.
|
|
1294
|
+
# RECOMMENDED: additionally scope secrets.SFTP_STABLE_KEY to a GitHub/Gitea
|
|
1295
|
+
# "environment" with required reviewers so the deploy credential cannot be
|
|
1296
|
+
# used without a human approval on the deployment.
|
|
1297
|
+
if: ${{ steps.version.outputs.skip != 'true' && vars.SFTP_STABLE_HOST != '' && steps.gate.outputs.has_makefile == 'true' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/stable') }}
|
|
1298
|
+
env:
|
|
1299
|
+
DEPLOY_KEY: ${{ secrets.SFTP_STABLE_KEY }}
|
|
1300
|
+
KNOWN_HOSTS: ${{ vars.SFTP_STABLE_KNOWN_HOSTS }}
|
|
1301
|
+
SSH_USER: ${{ vars.SFTP_STABLE_USER }}
|
|
1302
|
+
SSH_HOST: ${{ vars.SFTP_STABLE_HOST }}
|
|
1303
|
+
SSH_PORT: ${{ vars.SFTP_STABLE_PORT }}
|
|
1304
|
+
DEST: ${{ vars.SFTP_STABLE_PATH }}
|
|
1305
|
+
run: |
|
|
1306
|
+
set -euo pipefail
|
|
1307
|
+
# never leave the deploy key / known_hosts on a shared runner
|
|
1308
|
+
trap 'rm -f ~/.ssh/id_sftp_deploy ~/.ssh/known_hosts_sftp' EXIT
|
|
1309
|
+
[ -n "$DEST" ] && [ "$DEST" != "/" ] || { echo "SFTP_STABLE_PATH empty/root; refusing"; exit 1; }
|
|
1310
|
+
install -d -m 700 ~/.ssh
|
|
1311
|
+
install -m600 /dev/null ~/.ssh/id_sftp_deploy # 0600 before any bytes (no umask window)
|
|
1312
|
+
printf '%s\n' "$DEPLOY_KEY" > ~/.ssh/id_sftp_deploy; chmod 600 ~/.ssh/id_sftp_deploy
|
|
1313
|
+
printf '%s\n' "$KNOWN_HOSTS" > ~/.ssh/known_hosts_sftp; chmod 644 ~/.ssh/known_hosts_sftp
|
|
1314
|
+
SSH="ssh -i $HOME/.ssh/id_sftp_deploy -p ${SSH_PORT:-22} -o UserKnownHostsFile=$HOME/.ssh/known_hosts_sftp -o StrictHostKeyChecking=yes -o IdentitiesOnly=yes"
|
|
1315
|
+
$SSH "$SSH_USER@$SSH_HOST" "rm -rf \"$DEST\" && mkdir -p \"$DEST\""
|
|
1316
|
+
tar czf - --exclude=.git --exclude=.mokogit --exclude=.github --exclude='*.token' --exclude='*.token.json' . | $SSH "$SSH_USER@$SSH_HOST" "tar xzf - -C \"$DEST\""
|
|
1317
|
+
echo "Deployed to stable: $SSH_HOST:$DEST"
|
|
1318
|
+
|
|
1242
1319
|
- name: "Deploy to prod (inline — replaces standalone deploy.yml, #1427)"
|
|
1243
1320
|
if: steps.gate.outputs.has_makefile == 'true' && steps.version.outputs.skip != 'true' && vars.PROD_SSH_USERNAME != ''
|
|
1244
1321
|
env:
|
|
@@ -1280,24 +1357,116 @@ jobs:
|
|
|
1280
1357
|
--ssh-host "${{ vars.PROD_SSH_HOST }}" --ssh-port "${{ vars.PROD_SSH_PORT }}" \
|
|
1281
1358
|
--ssh-user "${{ vars.PROD_SSH_USERNAME }}" --ssh-key ~/.ssh/deploy_key
|
|
1282
1359
|
|
|
1283
|
-
# -- Electron
|
|
1360
|
+
# -- Electron download-stub release (opt-in, #544) -------------------------
|
|
1361
|
+
# When a repo opts into the branded download-stub (steps.stub.is_stub), build
|
|
1362
|
+
# + publish the stub installer + payload via tools/build-release.mjs on the
|
|
1363
|
+
# `release` runner (this job already runs there), MIRRORING MokoHub's proven
|
|
1364
|
+
# custom-mokohub-build-installer.yml. build-release.mjs does its own publish,
|
|
1365
|
+
# so this fully REPLACES the factory electron-builder leg below (mutually
|
|
1366
|
+
# exclusive via the is_stub gate). Channel = stable (this is auto-release).
|
|
1367
|
+
- name: "Setup Node (electron stub)"
|
|
1368
|
+
if: steps.gate.outputs.has_makefile == 'true' && steps.stub.outputs.is_stub == 'true' && steps.version.outputs.skip != 'true'
|
|
1369
|
+
uses: actions/setup-node@v4
|
|
1370
|
+
with:
|
|
1371
|
+
node-version: 24.18.1
|
|
1372
|
+
|
|
1373
|
+
- name: "Setup pnpm (electron stub)"
|
|
1374
|
+
if: steps.gate.outputs.has_makefile == 'true' && steps.stub.outputs.is_stub == 'true' && steps.version.outputs.skip != 'true'
|
|
1375
|
+
uses: pnpm/action-setup@v4
|
|
1376
|
+
with:
|
|
1377
|
+
version: 11.20.0
|
|
1378
|
+
|
|
1379
|
+
- name: "Provision Wine + Xvfb (stub build)"
|
|
1380
|
+
if: steps.gate.outputs.has_makefile == 'true' && steps.stub.outputs.is_stub == 'true' && steps.version.outputs.skip != 'true'
|
|
1381
|
+
run: |
|
|
1382
|
+
# electron-builder's portable/NSIS target runs the stub under Wine and
|
|
1383
|
+
# needs 32-bit libs + an X display; provision i386 Wine + Xvfb and init
|
|
1384
|
+
# the prefix once so the first Wine call does not race prefix creation.
|
|
1385
|
+
sudo dpkg --add-architecture i386 || true
|
|
1386
|
+
sudo apt-get update -qq
|
|
1387
|
+
sudo apt-get install -y -qq xvfb >/dev/null 2>&1 || echo "::warning::xvfb install failed"
|
|
1388
|
+
sudo apt-get install -y -qq wine64 wine32 >/dev/null 2>&1 || sudo apt-get install -y -qq wine >/dev/null 2>&1 || echo "::warning::wine install failed"
|
|
1389
|
+
export WINEDEBUG=-all
|
|
1390
|
+
xvfb-run -a wineboot --init >/dev/null 2>&1 || true
|
|
1391
|
+
|
|
1392
|
+
- name: "Fetch moko-installer (file: dep sibling) [stub]"
|
|
1393
|
+
if: steps.gate.outputs.has_makefile == 'true' && steps.stub.outputs.is_stub == 'true' && steps.version.outputs.skip != 'true'
|
|
1394
|
+
env:
|
|
1395
|
+
# github.token is scoped to THIS repo only, so it CANNOT clone the
|
|
1396
|
+
# cross-repo private moko-installer ("Repository not found"). Use the
|
|
1397
|
+
# org MOKOGIT_TOKEN secret (cross-repo read); fall back to github.token.
|
|
1398
|
+
MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
|
|
1399
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
1400
|
+
run: |
|
|
1401
|
+
# @mokoenterprises/moko-installer is a `file:../moko-installer` dep
|
|
1402
|
+
# (local-dev link); a fresh runner checkout has no sibling, so clone it
|
|
1403
|
+
# here. This is the STABLE release path, so pull moko-installer's stable
|
|
1404
|
+
# branch (the matching toolchain for a stable build).
|
|
1405
|
+
TOK="$(printf '%s' "${MOKOGIT_TOKEN:-$GITHUB_TOKEN}" | tr -d '[:space:]')"; echo "::add-mask::$TOK"
|
|
1406
|
+
SRV="${GITHUB_SERVER_URL:-https://git.mokoenterprises.us}"
|
|
1407
|
+
rm -rf ../moko-installer
|
|
1408
|
+
# #546 (MEDIUM credential-exposure): do NOT embed the token in the clone
|
|
1409
|
+
# URL — that persists it in ../moko-installer/.git/config and exposes it in
|
|
1410
|
+
# the runner process list. Pass it as a one-shot http.extraHeader instead
|
|
1411
|
+
# (the URL carries NO token), then rewrite origin to the clean URL so no
|
|
1412
|
+
# credential lingers in .git/config. An always() cleanup step below removes
|
|
1413
|
+
# ../moko-installer entirely.
|
|
1414
|
+
REPO_URL="https://${SRV#https://}/MokoEnterprises/moko-installer.git"
|
|
1415
|
+
git -c http.extraHeader="Authorization: token ${TOK}" clone --depth 1 -b stable "$REPO_URL" ../moko-installer
|
|
1416
|
+
git -C ../moko-installer remote set-url origin "$REPO_URL"
|
|
1417
|
+
|
|
1418
|
+
- name: "Install dependencies (stub)"
|
|
1419
|
+
if: steps.gate.outputs.has_makefile == 'true' && steps.stub.outputs.is_stub == 'true' && steps.version.outputs.skip != 'true'
|
|
1420
|
+
run: pnpm install --no-frozen-lockfile
|
|
1421
|
+
|
|
1422
|
+
- name: "Build + publish stub installer + payload (#544)"
|
|
1423
|
+
if: steps.gate.outputs.has_makefile == 'true' && steps.stub.outputs.is_stub == 'true' && steps.version.outputs.skip != 'true'
|
|
1424
|
+
env:
|
|
1425
|
+
HUSKY: "0"
|
|
1426
|
+
WINEDEBUG: "-all"
|
|
1427
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
1428
|
+
# Scoped write:issue token for the installer bug-report feature (#86);
|
|
1429
|
+
# absent on repos without the secret -> build-release just leaves it unset.
|
|
1430
|
+
MOKO_REPORT_TOKEN: ${{ secrets.MOKO_REPORT_TOKEN }}
|
|
1431
|
+
run: |
|
|
1432
|
+
# tools/build-release.mjs: electron-builder --win dir (payload) ->
|
|
1433
|
+
# buildInstaller (download mode) -> stub exe + payload tar.gz -> upload
|
|
1434
|
+
# both to the stable release. Wrapped in xvfb-run so the nested
|
|
1435
|
+
# electron-builder portable/NSIS pass has a virtual display under Wine.
|
|
1436
|
+
# 30-min guard (SIGTERM, then SIGKILL +30s), short of the job timeout so
|
|
1437
|
+
# a regression fails loudly, not as a silent kill.
|
|
1438
|
+
timeout -k 30 1800 xvfb-run -a node tools/build-release.mjs --channel stable --publish \
|
|
1439
|
+
|| { rc=$?; echo "::error::build-release.mjs exited $rc (124 = 30-min guard) — see electron-builder output above"; exit $rc; }
|
|
1440
|
+
|
|
1441
|
+
- name: "Cleanup moko-installer clone (#546)"
|
|
1442
|
+
# #546: always() — remove the cloned sibling so no checkout (and its
|
|
1443
|
+
# .git/config) lingers on the shared runner workspace, even if a stub step
|
|
1444
|
+
# above failed. LITERAL if: always() (never a continue-on-error expression,
|
|
1445
|
+
# which Gitea would discard the whole workflow over); independent step — no
|
|
1446
|
+
# needs:+always() fan-in. Safe no-op when the clone never happened.
|
|
1447
|
+
if: always()
|
|
1448
|
+
run: rm -rf ../moko-installer
|
|
1449
|
+
|
|
1450
|
+
# -- Electron: FACTORY installers (Windows via Wine + Linux) and attach ----
|
|
1284
1451
|
# No Windows/macOS runner: the `release` runner is Ubuntu, so we cross-build
|
|
1285
1452
|
# the Windows target with Wine and build Linux natively. macOS is skipped
|
|
1286
1453
|
# (cannot be cross-built off a Mac). All four steps no-op on non-electron repos.
|
|
1454
|
+
# ALSO gated on is_stub != 'true' (#544): a stub-opted repo runs the stub leg
|
|
1455
|
+
# above INSTEAD, so these two paths are mutually exclusive.
|
|
1287
1456
|
- name: "Setup Node (electron)"
|
|
1288
|
-
if: steps.gate.outputs.has_makefile == 'true' && steps.electron.outputs.is_electron == 'true' && steps.version.outputs.skip != 'true' && vars.ELECTRON_CI_BUILD == 'true'
|
|
1457
|
+
if: steps.gate.outputs.has_makefile == 'true' && steps.electron.outputs.is_electron == 'true' && steps.stub.outputs.is_stub != 'true' && steps.version.outputs.skip != 'true' && vars.ELECTRON_CI_BUILD == 'true'
|
|
1289
1458
|
uses: actions/setup-node@v4
|
|
1290
1459
|
with:
|
|
1291
1460
|
node-version: 24.18.1
|
|
1292
1461
|
|
|
1293
1462
|
- name: "Setup pnpm (electron)"
|
|
1294
|
-
if: steps.gate.outputs.has_makefile == 'true' && steps.electron.outputs.is_electron == 'true' && steps.version.outputs.skip != 'true' && vars.ELECTRON_CI_BUILD == 'true'
|
|
1463
|
+
if: steps.gate.outputs.has_makefile == 'true' && steps.electron.outputs.is_electron == 'true' && steps.stub.outputs.is_stub != 'true' && steps.version.outputs.skip != 'true' && vars.ELECTRON_CI_BUILD == 'true'
|
|
1295
1464
|
uses: pnpm/action-setup@v4
|
|
1296
1465
|
with:
|
|
1297
1466
|
version: 11.20.0
|
|
1298
1467
|
|
|
1299
1468
|
- name: "Build electron installers (Windows via Wine + Linux)"
|
|
1300
|
-
if: steps.gate.outputs.has_makefile == 'true' && steps.electron.outputs.is_electron == 'true' && steps.version.outputs.skip != 'true' && vars.ELECTRON_CI_BUILD == 'true'
|
|
1469
|
+
if: steps.gate.outputs.has_makefile == 'true' && steps.electron.outputs.is_electron == 'true' && steps.stub.outputs.is_stub != 'true' && steps.version.outputs.skip != 'true' && vars.ELECTRON_CI_BUILD == 'true'
|
|
1301
1470
|
env:
|
|
1302
1471
|
HUSKY: "0"
|
|
1303
1472
|
run: |
|
|
@@ -1336,7 +1505,7 @@ jobs:
|
|
|
1336
1505
|
xvfb-run -a npx --no-install electron-builder --win --linux --publish never || xvfb-run -a npx electron-builder --win --linux --publish never
|
|
1337
1506
|
|
|
1338
1507
|
- name: "Attach electron installers to the release"
|
|
1339
|
-
if: steps.gate.outputs.has_makefile == 'true' && steps.electron.outputs.is_electron == 'true' && steps.version.outputs.skip != 'true' && vars.ELECTRON_CI_BUILD == 'true'
|
|
1508
|
+
if: steps.gate.outputs.has_makefile == 'true' && steps.electron.outputs.is_electron == 'true' && steps.stub.outputs.is_stub != 'true' && steps.version.outputs.skip != 'true' && vars.ELECTRON_CI_BUILD == 'true'
|
|
1340
1509
|
continue-on-error: true
|
|
1341
1510
|
run: |
|
|
1342
1511
|
API_BASE="${MOKOGIT_URL}/api/v1/repos/${GIT_ORG}/${GIT_REPO}"
|
|
@@ -1721,7 +1890,7 @@ jobs:
|
|
|
1721
1890
|
# Write the safely-extracted blob (NOT a copy of the possibly-symlinked file).
|
|
1722
1891
|
install -m 0644 "${NOTES_CONTENT}" "${WIKI_DIR}/Release-Notes.md"
|
|
1723
1892
|
cd "${WIKI_DIR}"
|
|
1724
|
-
git config --local user.email "mokogit-actions[bot]@
|
|
1893
|
+
git config --local user.email "mokogit-actions[bot]@mokoenterprises.us"
|
|
1725
1894
|
git config --local user.name "mokogit-actions[bot]"
|
|
1726
1895
|
git config --local commit.gpgsign false
|
|
1727
1896
|
git add -- Release-Notes.md
|
|
@@ -1798,7 +1967,7 @@ jobs:
|
|
|
1798
1967
|
rm -f .npmrc; echo "$out"
|
|
1799
1968
|
if [ "$rc" -eq 0 ]; then echo "Published to npmjs.org."
|
|
1800
1969
|
elif printf '%s' "$out" | grep -qiE 'already exists|cannot publish over|EPUBLISHCONFLICT|409 Conflict'; then echo "::notice::npmjs.org already has this version - no-op."
|
|
1801
|
-
elif printf '%s' "$out" | grep -qiE 'not in this registry|ENEEDAUTH|EOTP|need auth|E401|E403|401 Unauthorized|403 Forbidden|404 Not Found|Forbidden'; then echo "::error::npmjs.org publish FAILED — authorization error (npm exit ${rc}). NPM_TOKEN lacks publish/create rights on the @
|
|
1970
|
+
elif printf '%s' "$out" | grep -qiE 'not in this registry|ENEEDAUTH|EOTP|need auth|E401|E403|401 Unauthorized|403 Forbidden|404 Not Found|Forbidden'; then echo "::error::npmjs.org publish FAILED — authorization error (npm exit ${rc}). NPM_TOKEN lacks publish/create rights on the @mokoenterprises scope (new-scoped-name first publish, an unauthorized token, or a revoked/expired token). Failing loud so a broken publish token cannot hide behind a green release — a 404 PUT is how npm masks an unauthorized scoped write."; exit "$rc"
|
|
1802
1971
|
else echo "::warning::npmjs.org publish failed (npm exit ${rc}) — transient/5xx/network issue; npmjs is the secondary mirror (MokoGIT registry is primary), not failing the run."; fi
|
|
1803
1972
|
|
|
1804
1973
|
# -- VS Code extension: build .vsix -> attach to the release (Template-Generic#515)
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# Copyright (C) 2026 Moko
|
|
1
|
+
# Copyright (C) 2026 Moko Enterprises <hello@mokoenterprises.us>
|
|
2
2
|
#
|
|
3
3
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
4
|
#
|
|
5
5
|
# FILE INFORMATION
|
|
6
6
|
# DEFGROUP: MokoGIT.Workflow
|
|
7
7
|
# INGROUP: MokoCLI.Universal
|
|
8
|
-
# REPO: https://git.
|
|
8
|
+
# REPO: https://git.mokoenterprises.us/MokoEnterprises/Template-Generic
|
|
9
9
|
# PATH: /.mokogit/workflows/branch-cleanup.yml
|
|
10
10
|
# VERSION: 01.00.00
|
|
11
11
|
# BRIEF: Delete feature branches after PR merge
|
|
@@ -39,7 +39,7 @@ jobs:
|
|
|
39
39
|
env:
|
|
40
40
|
MOKOGIT_TOKEN: ${{ github.token }}
|
|
41
41
|
REPO: ${{ github.repository }}
|
|
42
|
-
API_BASE: ${{ vars.MOKOGIT_URL || 'https://git.
|
|
42
|
+
API_BASE: ${{ vars.MOKOGIT_URL || 'https://git.mokoenterprises.us' }}
|
|
43
43
|
BRANCH: ${{ github.event.pull_request.head.ref }}
|
|
44
44
|
run: |
|
|
45
45
|
set -euo pipefail
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# Copyright (C) 2026 Moko
|
|
1
|
+
# Copyright (C) 2026 Moko Enterprises <hello@mokoenterprises.us>
|
|
2
2
|
#
|
|
3
3
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
4
|
#
|
|
5
5
|
# FILE INFORMATION
|
|
6
6
|
# DEFGROUP: MokoGIT.Workflow
|
|
7
7
|
# INGROUP: MokoCLI.Universal
|
|
8
|
-
# REPO: https://git.
|
|
8
|
+
# REPO: https://git.mokoenterprises.us/MokoEnterprises/Template-Generic
|
|
9
9
|
# PATH: /.mokogit/workflows/ci-issue-reporter.yml
|
|
10
10
|
# VERSION: 01.00.00
|
|
11
11
|
# BRIEF: Reusable workflow � creates/updates a MokoGIT issue when a CI gate fails.
|
|
@@ -62,9 +62,9 @@ jobs:
|
|
|
62
62
|
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 || true
|
|
63
63
|
fi
|
|
64
64
|
rm -rf /tmp/mokocli
|
|
65
|
-
REG='{"type":"composer","url":"https://git.
|
|
65
|
+
REG='{"type":"composer","url":"https://git.mokoenterprises.us/api/packages/MokoEnterprises/composer"}'
|
|
66
66
|
if composer create-project --no-install --no-interaction --no-progress --quiet \
|
|
67
|
-
--repository="${REG}"
|
|
67
|
+
--repository="${REG}" mokoenterprises/mokocli /tmp/mokocli >/dev/null 2>&1 \
|
|
68
68
|
&& [ -f /tmp/mokocli/cli/version_bump.php ]; then
|
|
69
69
|
echo "Installed mokocli fresh from the Composer registry (primary)"
|
|
70
70
|
echo "MOKO_CLI=/tmp/mokocli/cli" >> $GITHUB_ENV
|
|
@@ -83,7 +83,7 @@ jobs:
|
|
|
83
83
|
- name: Report CI failure
|
|
84
84
|
env:
|
|
85
85
|
MOKOGIT_TOKEN: ${{ github.token }}
|
|
86
|
-
MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.
|
|
86
|
+
MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoenterprises.us' }}
|
|
87
87
|
# Route all workflow_call inputs through env vars — referencing ${{ inputs.* }}
|
|
88
88
|
# directly in a run: block interpolates at YAML-parse time and is a shell-injection
|
|
89
89
|
# vector. Shell variables are not re-parsed, so a crafted input can't break out.
|