@mokoconsulting/mcp-mokogitea-api 1.4.0 → 1.4.1
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/.mokogitea/workflows/auto-bump.yml +9 -9
- package/.mokogitea/workflows/auto-release.yml +90 -28
- package/.mokogitea/workflows/branch-cleanup.yml +1 -1
- package/.mokogitea/workflows/npm-publish.yml +69 -10
- package/.mokogitea/workflows/pr-check.yml +2 -2
- package/.mokogitea/workflows/pre-release.yml +244 -3
- package/.mokogitea/workflows/repo-health.yml +4 -3
- package/dist/client.js +20 -1
- package/dist/index.js +10 -2
- package/package.json +1 -1
- package/src/client.ts +15 -1
- package/src/index.ts +10 -2
- package/Dockerfile +0 -18
- package/dist/server.d.ts +0 -4
- package/dist/server.js +0 -12
- package/dist/sse.d.ts +0 -2
- package/dist/sse.js +0 -87
- package/src/server.ts +0 -16
- package/src/sse.ts +0 -100
- package/wiki/ARCHITECTURE.md +0 -144
- package/wiki/Home.md +0 -35
- package/wiki/INSTALLATION.md +0 -170
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
#
|
|
5
5
|
# FILE INFORMATION
|
|
6
6
|
# DEFGROUP: Gitea.Workflow
|
|
7
|
-
# INGROUP:
|
|
8
|
-
# REPO: https://git.mokoconsulting.tech/MokoConsulting/
|
|
7
|
+
# INGROUP: mokocli.Release
|
|
8
|
+
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
|
9
9
|
# PATH: /.mokogitea/workflows/auto-bump.yml
|
|
10
10
|
# VERSION: 09.02.00
|
|
11
11
|
# BRIEF: Auto patch-bump version on every push to dev (skips merge commits)
|
|
@@ -43,19 +43,19 @@ jobs:
|
|
|
43
43
|
token: ${{ secrets.MOKOGITEA_TOKEN }}
|
|
44
44
|
fetch-depth: 1
|
|
45
45
|
|
|
46
|
-
- name: Setup
|
|
46
|
+
- name: Setup mokocli tools
|
|
47
47
|
run: |
|
|
48
48
|
if ! command -v composer &> /dev/null; then
|
|
49
49
|
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
|
|
50
50
|
fi
|
|
51
|
-
if [ -d "/opt/
|
|
52
|
-
echo "MOKO_CLI=/opt/
|
|
51
|
+
if [ -d "/opt/mokocli/cli" ]; then
|
|
52
|
+
echo "MOKO_CLI=/opt/mokocli/cli" >> "$GITHUB_ENV"
|
|
53
53
|
else
|
|
54
54
|
git clone --depth 1 --branch main --quiet \
|
|
55
|
-
"https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/
|
|
56
|
-
/tmp/
|
|
57
|
-
cd /tmp/
|
|
58
|
-
echo "MOKO_CLI=/tmp/
|
|
55
|
+
"https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/MokoConsulting/mokocli.git" \
|
|
56
|
+
/tmp/mokocli
|
|
57
|
+
cd /tmp/mokocli && composer install --no-dev --no-interaction --quiet
|
|
58
|
+
echo "MOKO_CLI=/tmp/mokocli/cli" >> "$GITHUB_ENV"
|
|
59
59
|
fi
|
|
60
60
|
|
|
61
61
|
- name: Bump version
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
#
|
|
5
5
|
# FILE INFORMATION
|
|
6
6
|
# DEFGROUP: Gitea.Workflow
|
|
7
|
-
# INGROUP:
|
|
8
|
-
# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/
|
|
7
|
+
# INGROUP: mokocli.Release
|
|
8
|
+
# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli
|
|
9
9
|
# PATH: /templates/workflows/universal/auto-release.yml.template
|
|
10
10
|
# VERSION: 05.00.00
|
|
11
11
|
# BRIEF: Universal build & release � detects platform from manifest.xml
|
|
@@ -66,25 +66,25 @@ jobs:
|
|
|
66
66
|
token: ${{ secrets.MOKOGITEA_TOKEN }}
|
|
67
67
|
fetch-depth: 1
|
|
68
68
|
|
|
69
|
-
- name: Setup
|
|
69
|
+
- name: Setup mokocli tools
|
|
70
70
|
env:
|
|
71
71
|
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
|
72
72
|
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
|
|
73
73
|
run: |
|
|
74
|
-
if [ -f /opt/
|
|
75
|
-
echo Using pre-installed /opt/
|
|
76
|
-
echo MOKO_CLI=/opt/
|
|
74
|
+
if [ -f /opt/mokocli/cli/version_bump.php ] && [ -f /opt/mokocli/vendor/autoload.php ]; then
|
|
75
|
+
echo Using pre-installed /opt/mokocli
|
|
76
|
+
echo MOKO_CLI=/opt/mokocli/cli >> $GITHUB_ENV
|
|
77
77
|
else
|
|
78
78
|
echo Falling back to fresh clone
|
|
79
79
|
if ! command -v composer > /dev/null 2>&1; then
|
|
80
80
|
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
|
|
81
81
|
fi
|
|
82
|
-
rm -rf /tmp/
|
|
83
|
-
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/
|
|
84
|
-
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/
|
|
85
|
-
cd /tmp/
|
|
82
|
+
rm -rf /tmp/mokocli
|
|
83
|
+
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git
|
|
84
|
+
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
|
|
85
|
+
cd /tmp/mokocli
|
|
86
86
|
composer install --no-dev --no-interaction --quiet
|
|
87
|
-
echo MOKO_CLI=/tmp/
|
|
87
|
+
echo MOKO_CLI=/tmp/mokocli/cli >> $GITHUB_ENV
|
|
88
88
|
fi
|
|
89
89
|
|
|
90
90
|
- name: Rename branch to rc
|
|
@@ -109,6 +109,40 @@ jobs:
|
|
|
109
109
|
--path . --stability rc --bump minor --branch rc \
|
|
110
110
|
--token "${{ secrets.MOKOGITEA_TOKEN }}"
|
|
111
111
|
|
|
112
|
+
- name: Update RC release notes from CHANGELOG.md
|
|
113
|
+
run: |
|
|
114
|
+
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
|
115
|
+
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
|
|
116
|
+
|
|
117
|
+
# Extract [Unreleased] section from changelog
|
|
118
|
+
NOTES=""
|
|
119
|
+
if [ -f "CHANGELOG.md" ]; then
|
|
120
|
+
NOTES=$(awk '/^## \[Unreleased\]/{found=1; next} /^## \[/{if(found) exit} found{print}' CHANGELOG.md)
|
|
121
|
+
fi
|
|
122
|
+
[ -z "$NOTES" ] && NOTES="Release candidate"
|
|
123
|
+
|
|
124
|
+
# Find the RC release and update its body
|
|
125
|
+
RELEASE_ID=$(curl -sf -H "Authorization: token ${TOKEN}" \
|
|
126
|
+
"${API_BASE}/releases/tags/release-candidate" \
|
|
127
|
+
| python3 -c "import json,sys; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true)
|
|
128
|
+
|
|
129
|
+
if [ -n "$RELEASE_ID" ]; then
|
|
130
|
+
python3 -c "
|
|
131
|
+
import json, urllib.request
|
|
132
|
+
body = open('/dev/stdin').read()
|
|
133
|
+
payload = json.dumps({'body': body}).encode()
|
|
134
|
+
req = urllib.request.Request(
|
|
135
|
+
'${API_BASE}/releases/${RELEASE_ID}',
|
|
136
|
+
data=payload, method='PATCH',
|
|
137
|
+
headers={
|
|
138
|
+
'Authorization': 'token ${TOKEN}',
|
|
139
|
+
'Content-Type': 'application/json'
|
|
140
|
+
})
|
|
141
|
+
urllib.request.urlopen(req)
|
|
142
|
+
" <<< "$NOTES"
|
|
143
|
+
echo "RC release notes updated from CHANGELOG.md"
|
|
144
|
+
fi
|
|
145
|
+
|
|
112
146
|
- name: Summary
|
|
113
147
|
if: always()
|
|
114
148
|
run: |
|
|
@@ -149,26 +183,26 @@ jobs:
|
|
|
149
183
|
fi
|
|
150
184
|
echo "No conflict markers found"
|
|
151
185
|
|
|
152
|
-
- name: Setup
|
|
186
|
+
- name: Setup mokocli tools
|
|
153
187
|
env:
|
|
154
188
|
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
|
155
189
|
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
|
|
156
190
|
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_MIRROR_TOKEN }}"}}'
|
|
157
191
|
run: |
|
|
158
|
-
if [ -f /opt/
|
|
159
|
-
echo Using pre-installed /opt/
|
|
160
|
-
echo MOKO_CLI=/opt/
|
|
192
|
+
if [ -f /opt/mokocli/cli/version_bump.php ] && [ -f /opt/mokocli/vendor/autoload.php ]; then
|
|
193
|
+
echo Using pre-installed /opt/mokocli
|
|
194
|
+
echo MOKO_CLI=/opt/mokocli/cli >> $GITHUB_ENV
|
|
161
195
|
else
|
|
162
196
|
echo Falling back to fresh clone
|
|
163
197
|
if ! command -v composer > /dev/null 2>&1; then
|
|
164
198
|
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
|
|
165
199
|
fi
|
|
166
|
-
rm -rf /tmp/
|
|
167
|
-
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/
|
|
168
|
-
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/
|
|
169
|
-
cd /tmp/
|
|
200
|
+
rm -rf /tmp/mokocli
|
|
201
|
+
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git
|
|
202
|
+
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
|
|
203
|
+
cd /tmp/mokocli
|
|
170
204
|
composer install --no-dev --no-interaction --quiet
|
|
171
|
-
echo MOKO_CLI=/tmp/
|
|
205
|
+
echo MOKO_CLI=/tmp/mokocli/cli >> $GITHUB_ENV
|
|
172
206
|
fi
|
|
173
207
|
|
|
174
208
|
- name: "Determine version bump level"
|
|
@@ -194,22 +228,32 @@ jobs:
|
|
|
194
228
|
--path . --stability stable ${BUMP_FLAG} --branch main \
|
|
195
229
|
--token "${{ secrets.MOKOGITEA_TOKEN }}"
|
|
196
230
|
|
|
197
|
-
- name: Update release notes
|
|
231
|
+
- name: Update release notes and promote changelog
|
|
198
232
|
run: |
|
|
199
233
|
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
|
234
|
+
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
|
|
235
|
+
|
|
236
|
+
# Get the stable release info (version and ID)
|
|
237
|
+
RELEASE_JSON=$(curl -sf -H "Authorization: token ${TOKEN}" \
|
|
238
|
+
"${API_BASE}/releases/tags/stable" 2>/dev/null || echo '{}')
|
|
239
|
+
RELEASE_ID=$(python3 -c "import json,sys; print(json.load(sys.stdin).get('id',''))" <<< "$RELEASE_JSON" 2>/dev/null || true)
|
|
240
|
+
# Extract version from release name (e.g. "06.17.00" or "v06.17.00")
|
|
241
|
+
VERSION=$(python3 -c "
|
|
242
|
+
import json, sys, re
|
|
243
|
+
r = json.load(sys.stdin)
|
|
244
|
+
name = r.get('name', '')
|
|
245
|
+
m = re.search(r'(\d+\.\d+\.\d+)', name)
|
|
246
|
+
print(m.group(1) if m else '')
|
|
247
|
+
" <<< "$RELEASE_JSON" 2>/dev/null || true)
|
|
200
248
|
|
|
201
249
|
# Extract [Unreleased] section from changelog
|
|
250
|
+
NOTES=""
|
|
202
251
|
if [ -f "CHANGELOG.md" ]; then
|
|
203
252
|
NOTES=$(awk '/^## \[Unreleased\]/{found=1; next} /^## \[/{if(found) exit} found{print}' CHANGELOG.md)
|
|
204
|
-
[ -z "$NOTES" ] && NOTES="Stable release"
|
|
205
|
-
else
|
|
206
|
-
NOTES="Stable release"
|
|
207
253
|
fi
|
|
254
|
+
[ -z "$NOTES" ] && NOTES="Stable release"
|
|
208
255
|
|
|
209
256
|
# Update release body via API
|
|
210
|
-
RELEASE_ID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \
|
|
211
|
-
"${API_BASE}/releases/tags/stable" | python3 -c "import json,sys; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true)
|
|
212
|
-
|
|
213
257
|
if [ -n "$RELEASE_ID" ]; then
|
|
214
258
|
python3 -c "
|
|
215
259
|
import json, urllib.request
|
|
@@ -219,7 +263,7 @@ jobs:
|
|
|
219
263
|
'${API_BASE}/releases/${RELEASE_ID}',
|
|
220
264
|
data=payload, method='PATCH',
|
|
221
265
|
headers={
|
|
222
|
-
'Authorization': 'token ${
|
|
266
|
+
'Authorization': 'token ${TOKEN}',
|
|
223
267
|
'Content-Type': 'application/json'
|
|
224
268
|
})
|
|
225
269
|
urllib.request.urlopen(req)
|
|
@@ -227,6 +271,24 @@ jobs:
|
|
|
227
271
|
echo "Release notes updated from CHANGELOG.md"
|
|
228
272
|
fi
|
|
229
273
|
|
|
274
|
+
# Promote [Unreleased] → [version] in CHANGELOG.md and reset
|
|
275
|
+
if [ -n "$VERSION" ] && [ -f "CHANGELOG.md" ]; then
|
|
276
|
+
DATE=$(date +%Y-%m-%d)
|
|
277
|
+
python3 -c "
|
|
278
|
+
import sys
|
|
279
|
+
version, date = sys.argv[1], sys.argv[2]
|
|
280
|
+
content = open('CHANGELOG.md').read()
|
|
281
|
+
old = '## [Unreleased]'
|
|
282
|
+
new = f'## [Unreleased]\n\n## [{version}] --- {date}'
|
|
283
|
+
content = content.replace(old, new, 1)
|
|
284
|
+
open('CHANGELOG.md', 'w').write(content)
|
|
285
|
+
" "$VERSION" "$DATE"
|
|
286
|
+
git add CHANGELOG.md
|
|
287
|
+
git commit -m "chore: promote changelog [Unreleased] → [${VERSION}]" || true
|
|
288
|
+
git push origin main || true
|
|
289
|
+
echo "Changelog promoted: [Unreleased] → [${VERSION}]"
|
|
290
|
+
fi
|
|
291
|
+
|
|
230
292
|
# -- STEP 9: Mirror to GitHub (stable only) --------------------------------
|
|
231
293
|
- name: "Step 9: Mirror release to GitHub"
|
|
232
294
|
if: >-
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# FILE INFORMATION
|
|
6
6
|
# DEFGROUP: Gitea.Workflow
|
|
7
7
|
# INGROUP: MokoStandards.Universal
|
|
8
|
-
# REPO: https://git.mokoconsulting.tech/MokoConsulting/
|
|
8
|
+
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
|
9
9
|
# PATH: /.mokogitea/workflows/branch-cleanup.yml
|
|
10
10
|
# VERSION: 01.00.00
|
|
11
11
|
# BRIEF: Delete feature branches after PR merge
|
|
@@ -9,9 +9,17 @@ on:
|
|
|
9
9
|
- main
|
|
10
10
|
workflow_dispatch:
|
|
11
11
|
|
|
12
|
+
env:
|
|
13
|
+
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
|
14
|
+
GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
|
|
15
|
+
GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }}
|
|
16
|
+
|
|
12
17
|
jobs:
|
|
13
18
|
publish:
|
|
14
19
|
runs-on: ubuntu-latest
|
|
20
|
+
if: >-
|
|
21
|
+
!contains(github.event.head_commit.message, '[skip ci]') &&
|
|
22
|
+
!contains(github.event.head_commit.message, '[skip publish]')
|
|
15
23
|
steps:
|
|
16
24
|
- name: Checkout
|
|
17
25
|
uses: actions/checkout@v4
|
|
@@ -30,20 +38,71 @@ jobs:
|
|
|
30
38
|
|
|
31
39
|
- name: Auto-bump patch version
|
|
32
40
|
run: |
|
|
41
|
+
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
|
42
|
+
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
|
|
43
|
+
|
|
33
44
|
PKG_NAME=$(node -p "require('./package.json').name")
|
|
34
45
|
CURRENT=$(node -p "require('./package.json').version")
|
|
35
46
|
PUBLISHED=$(npm view "${PKG_NAME}@latest" version 2>/dev/null || echo "0.0.0")
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
NEW_VER=$(node -p "require('./package.json').version")
|
|
39
|
-
echo "Bumped ${CURRENT} -> ${NEW_VER}"
|
|
40
|
-
git config user.name "github-actions[bot]"
|
|
41
|
-
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
42
|
-
git add package.json
|
|
43
|
-
git commit -m "chore: bump to ${NEW_VER} [skip ci]"
|
|
44
|
-
git push
|
|
45
|
-
else
|
|
47
|
+
|
|
48
|
+
if [ "$CURRENT" != "$PUBLISHED" ]; then
|
|
46
49
|
echo "Version ${CURRENT} not yet published, using as-is."
|
|
50
|
+
exit 0
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Bump locally to get the new version
|
|
54
|
+
npm version patch --no-git-tag-version
|
|
55
|
+
NEW_VER=$(node -p "require('./package.json').version")
|
|
56
|
+
echo "Bumping ${CURRENT} -> ${NEW_VER}"
|
|
57
|
+
|
|
58
|
+
# Push via Gitea API: branch + PR + merge
|
|
59
|
+
BRANCH="chore/npm-version-bump"
|
|
60
|
+
FILEPATH="package.json"
|
|
61
|
+
CONTENT=$(base64 -w 0 < package.json)
|
|
62
|
+
COMMIT_MSG="chore: bump to ${NEW_VER} [skip ci]"
|
|
63
|
+
|
|
64
|
+
# Get current file SHA on main
|
|
65
|
+
FILE_SHA=$(curl -sf -H "Authorization: token ${TOKEN}" \
|
|
66
|
+
"${API_BASE}/contents/${FILEPATH}?ref=main" \
|
|
67
|
+
| python3 -c "import json,sys; print(json.load(sys.stdin).get('sha',''))" 2>/dev/null || true)
|
|
68
|
+
|
|
69
|
+
# Create chore branch from main
|
|
70
|
+
curl -sf -X POST -H "Authorization: token ${TOKEN}" \
|
|
71
|
+
-H "Content-Type: application/json" \
|
|
72
|
+
"${API_BASE}/branches" \
|
|
73
|
+
-d "{\"new_branch_name\":\"${BRANCH}\",\"old_branch_name\":\"main\"}" 2>/dev/null || true
|
|
74
|
+
|
|
75
|
+
# Get file SHA on chore branch (may differ if branch already existed)
|
|
76
|
+
BRANCH_SHA=$(curl -sf -H "Authorization: token ${TOKEN}" \
|
|
77
|
+
"${API_BASE}/contents/${FILEPATH}?ref=${BRANCH}" \
|
|
78
|
+
| python3 -c "import json,sys; print(json.load(sys.stdin).get('sha',''))" 2>/dev/null || true)
|
|
79
|
+
[ -n "$BRANCH_SHA" ] && FILE_SHA="$BRANCH_SHA"
|
|
80
|
+
|
|
81
|
+
# Push package.json to chore branch
|
|
82
|
+
PAYLOAD="{\"content\":\"${CONTENT}\",\"message\":\"${COMMIT_MSG}\",\"branch\":\"${BRANCH}\",\"sha\":\"${FILE_SHA}\"}"
|
|
83
|
+
HTTP=$(curl -sf -o /dev/null -w "%{http_code}" -X PUT \
|
|
84
|
+
-H "Authorization: token ${TOKEN}" \
|
|
85
|
+
-H "Content-Type: application/json" \
|
|
86
|
+
-d "$PAYLOAD" \
|
|
87
|
+
"${API_BASE}/contents/${FILEPATH}" 2>/dev/null || echo "ERR")
|
|
88
|
+
echo "File push: HTTP ${HTTP}"
|
|
89
|
+
|
|
90
|
+
# Create PR
|
|
91
|
+
PR_NUM=$(curl -sf -X POST -H "Authorization: token ${TOKEN}" \
|
|
92
|
+
-H "Content-Type: application/json" \
|
|
93
|
+
"${API_BASE}/pulls" \
|
|
94
|
+
-d "{\"title\":\"${COMMIT_MSG}\",\"head\":\"${BRANCH}\",\"base\":\"main\"}" \
|
|
95
|
+
| python3 -c "import json,sys; print(json.load(sys.stdin).get('number',''))" 2>/dev/null || true)
|
|
96
|
+
|
|
97
|
+
if [ -n "$PR_NUM" ]; then
|
|
98
|
+
# Merge PR
|
|
99
|
+
curl -sf -X POST -H "Authorization: token ${TOKEN}" \
|
|
100
|
+
-H "Content-Type: application/json" \
|
|
101
|
+
"${API_BASE}/pulls/${PR_NUM}/merge" \
|
|
102
|
+
-d "{\"Do\":\"merge\",\"merge_message_field\":\"${COMMIT_MSG}\"}" 2>/dev/null
|
|
103
|
+
echo "Version bumped via PR #${PR_NUM} (merged)"
|
|
104
|
+
else
|
|
105
|
+
echo "::warning::Could not create PR for version bump — publishing with current version"
|
|
47
106
|
fi
|
|
48
107
|
env:
|
|
49
108
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
#
|
|
5
5
|
# FILE INFORMATION
|
|
6
6
|
# DEFGROUP: Gitea.Workflow
|
|
7
|
-
# INGROUP:
|
|
8
|
-
# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/
|
|
7
|
+
# INGROUP: mokocli.CI
|
|
8
|
+
# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli
|
|
9
9
|
# PATH: /templates/workflows/universal/pr-check.yml.template
|
|
10
10
|
# VERSION: 09.23.00
|
|
11
11
|
# BRIEF: PR gate — branch policy + code validation before merge
|
|
@@ -4,8 +4,249 @@
|
|
|
4
4
|
#
|
|
5
5
|
# FILE INFORMATION
|
|
6
6
|
# DEFGROUP: Gitea.Workflow
|
|
7
|
-
# INGROUP:
|
|
8
|
-
# REPO: https://git.mokoconsulting.tech/MokoConsulting/
|
|
7
|
+
# INGROUP: mokocli.Release
|
|
8
|
+
# REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
|
9
9
|
# PATH: /templates/workflows/universal/pre-release.yml.template
|
|
10
10
|
# VERSION: 05.01.00
|
|
11
|
-
# BRIEF: Auto pre-release on push to dev/alpha/beta/rc branches
|
|
11
|
+
# BRIEF: Auto pre-release on push to dev/alpha/beta/rc branches
|
|
12
|
+
|
|
13
|
+
name: "Universal: Pre-Release"
|
|
14
|
+
|
|
15
|
+
on:
|
|
16
|
+
push:
|
|
17
|
+
branches:
|
|
18
|
+
- dev
|
|
19
|
+
- 'fix/**'
|
|
20
|
+
- 'patch/**'
|
|
21
|
+
- 'hotfix/**'
|
|
22
|
+
- 'bugfix/**'
|
|
23
|
+
- 'chore/**'
|
|
24
|
+
- alpha
|
|
25
|
+
- beta
|
|
26
|
+
- rc
|
|
27
|
+
workflow_dispatch:
|
|
28
|
+
inputs:
|
|
29
|
+
stability:
|
|
30
|
+
description: 'Pre-release channel'
|
|
31
|
+
required: true
|
|
32
|
+
type: choice
|
|
33
|
+
options:
|
|
34
|
+
- development
|
|
35
|
+
- alpha
|
|
36
|
+
- beta
|
|
37
|
+
- release-candidate
|
|
38
|
+
|
|
39
|
+
permissions:
|
|
40
|
+
contents: write
|
|
41
|
+
|
|
42
|
+
env:
|
|
43
|
+
GITEA_URL: ${{ vars.GITEA_URL || 'https://git.mokoconsulting.tech' }}
|
|
44
|
+
GITEA_ORG: ${{ vars.GITEA_ORG || github.repository_owner }}
|
|
45
|
+
GITEA_REPO: ${{ vars.GITEA_REPO || github.event.repository.name }}
|
|
46
|
+
|
|
47
|
+
jobs:
|
|
48
|
+
build:
|
|
49
|
+
name: "Build Pre-Release (${{ inputs.stability || github.ref_name }})"
|
|
50
|
+
runs-on: release
|
|
51
|
+
if: >-
|
|
52
|
+
github.event_name == 'workflow_dispatch' ||
|
|
53
|
+
github.event_name == 'push'
|
|
54
|
+
|
|
55
|
+
steps:
|
|
56
|
+
- name: Checkout
|
|
57
|
+
uses: actions/checkout@v4
|
|
58
|
+
with:
|
|
59
|
+
fetch-depth: 0
|
|
60
|
+
token: ${{ secrets.MOKOGITEA_TOKEN }}
|
|
61
|
+
ref: ${{ github.ref_name }}
|
|
62
|
+
|
|
63
|
+
- name: Setup mokocli tools
|
|
64
|
+
env:
|
|
65
|
+
MOKO_CLONE_TOKEN: ${{ secrets.MOKOGITEA_TOKEN }}
|
|
66
|
+
MOKO_CLONE_HOST: git.mokoconsulting.tech/MokoConsulting
|
|
67
|
+
run: |
|
|
68
|
+
# Use pre-installed /opt/mokocli if available (updated by cron every 6h)
|
|
69
|
+
if [ -f /opt/mokocli/cli/version_bump.php ] && [ -f /opt/mokocli/cli/manifest_element.php ] && [ -f /opt/mokocli/vendor/autoload.php ]; then
|
|
70
|
+
echo Using pre-installed /opt/mokocli
|
|
71
|
+
echo MOKO_CLI=/opt/mokocli/cli >> $GITHUB_ENV
|
|
72
|
+
else
|
|
73
|
+
echo Falling back to fresh clone
|
|
74
|
+
if ! command -v composer > /dev/null 2>&1; then
|
|
75
|
+
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
|
|
76
|
+
fi
|
|
77
|
+
rm -rf /tmp/mokocli
|
|
78
|
+
CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/mokocli.git
|
|
79
|
+
git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/mokocli
|
|
80
|
+
cd /tmp/mokocli && composer install --no-dev --no-interaction --quiet
|
|
81
|
+
echo MOKO_CLI=/tmp/mokocli/cli >> $GITHUB_ENV
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
- name: Detect platform
|
|
85
|
+
id: platform
|
|
86
|
+
run: |
|
|
87
|
+
# Auto-detect and update platform if not set in manifest
|
|
88
|
+
php ${MOKO_CLI}/platform_detect.php --path . --github-output 2>/dev/null || true
|
|
89
|
+
php ${MOKO_CLI}/manifest_read.php --path . --github-output
|
|
90
|
+
|
|
91
|
+
- name: Resolve metadata and bump version
|
|
92
|
+
id: meta
|
|
93
|
+
run: |
|
|
94
|
+
# Auto-detect stability from branch name on push, or use input on dispatch
|
|
95
|
+
if [ "${{ github.event_name }}" = "push" ]; then
|
|
96
|
+
case "${{ github.ref_name }}" in
|
|
97
|
+
rc) STABILITY="release-candidate" ;;
|
|
98
|
+
alpha) STABILITY="alpha" ;;
|
|
99
|
+
beta) STABILITY="beta" ;;
|
|
100
|
+
*) STABILITY="development" ;;
|
|
101
|
+
esac
|
|
102
|
+
else
|
|
103
|
+
STABILITY="${{ inputs.stability || 'development' }}"
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
case "$STABILITY" in
|
|
107
|
+
development) SUFFIX="-dev"; TAG="development" ;;
|
|
108
|
+
alpha) SUFFIX="-alpha"; TAG="alpha" ;;
|
|
109
|
+
beta) SUFFIX="-beta"; TAG="beta" ;;
|
|
110
|
+
release-candidate) SUFFIX="-rc"; TAG="release-candidate" ;;
|
|
111
|
+
esac
|
|
112
|
+
|
|
113
|
+
# Bump version via CLI: patch for dev/alpha/beta, minor for RC
|
|
114
|
+
case "$STABILITY" in
|
|
115
|
+
release-candidate) BUMP="minor" ;;
|
|
116
|
+
*) BUMP="patch" ;;
|
|
117
|
+
esac
|
|
118
|
+
|
|
119
|
+
php ${MOKO_CLI}/version_bump.php --path . $([ "$BUMP" = "minor" ] && echo "--minor") 2>/dev/null || true
|
|
120
|
+
|
|
121
|
+
# Set stability suffix and verify consistency
|
|
122
|
+
VERSION=$(php ${MOKO_CLI}/version_read.php --path . 2>/dev/null || echo "00.00.01")
|
|
123
|
+
VERSION=$(echo "$VERSION" | sed 's/-\(dev\|alpha\|beta\|rc\)$//')
|
|
124
|
+
|
|
125
|
+
php ${MOKO_CLI}/version_set_platform.php \
|
|
126
|
+
--path . --version "$VERSION" --branch "${{ github.ref_name }}" --stability "$STABILITY" 2>/dev/null || true
|
|
127
|
+
php ${MOKO_CLI}/version_check.php --path . --fix 2>/dev/null || true
|
|
128
|
+
|
|
129
|
+
# Ensure licensing tags (updateservers, dlid) if enabled in manifest.xml
|
|
130
|
+
php ${MOKO_CLI}/manifest_licensing.php --path . --fix 2>/dev/null || true
|
|
131
|
+
|
|
132
|
+
# Append suffix for output
|
|
133
|
+
if [ -n "$SUFFIX" ]; then
|
|
134
|
+
VERSION="${VERSION}${SUFFIX}"
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
# Commit version bump
|
|
138
|
+
git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
|
|
139
|
+
git config --local user.name "gitea-actions[bot]"
|
|
140
|
+
git remote set-url origin "https://x-access-token:${{ secrets.MOKOGITEA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
|
|
141
|
+
git add -A
|
|
142
|
+
git diff --cached --quiet || {
|
|
143
|
+
git commit -m "chore(version): pre-release bump to ${VERSION} [skip ci]"
|
|
144
|
+
git push origin HEAD 2>&1
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
# Auto-detect element via manifest_element.php
|
|
148
|
+
php ${MOKO_CLI}/manifest_element.php \
|
|
149
|
+
--path . --version "$VERSION" --stability "$STABILITY" \
|
|
150
|
+
--repo "${GITEA_REPO}" --github-output
|
|
151
|
+
|
|
152
|
+
# Read back element outputs
|
|
153
|
+
EXT_ELEMENT=$(grep '^ext_element=' "$GITHUB_OUTPUT" | tail -1 | cut -d= -f2)
|
|
154
|
+
ZIP_NAME=$(grep '^zip_name=' "$GITHUB_OUTPUT" | tail -1 | cut -d= -f2)
|
|
155
|
+
[ -z "$EXT_ELEMENT" ] && EXT_ELEMENT=$(echo "${GITEA_REPO}" | tr '[:upper:]' '[:lower:]' | tr -d ' -')
|
|
156
|
+
[ -z "$ZIP_NAME" ] && ZIP_NAME="${EXT_ELEMENT}-${VERSION}.zip"
|
|
157
|
+
|
|
158
|
+
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
|
159
|
+
echo "stability=${STABILITY}" >> "$GITHUB_OUTPUT"
|
|
160
|
+
echo "suffix=${SUFFIX}" >> "$GITHUB_OUTPUT"
|
|
161
|
+
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
|
|
162
|
+
echo "zip_name=${ZIP_NAME}" >> "$GITHUB_OUTPUT"
|
|
163
|
+
echo "ext_element=${EXT_ELEMENT}" >> "$GITHUB_OUTPUT"
|
|
164
|
+
|
|
165
|
+
echo "=== Pre-Release: ${EXT_ELEMENT} ${VERSION}${SUFFIX} ==="
|
|
166
|
+
|
|
167
|
+
- name: Create release
|
|
168
|
+
id: release
|
|
169
|
+
run: |
|
|
170
|
+
TAG="${{ steps.meta.outputs.tag }}"
|
|
171
|
+
VERSION="${{ steps.meta.outputs.version }}"
|
|
172
|
+
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
|
173
|
+
php ${MOKO_CLI}/release_create.php \
|
|
174
|
+
--path . --version "$VERSION" --tag "$TAG" \
|
|
175
|
+
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \
|
|
176
|
+
--repo "${GITEA_REPO}" --branch "${{ github.ref_name }}" --prerelease
|
|
177
|
+
|
|
178
|
+
- name: Update release notes from CHANGELOG.md
|
|
179
|
+
run: |
|
|
180
|
+
TAG="${{ steps.meta.outputs.tag }}"
|
|
181
|
+
VERSION="${{ steps.meta.outputs.version }}"
|
|
182
|
+
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
|
183
|
+
|
|
184
|
+
# Extract [Unreleased] section from changelog (everything between [Unreleased] and next ## heading)
|
|
185
|
+
if [ -f "CHANGELOG.md" ]; then
|
|
186
|
+
NOTES=$(awk '/^## \[Unreleased\]/{found=1; next} /^## \[/{if(found) exit} found{print}' CHANGELOG.md)
|
|
187
|
+
[ -z "$NOTES" ] && NOTES="Release ${VERSION}"
|
|
188
|
+
else
|
|
189
|
+
NOTES="Release ${VERSION}"
|
|
190
|
+
fi
|
|
191
|
+
|
|
192
|
+
# Update release body via API
|
|
193
|
+
RELEASE_ID=$(curl -sf -H "Authorization: token ${{ secrets.MOKOGITEA_TOKEN }}" \
|
|
194
|
+
"${API_BASE}/releases/tags/${TAG}" | python3 -c "import json,sys; print(json.load(sys.stdin).get('id',''))" 2>/dev/null || true)
|
|
195
|
+
|
|
196
|
+
if [ -n "$RELEASE_ID" ]; then
|
|
197
|
+
python3 -c "
|
|
198
|
+
import json, urllib.request
|
|
199
|
+
body = open('/dev/stdin').read()
|
|
200
|
+
payload = json.dumps({'body': body}).encode()
|
|
201
|
+
req = urllib.request.Request(
|
|
202
|
+
'${API_BASE}/releases/${RELEASE_ID}',
|
|
203
|
+
data=payload, method='PATCH',
|
|
204
|
+
headers={
|
|
205
|
+
'Authorization': 'token ${{ secrets.MOKOGITEA_TOKEN }}',
|
|
206
|
+
'Content-Type': 'application/json'
|
|
207
|
+
})
|
|
208
|
+
urllib.request.urlopen(req)
|
|
209
|
+
" <<< "$NOTES"
|
|
210
|
+
echo "Release notes updated from CHANGELOG.md"
|
|
211
|
+
fi
|
|
212
|
+
|
|
213
|
+
- name: Build package and upload
|
|
214
|
+
id: package
|
|
215
|
+
run: |
|
|
216
|
+
VERSION="${{ steps.meta.outputs.version }}"
|
|
217
|
+
TAG="${{ steps.meta.outputs.tag }}"
|
|
218
|
+
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
|
219
|
+
php ${MOKO_CLI}/release_package.php \
|
|
220
|
+
--path . --version "$VERSION" --tag "$TAG" \
|
|
221
|
+
--token "${{ secrets.MOKOGITEA_TOKEN }}" --api-base "$API_BASE" \
|
|
222
|
+
--repo "${GITEA_REPO}" --output /tmp || true
|
|
223
|
+
|
|
224
|
+
# updates.xml is generated dynamically by MokoGitea license server
|
|
225
|
+
# No need to build, commit, or sync updates.xml from workflows
|
|
226
|
+
|
|
227
|
+
- name: "Delete lesser pre-release channels (cascade)"
|
|
228
|
+
continue-on-error: true
|
|
229
|
+
run: |
|
|
230
|
+
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
|
231
|
+
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
|
|
232
|
+
|
|
233
|
+
php ${MOKO_CLI}/release_cascade.php \
|
|
234
|
+
--stability "${{ steps.meta.outputs.stability }}" \
|
|
235
|
+
--token "${TOKEN}" \
|
|
236
|
+
--api-base "${API_BASE}"
|
|
237
|
+
|
|
238
|
+
- name: Summary
|
|
239
|
+
if: always()
|
|
240
|
+
run: |
|
|
241
|
+
VERSION="${{ steps.meta.outputs.version }}"
|
|
242
|
+
STABILITY="${{ steps.meta.outputs.stability }}"
|
|
243
|
+
ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
|
|
244
|
+
SHA256="${{ steps.package.outputs.sha256_zip }}"
|
|
245
|
+
echo "## Pre-Release Complete" >> $GITHUB_STEP_SUMMARY
|
|
246
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
247
|
+
echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
|
|
248
|
+
echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
|
|
249
|
+
echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
|
|
250
|
+
echo "| Channel | ${STABILITY} |" >> $GITHUB_STEP_SUMMARY
|
|
251
|
+
echo "| Package | \`${ZIP_NAME}\` |" >> $GITHUB_STEP_SUMMARY
|
|
252
|
+
echo "| SHA-256 | \`${SHA256:-n/a}\` |" >> $GITHUB_STEP_SUMMARY
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
#
|
|
8
8
|
# FILE INFORMATION
|
|
9
9
|
# DEFGROUP: Gitea.Workflow
|
|
10
|
-
# INGROUP:
|
|
11
|
-
# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/
|
|
10
|
+
# INGROUP: mokocli.Validation
|
|
11
|
+
# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli
|
|
12
12
|
# PATH: /templates/workflows/joomla/repo_health.yml.template
|
|
13
13
|
# VERSION: 09.23.00
|
|
14
14
|
# BRIEF: Enforces repository guardrails by validating scripts governance, tooling availability, and core repository health artifacts.
|
|
@@ -33,7 +33,8 @@ on:
|
|
|
33
33
|
- scripts
|
|
34
34
|
- repo
|
|
35
35
|
pull_request:
|
|
36
|
-
|
|
36
|
+
branches:
|
|
37
|
+
- main
|
|
37
38
|
|
|
38
39
|
permissions:
|
|
39
40
|
contents: read
|
package/dist/client.js
CHANGED
|
@@ -42,7 +42,26 @@ export class GiteaClient {
|
|
|
42
42
|
return this.request(this.buildUrl(endpoint), 'PUT', body);
|
|
43
43
|
}
|
|
44
44
|
async delete(endpoint, body) {
|
|
45
|
-
|
|
45
|
+
if (body === undefined) {
|
|
46
|
+
return this.request(this.buildUrl(endpoint), 'DELETE');
|
|
47
|
+
}
|
|
48
|
+
// Use fetch for DELETE+body — node:https drops the body on some
|
|
49
|
+
// proxy/TLS configurations, causing the server to see an empty request.
|
|
50
|
+
const url = this.buildUrl(endpoint);
|
|
51
|
+
const resp = await fetch(url, {
|
|
52
|
+
method: 'DELETE',
|
|
53
|
+
headers: { ...this.headers },
|
|
54
|
+
body: JSON.stringify(body),
|
|
55
|
+
});
|
|
56
|
+
const raw = await resp.text();
|
|
57
|
+
let data;
|
|
58
|
+
try {
|
|
59
|
+
data = JSON.parse(raw);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
data = raw;
|
|
63
|
+
}
|
|
64
|
+
return { status: resp.status, data };
|
|
46
65
|
}
|
|
47
66
|
buildUrl(endpoint, params) {
|
|
48
67
|
const path = endpoint.startsWith('/') ? endpoint : `/${endpoint}`;
|