@mokoconsulting/mcp-mokosuite 1.0.0 → 1.1.0-dev.372
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/workflows/auto-bump.yml +8 -0
- package/.mokogit/workflows/auto-release.yml +184 -71
- package/.mokogit/workflows/cascade-dev.yml +128 -60
- package/.mokogit/workflows/changelog-validation.yml +41 -25
- package/.mokogit/workflows/ci-issue-reporter.yml +1 -1
- package/.mokogit/workflows/cleanup.yml +3 -3
- package/.mokogit/workflows/custom-workflow-sync-trigger.yml +83 -0
- package/.mokogit/workflows/issue-branch.yml +1 -1
- package/.mokogit/workflows/npm-build-test.yml +103 -19
- package/.mokogit/workflows/npm-prerelease.yml +174 -0
- package/.mokogit/workflows/npm-publish.yml +44 -17
- package/.mokogit/workflows/pr-check.yml +181 -53
- package/.mokogit/workflows/pre-release.yml +174 -35
- package/.mokogit/workflows/rc-revert.yml +1 -1
- package/.mokogit/workflows/version-set.yml +4 -4
- package/AGENTS.md +39 -0
- package/CHANGELOG.md +46 -10
- package/dist/index.js +28 -1
- package/docs/API.md +54 -45
- package/package.json +1 -1
- package/src/index.ts +59 -1
- package/.mokogit/workflows/ci-generic.yml +0 -203
- package/.mokogit/workflows/repo-health.yml +0 -700
- package/.mokogit/workflows/standards-compliance.yml +0 -2507
|
@@ -2,8 +2,16 @@
|
|
|
2
2
|
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
3
3
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
4
|
#
|
|
5
|
-
# Builds the MCP server
|
|
6
|
-
#
|
|
5
|
+
# Builds the MCP server via the centralized MokoCLI build agent
|
|
6
|
+
# (moko lint|build|test), then validates that compiled output exists and that
|
|
7
|
+
# tools are properly registered. The build agent is platform-aware via the
|
|
8
|
+
# repo's NATIVE manifest (package.json) — no metadata API call — so inline
|
|
9
|
+
# npm install / npx tsc / npm run build / npm test are no longer needed here.
|
|
10
|
+
#
|
|
11
|
+
# GATE: `moko` is provided by mokocli on the runner PATH (/opt/mokocli/cli).
|
|
12
|
+
# It becomes available only after the mokocli build agent lands on `main` and
|
|
13
|
+
# the runner image is rebuilt. Until then this workflow is authored/reviewed
|
|
14
|
+
# but should not be expected to run green.
|
|
7
15
|
|
|
8
16
|
name: "MCP: Build & Validate"
|
|
9
17
|
|
|
@@ -18,6 +26,7 @@ on:
|
|
|
18
26
|
|
|
19
27
|
permissions:
|
|
20
28
|
contents: read
|
|
29
|
+
pull-requests: write
|
|
21
30
|
|
|
22
31
|
env:
|
|
23
32
|
MOKOGIT_URL: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }}
|
|
@@ -47,22 +56,57 @@ jobs:
|
|
|
47
56
|
with:
|
|
48
57
|
node-version: ${{ matrix.node-version }}
|
|
49
58
|
|
|
50
|
-
- name:
|
|
51
|
-
|
|
59
|
+
- name: Setup MokoCLI build agent (moko on PATH)
|
|
60
|
+
env:
|
|
61
|
+
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
|
|
62
|
+
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
|
|
63
|
+
run: |
|
|
64
|
+
# Reach mokocli the SAME way the release workflows' "Setup MokoCLI tools"
|
|
65
|
+
# step does: prefer the pre-installed /opt/mokocli, else fall back to a
|
|
66
|
+
# fresh clone. The only difference is we expose the `moko` binary on PATH
|
|
67
|
+
# (mokocli's cli/ dir) so `moko build|test|lint` resolve — we do NOT invent
|
|
68
|
+
# a new install mechanism.
|
|
69
|
+
if [ -x /opt/mokocli/cli/moko ] || [ -f /opt/mokocli/cli/moko ]; then
|
|
70
|
+
echo Using pre-installed /opt/mokocli
|
|
71
|
+
echo "/opt/mokocli/cli" >> "$GITHUB_PATH"
|
|
72
|
+
else
|
|
73
|
+
echo Falling back to fresh clone
|
|
74
|
+
MOKO_CLONE_TOKEN="$(printf '%s' "${MOKO_CLONE_TOKEN}" | tr -d '[:space:]')"
|
|
75
|
+
echo "::add-mask::${MOKO_CLONE_TOKEN}"
|
|
76
|
+
if [ -z "${MOKO_CLONE_TOKEN}" ]; then
|
|
77
|
+
echo "::error::MOKOGIT_TOKEN secret is empty — cannot clone mokocli fallback." >&2
|
|
78
|
+
exit 1
|
|
79
|
+
fi
|
|
80
|
+
if ! command -v composer > /dev/null 2>&1; then
|
|
81
|
+
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
|
|
82
|
+
fi
|
|
83
|
+
rm -rf /tmp/mokocli
|
|
84
|
+
CLONE_URL="https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git"
|
|
85
|
+
git clone --depth 1 --branch main --quiet "${CLONE_URL}" /tmp/mokocli
|
|
86
|
+
( cd /tmp/mokocli && composer install --no-dev --no-interaction --no-progress --optimize-autoloader --quiet )
|
|
87
|
+
echo "/tmp/mokocli/cli" >> "$GITHUB_PATH"
|
|
88
|
+
fi
|
|
52
89
|
|
|
53
|
-
- name:
|
|
54
|
-
run:
|
|
90
|
+
- name: Lint
|
|
91
|
+
run: moko lint
|
|
55
92
|
|
|
56
93
|
- name: Build
|
|
57
|
-
run:
|
|
94
|
+
run: moko build
|
|
95
|
+
|
|
96
|
+
- name: Test
|
|
97
|
+
run: moko test
|
|
58
98
|
|
|
59
99
|
- name: Verify dist output exists
|
|
60
100
|
run: |
|
|
101
|
+
# dist/index.js is the bin/main entry for every MCP server (shared
|
|
102
|
+
# package.json convention). Assert that + that the build emitted
|
|
103
|
+
# compiled output. Do NOT hard-code other filenames: source layouts
|
|
104
|
+
# differ per server (many have no client.ts/types.ts/root config.ts),
|
|
105
|
+
# which false-failed this check on every build fleet-wide.
|
|
61
106
|
test -f dist/index.js || (echo "ERROR: dist/index.js not found" && exit 1)
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
echo "✓ All required dist files present"
|
|
107
|
+
JS_COUNT=$(find dist -name '*.js' | wc -l)
|
|
108
|
+
[ "${JS_COUNT}" -gt 0 ] || (echo "ERROR: no compiled .js files in dist/" && exit 1)
|
|
109
|
+
echo "✓ dist/index.js present; ${JS_COUNT} compiled .js file(s) in dist/"
|
|
66
110
|
|
|
67
111
|
- name: Verify shebang in index.js
|
|
68
112
|
run: |
|
|
@@ -70,14 +114,54 @@ jobs:
|
|
|
70
114
|
|
|
71
115
|
- name: Count registered tools
|
|
72
116
|
run: |
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
117
|
+
# Tools may be registered in the entry file OR in modules it imports
|
|
118
|
+
# (modular servers call server.tool( / .registerTool( inside
|
|
119
|
+
# source/tools/*.ts). Count registrations across the whole source
|
|
120
|
+
# tree, not just index.ts, else modular servers false-report zero.
|
|
121
|
+
SRC_DIR="${{ steps.srcdir.outputs.source_dir }}"
|
|
122
|
+
[ -n "${SRC_DIR}" ] && [ -d "${SRC_DIR}" ] || SRC_DIR="source"
|
|
123
|
+
[ -d "${SRC_DIR}" ] || SRC_DIR="src"
|
|
124
|
+
TOOL_COUNT=$(grep -rE "server\.tool\(|\.registerTool\(" "${SRC_DIR}" 2>/dev/null | wc -l | tr -d ' ')
|
|
125
|
+
echo "Registered tool calls under ${SRC_DIR}: ${TOOL_COUNT}"
|
|
80
126
|
if [ "${TOOL_COUNT}" -eq 0 ]; then
|
|
81
|
-
echo "ERROR: No tools registered
|
|
127
|
+
echo "ERROR: No tools registered under ${SRC_DIR}"
|
|
82
128
|
exit 1
|
|
83
129
|
fi
|
|
130
|
+
|
|
131
|
+
ci-summary:
|
|
132
|
+
name: CI Summary (sticky comment)
|
|
133
|
+
runs-on: ubuntu-latest
|
|
134
|
+
needs: [build]
|
|
135
|
+
if: always()
|
|
136
|
+
steps:
|
|
137
|
+
- name: Upsert sticky CI summary comment
|
|
138
|
+
env:
|
|
139
|
+
TOKEN: ${{ secrets.MOKOGIT_TOKEN || github.token }}
|
|
140
|
+
SERVER: ${{ vars.MOKOGIT_URL || 'https://git.mokoconsulting.tech' }}
|
|
141
|
+
REPO: ${{ github.repository }}
|
|
142
|
+
PR: ${{ github.event.pull_request.number }}
|
|
143
|
+
BUILD: ${{ needs.build.result }}
|
|
144
|
+
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
145
|
+
HEAD_REF: ${{ github.head_ref }}
|
|
146
|
+
BASE_REF: ${{ github.base_ref }}
|
|
147
|
+
run: |
|
|
148
|
+
set -uo pipefail
|
|
149
|
+
{ [ -n "${TOKEN:-}" ] && [ -n "${PR:-}" ]; } || { echo "no token/PR; skip"; exit 0; }
|
|
150
|
+
icon() { case "$1" in success) printf '✅';; failure) printf '❌';; skipped) printf '⏭️';; *) printf '⚪';; esac; }
|
|
151
|
+
MARKER="<!-- ci-summary -->"
|
|
152
|
+
BODY="$(printf '%s\n## MCP Build & Validate\n\n- %s Build & validate (`%s` → `%s`)\n\n_Updated %s · [run](%s)_' \
|
|
153
|
+
"${MARKER}" \
|
|
154
|
+
"$(icon "${BUILD}")" "${HEAD_REF}" "${BASE_REF}" \
|
|
155
|
+
"$(date -u +%FT%TZ)" "${RUN_URL}")"
|
|
156
|
+
LIST="${SERVER}/api/v1/repos/${REPO}/issues/${PR}/comments"
|
|
157
|
+
EDIT="${SERVER}/api/v1/repos/${REPO}/issues/comments"
|
|
158
|
+
CID="$(curl -sf -H "Authorization: token ${TOKEN}" "${LIST}?limit=100" 2>/dev/null \
|
|
159
|
+
| python3 -c "import sys,json; c=[x for x in json.load(sys.stdin) if '${MARKER}' in (x.get('body') or '')]; print(c[-1]['id'] if c else '')" 2>/dev/null || true)"
|
|
160
|
+
PAYLOAD="$(python3 -c "import json,sys; print(json.dumps({'body': sys.stdin.read()}))" <<<"${BODY}")"
|
|
161
|
+
if [ -n "${CID}" ]; then
|
|
162
|
+
curl -sf -X PATCH -H "Authorization: token ${TOKEN}" -H "Content-Type: application/json" -d "${PAYLOAD}" "${EDIT}/${CID}" >/dev/null 2>&1 || true
|
|
163
|
+
echo "updated sticky CI summary #${CID} on PR #${PR}"
|
|
164
|
+
else
|
|
165
|
+
curl -sf -X POST -H "Authorization: token ${TOKEN}" -H "Content-Type: application/json" -d "${PAYLOAD}" "${LIST}" >/dev/null 2>&1 || true
|
|
166
|
+
echo "created sticky CI summary on PR #${PR}"
|
|
167
|
+
fi
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
#
|
|
5
|
+
# FILE INFORMATION
|
|
6
|
+
# DEFGROUP: MokoGIT.Workflow
|
|
7
|
+
# INGROUP: MokoCLI.Release
|
|
8
|
+
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-NPM
|
|
9
|
+
# PATH: /.mokogit/workflows/npm-prerelease.yml
|
|
10
|
+
# VERSION: 02.00.00
|
|
11
|
+
# BRIEF: Pre-release (dev/alpha/beta/rc) npm publishing for npm-family repos. Split
|
|
12
|
+
# out of the universal pre-release.yml (Template-Generic 06.01.00) so npm
|
|
13
|
+
# dist-tag publishing lives ONLY in the npm template. Build + publish now
|
|
14
|
+
# delegate to the centralized MokoCLI build agent (moko build / moko
|
|
15
|
+
# publish); `moko publish` preserves the same dev-channel dist-tag publish
|
|
16
|
+
# to npmjs.org + the MokoGIT npm registry that the former inline block did.
|
|
17
|
+
# npm-publish.yml handles STABLE (latest) on main; this handles the dev
|
|
18
|
+
# channel on dev.
|
|
19
|
+
#
|
|
20
|
+
# GATE: `moko` is provided by mokocli on the runner PATH (/opt/mokocli/cli),
|
|
21
|
+
# available only after the mokocli build agent lands on `main` and the runner
|
|
22
|
+
# image is rebuilt — authored/reviewed now, runs green later.
|
|
23
|
+
|
|
24
|
+
name: "Publish to npm (pre-release channel)"
|
|
25
|
+
|
|
26
|
+
on:
|
|
27
|
+
# Dev-channel publish on every merge to dev. paths-ignore is a non-code denylist:
|
|
28
|
+
# a push touching only docs / CI config / repo metadata does not publish. The
|
|
29
|
+
# concurrency guard below collapses a burst of merges into one.
|
|
30
|
+
push:
|
|
31
|
+
branches:
|
|
32
|
+
- dev
|
|
33
|
+
paths-ignore:
|
|
34
|
+
- '.mokogit/**'
|
|
35
|
+
- '.gitea/**'
|
|
36
|
+
- '.github/**'
|
|
37
|
+
- '.vscode/**'
|
|
38
|
+
- '.idea/**'
|
|
39
|
+
- 'docs/**'
|
|
40
|
+
- 'wiki/**'
|
|
41
|
+
- '**/*.md'
|
|
42
|
+
- '.editorconfig'
|
|
43
|
+
- '.gitignore'
|
|
44
|
+
- '.gitattributes'
|
|
45
|
+
- '.gitmodules'
|
|
46
|
+
- '.gitmessage'
|
|
47
|
+
- 'LICENSE'
|
|
48
|
+
schedule:
|
|
49
|
+
# Nightly at 07:00 UTC — safety-net batch for any dev merge a push publish missed.
|
|
50
|
+
- cron: '0 7 * * *'
|
|
51
|
+
workflow_dispatch:
|
|
52
|
+
inputs:
|
|
53
|
+
stability:
|
|
54
|
+
description: 'Pre-release channel'
|
|
55
|
+
required: true
|
|
56
|
+
default: development
|
|
57
|
+
type: choice
|
|
58
|
+
options:
|
|
59
|
+
- development
|
|
60
|
+
- alpha
|
|
61
|
+
- beta
|
|
62
|
+
- release-candidate
|
|
63
|
+
ref:
|
|
64
|
+
description: 'Branch to build (default: dev)'
|
|
65
|
+
required: false
|
|
66
|
+
default: dev
|
|
67
|
+
type: string
|
|
68
|
+
|
|
69
|
+
concurrency:
|
|
70
|
+
group: npm-prerelease-${{ github.ref }}-${{ inputs.stability || 'development' }}
|
|
71
|
+
cancel-in-progress: true
|
|
72
|
+
|
|
73
|
+
permissions:
|
|
74
|
+
contents: read
|
|
75
|
+
|
|
76
|
+
jobs:
|
|
77
|
+
publish:
|
|
78
|
+
name: "npm pre-release (${{ inputs.stability || 'development' }})"
|
|
79
|
+
runs-on: release
|
|
80
|
+
# Skip on template repos (Template-*) — they scaffold other repos and do not
|
|
81
|
+
# release. Triggers: push to dev, the nightly schedule, and manual dispatch.
|
|
82
|
+
# As defence-in-depth we also refuse a manual dispatch aimed at a bot/sync ref
|
|
83
|
+
# (mirrors pre-release.yml).
|
|
84
|
+
if: >-
|
|
85
|
+
!startsWith(github.event.repository.name, 'Template-') &&
|
|
86
|
+
(
|
|
87
|
+
github.event_name == 'push' ||
|
|
88
|
+
github.event_name == 'schedule' ||
|
|
89
|
+
(
|
|
90
|
+
github.event_name == 'workflow_dispatch' &&
|
|
91
|
+
!startsWith(inputs.ref, 'chore/') &&
|
|
92
|
+
!startsWith(inputs.ref, 'sync/') &&
|
|
93
|
+
!startsWith(inputs.ref, 'bot/') &&
|
|
94
|
+
!startsWith(inputs.ref, 'mokoonyx-template-sync') &&
|
|
95
|
+
!startsWith(inputs.ref, 'template-sync')
|
|
96
|
+
)
|
|
97
|
+
)
|
|
98
|
+
steps:
|
|
99
|
+
# Build ref: the dispatch input if given, else `dev` — correct for both a push
|
|
100
|
+
# (only `dev` triggers it) and the nightly schedule (where github.ref_name
|
|
101
|
+
# would otherwise be the default branch, main).
|
|
102
|
+
- name: Resolve build ref
|
|
103
|
+
id: ref
|
|
104
|
+
run: echo "ref=${{ inputs.ref || 'dev' }}" >> "$GITHUB_OUTPUT"
|
|
105
|
+
|
|
106
|
+
- name: Checkout
|
|
107
|
+
uses: actions/checkout@v4
|
|
108
|
+
with:
|
|
109
|
+
ref: ${{ steps.ref.outputs.ref }}
|
|
110
|
+
|
|
111
|
+
- name: Setup Node.js
|
|
112
|
+
uses: actions/setup-node@v4
|
|
113
|
+
with:
|
|
114
|
+
node-version: '20'
|
|
115
|
+
registry-url: 'https://registry.npmjs.org'
|
|
116
|
+
|
|
117
|
+
- name: Setup MokoCLI build agent (moko on PATH)
|
|
118
|
+
env:
|
|
119
|
+
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
|
|
120
|
+
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
|
|
121
|
+
run: |
|
|
122
|
+
# Reach mokocli the SAME way the release workflows' "Setup MokoCLI tools"
|
|
123
|
+
# step does: prefer the pre-installed /opt/mokocli, else a fresh clone. We
|
|
124
|
+
# expose the `moko` binary on PATH so `moko build|publish` resolve — no new
|
|
125
|
+
# install mechanism is introduced.
|
|
126
|
+
if [ -x /opt/mokocli/cli/moko ] || [ -f /opt/mokocli/cli/moko ]; then
|
|
127
|
+
echo Using pre-installed /opt/mokocli
|
|
128
|
+
echo "/opt/mokocli/cli" >> "$GITHUB_PATH"
|
|
129
|
+
else
|
|
130
|
+
echo Falling back to fresh clone
|
|
131
|
+
MOKO_CLONE_TOKEN="$(printf '%s' "${MOKO_CLONE_TOKEN}" | tr -d '[:space:]')"
|
|
132
|
+
echo "::add-mask::${MOKO_CLONE_TOKEN}"
|
|
133
|
+
if [ -z "${MOKO_CLONE_TOKEN}" ]; then
|
|
134
|
+
echo "::error::MOKOGIT_TOKEN secret is empty — cannot clone mokocli fallback." >&2
|
|
135
|
+
exit 1
|
|
136
|
+
fi
|
|
137
|
+
if ! command -v composer > /dev/null 2>&1; then
|
|
138
|
+
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
|
|
139
|
+
fi
|
|
140
|
+
rm -rf /tmp/mokocli
|
|
141
|
+
CLONE_URL="https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git"
|
|
142
|
+
git clone --depth 1 --branch main --quiet "${CLONE_URL}" /tmp/mokocli
|
|
143
|
+
( cd /tmp/mokocli && composer install --no-dev --no-interaction --no-progress --optimize-autoloader --quiet )
|
|
144
|
+
echo "/tmp/mokocli/cli" >> "$GITHUB_PATH"
|
|
145
|
+
fi
|
|
146
|
+
|
|
147
|
+
- name: Build
|
|
148
|
+
run: moko build
|
|
149
|
+
|
|
150
|
+
# dev/rc/beta/alpha channel maps to the matching npm dist-tag; the version is
|
|
151
|
+
# <base>-<tag>.<run_number> so it is unique per run and npm won't reject it.
|
|
152
|
+
# The nightly schedule always publishes the development channel. Repos without
|
|
153
|
+
# an NPM_TOKEN secret warn-and-skip rather than fail the run. Published to
|
|
154
|
+
# npmjs.org AND the MokoGIT npm registry (matching npm-publish.yml). A
|
|
155
|
+
# per-registry publish that fails because the version already exists is a
|
|
156
|
+
# warning, not a failure — the run only fails if BOTH registries reject it.
|
|
157
|
+
# moko publish preserves that dist-tag / dual-registry behavior; it derives
|
|
158
|
+
# the channel from --stability (schedule → development).
|
|
159
|
+
- name: Publish npm package (pre-release channel)
|
|
160
|
+
env:
|
|
161
|
+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
162
|
+
MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
|
|
163
|
+
run: |
|
|
164
|
+
set -uo pipefail
|
|
165
|
+
if [ -z "${NPM_TOKEN}" ]; then
|
|
166
|
+
echo "::warning::NPM_TOKEN not set — skipping npm pre-release publish"
|
|
167
|
+
exit 0
|
|
168
|
+
fi
|
|
169
|
+
if [ "${{ github.event_name }}" = "schedule" ]; then
|
|
170
|
+
STABILITY=development
|
|
171
|
+
else
|
|
172
|
+
STABILITY="${{ inputs.stability || 'development' }}"
|
|
173
|
+
fi
|
|
174
|
+
moko publish --stability "$STABILITY"
|
|
@@ -7,12 +7,19 @@
|
|
|
7
7
|
# INGROUP: MokoCLI.Release
|
|
8
8
|
# REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-NPM
|
|
9
9
|
# PATH: /.mokogit/workflows/npm-publish.yml
|
|
10
|
-
# VERSION:
|
|
10
|
+
# VERSION: 03.00.00
|
|
11
11
|
# BRIEF: Build + publish shim. The shared release engine (pre-release.yml /
|
|
12
12
|
# auto-release.yml) owns version bump, tag, changelog and release
|
|
13
13
|
# object; this workflow only builds and publishes the version the
|
|
14
14
|
# engine has already written to package.json. It never bumps or
|
|
15
|
-
# writes the version.
|
|
15
|
+
# writes the version. Build + publish now delegate to the centralized
|
|
16
|
+
# MokoCLI build agent (moko build / moko publish); `moko publish`
|
|
17
|
+
# preserves the same dual-registry npm publish (npmjs.org + the MokoGIT
|
|
18
|
+
# npm registry) that the former inline block performed.
|
|
19
|
+
#
|
|
20
|
+
# GATE: `moko` is provided by mokocli on the runner PATH (/opt/mokocli/cli),
|
|
21
|
+
# available only after the mokocli build agent lands on `main` and the runner
|
|
22
|
+
# image is rebuilt — authored/reviewed now, runs green later.
|
|
16
23
|
|
|
17
24
|
name: "Publish to npm"
|
|
18
25
|
|
|
@@ -85,13 +92,40 @@ jobs:
|
|
|
85
92
|
with:
|
|
86
93
|
node-version: '20'
|
|
87
94
|
|
|
88
|
-
- name:
|
|
95
|
+
- name: Setup MokoCLI build agent (moko on PATH)
|
|
89
96
|
if: steps.detect.outputs.changed == 'true'
|
|
90
|
-
|
|
97
|
+
env:
|
|
98
|
+
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
|
|
99
|
+
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
|
|
100
|
+
run: |
|
|
101
|
+
# Reach mokocli the SAME way the release workflows' "Setup MokoCLI tools"
|
|
102
|
+
# step does: prefer the pre-installed /opt/mokocli, else a fresh clone. We
|
|
103
|
+
# expose the `moko` binary on PATH so `moko build|publish` resolve — no new
|
|
104
|
+
# install mechanism is introduced.
|
|
105
|
+
if [ -x /opt/mokocli/cli/moko ] || [ -f /opt/mokocli/cli/moko ]; then
|
|
106
|
+
echo Using pre-installed /opt/mokocli
|
|
107
|
+
echo "/opt/mokocli/cli" >> "$GITHUB_PATH"
|
|
108
|
+
else
|
|
109
|
+
echo Falling back to fresh clone
|
|
110
|
+
MOKO_CLONE_TOKEN="$(printf '%s' "${MOKO_CLONE_TOKEN}" | tr -d '[:space:]')"
|
|
111
|
+
echo "::add-mask::${MOKO_CLONE_TOKEN}"
|
|
112
|
+
if [ -z "${MOKO_CLONE_TOKEN}" ]; then
|
|
113
|
+
echo "::error::MOKOGIT_TOKEN secret is empty — cannot clone mokocli fallback." >&2
|
|
114
|
+
exit 1
|
|
115
|
+
fi
|
|
116
|
+
if ! command -v composer > /dev/null 2>&1; then
|
|
117
|
+
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
|
|
118
|
+
fi
|
|
119
|
+
rm -rf /tmp/mokocli
|
|
120
|
+
CLONE_URL="https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git"
|
|
121
|
+
git clone --depth 1 --branch main --quiet "${CLONE_URL}" /tmp/mokocli
|
|
122
|
+
( cd /tmp/mokocli && composer install --no-dev --no-interaction --no-progress --optimize-autoloader --quiet )
|
|
123
|
+
echo "/tmp/mokocli/cli" >> "$GITHUB_PATH"
|
|
124
|
+
fi
|
|
91
125
|
|
|
92
126
|
- name: Build
|
|
93
127
|
if: steps.detect.outputs.changed == 'true'
|
|
94
|
-
run:
|
|
128
|
+
run: moko build
|
|
95
129
|
|
|
96
130
|
- name: Read version to publish
|
|
97
131
|
id: version
|
|
@@ -109,18 +143,11 @@ jobs:
|
|
|
109
143
|
- name: Publish to npmjs.org + git.mokoconsulting.tech
|
|
110
144
|
if: steps.detect.outputs.changed == 'true'
|
|
111
145
|
run: |
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
VER=$(node -p "require('./package.json').version")
|
|
118
|
-
rc=0
|
|
119
|
-
echo "Publishing ${VER} -> npmjs.org"
|
|
120
|
-
npm publish --access public --registry https://registry.npmjs.org/ || { echo "::warning::npmjs.org publish failed (version ${VER} may already exist)"; rc=$((rc+1)); }
|
|
121
|
-
echo "Publishing ${VER} -> git.mokoconsulting.tech"
|
|
122
|
-
npm publish --access public --registry https://git.mokoconsulting.tech/api/packages/MokoConsulting/npm/ || { echo "::warning::git.mokoconsulting.tech publish failed (version ${VER} may already exist)"; rc=$((rc+1)); }
|
|
123
|
-
[ "$rc" -lt 2 ]
|
|
146
|
+
# moko publish preserves the former inline behavior: idempotent dual-registry
|
|
147
|
+
# npm publish to npmjs.org AND the MokoGIT npm registry, publishing the version
|
|
148
|
+
# the release engine already wrote to package.json (never bumps). It reads the
|
|
149
|
+
# registry auth tokens from the environment below.
|
|
150
|
+
moko publish
|
|
124
151
|
env:
|
|
125
152
|
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
126
153
|
MOKOGIT_TOKEN: ${{ secrets.MOKOGIT_TOKEN }}
|