@mokoconsulting/mcp-mokogitea-api 1.3.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 +72 -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/README.md +4 -1
- package/dist/client.js +20 -1
- package/dist/index.js +47 -2
- package/package.json +2 -2
- package/src/client.ts +15 -1
- package/src/index.ts +63 -2
- package/tsconfig.json +1 -1
|
@@ -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
|
|
@@ -28,24 +36,78 @@ jobs:
|
|
|
28
36
|
- name: Build
|
|
29
37
|
run: npm run build
|
|
30
38
|
|
|
31
|
-
- name:
|
|
32
|
-
id: version
|
|
39
|
+
- name: Auto-bump patch version
|
|
33
40
|
run: |
|
|
41
|
+
API_BASE="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
|
|
42
|
+
TOKEN="${{ secrets.MOKOGITEA_TOKEN }}"
|
|
43
|
+
|
|
34
44
|
PKG_NAME=$(node -p "require('./package.json').name")
|
|
35
|
-
|
|
36
|
-
PUBLISHED=$(npm view "${PKG_NAME}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
echo "Version ${
|
|
45
|
+
CURRENT=$(node -p "require('./package.json').version")
|
|
46
|
+
PUBLISHED=$(npm view "${PKG_NAME}@latest" version 2>/dev/null || echo "0.0.0")
|
|
47
|
+
|
|
48
|
+
if [ "$CURRENT" != "$PUBLISHED" ]; then
|
|
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)"
|
|
40
104
|
else
|
|
41
|
-
echo "
|
|
42
|
-
echo "Publishing ${PKG_NAME}@${PKG_VERSION}"
|
|
105
|
+
echo "::warning::Could not create PR for version bump — publishing with current version"
|
|
43
106
|
fi
|
|
44
107
|
env:
|
|
45
108
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
46
109
|
|
|
47
110
|
- name: Publish
|
|
48
|
-
if: steps.version.outputs.skip != 'true'
|
|
49
111
|
run: npm publish --access public
|
|
50
112
|
env:
|
|
51
113
|
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/README.md
CHANGED
|
@@ -250,12 +250,15 @@ If `connection` is omitted, the `defaultConnection` is used.
|
|
|
250
250
|
| `gitea_webhooks_list` | List webhooks for a repository |
|
|
251
251
|
| `gitea_webhook_create` | Create a webhook |
|
|
252
252
|
|
|
253
|
-
### Wiki (
|
|
253
|
+
### Wiki (5 tools)
|
|
254
254
|
|
|
255
255
|
| Tool | Description |
|
|
256
256
|
|------|-------------|
|
|
257
257
|
| `gitea_wiki_pages_list` | List wiki pages |
|
|
258
258
|
| `gitea_wiki_page_get` | Get a wiki page |
|
|
259
|
+
| `gitea_wiki_page_create` | Create a new wiki page |
|
|
260
|
+
| `gitea_wiki_page_edit` | Edit an existing wiki page |
|
|
261
|
+
| `gitea_wiki_page_delete` | Delete a wiki page |
|
|
259
262
|
|
|
260
263
|
### Notifications (2 tools)
|
|
261
264
|
|
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}`;
|
package/dist/index.js
CHANGED
|
@@ -690,6 +690,43 @@ server.tool('gitea_webhook_create', 'Create a webhook', {
|
|
|
690
690
|
// ── Wiki ────────────────────────────────────────────────────────────────
|
|
691
691
|
server.tool('gitea_wiki_pages_list', 'List wiki pages', { ...OwnerRepo, ...PaginationParams, ...ConnectionParam }, async ({ owner, repo, page, limit, connection }) => formatResponse(await clientFor(connection).get(`/repos/${owner}/${repo}/wiki/pages`, pageQuery({ page, limit }))));
|
|
692
692
|
server.tool('gitea_wiki_page_get', 'Get a wiki page', { ...OwnerRepo, page_name: z.string().describe('Page name/slug'), ...ConnectionParam }, async ({ owner, repo, page_name, connection }) => formatResponse(await clientFor(connection).get(`/repos/${owner}/${repo}/wiki/page/${page_name}`)));
|
|
693
|
+
server.tool('gitea_wiki_page_create', 'Create a new wiki page', {
|
|
694
|
+
...OwnerRepo,
|
|
695
|
+
title: z.string().describe('Page title'),
|
|
696
|
+
content: z.string().describe('Page content (markdown)'),
|
|
697
|
+
message: z.string().optional().describe('Commit message for the wiki change'),
|
|
698
|
+
...ConnectionParam,
|
|
699
|
+
}, async ({ owner, repo, title, content, message, connection }) => {
|
|
700
|
+
const body = {
|
|
701
|
+
title,
|
|
702
|
+
content_base64: Buffer.from(content).toString('base64'),
|
|
703
|
+
};
|
|
704
|
+
if (message !== undefined)
|
|
705
|
+
body.message = message;
|
|
706
|
+
return formatResponse(await clientFor(connection).post(`/repos/${owner}/${repo}/wiki/pages`, body));
|
|
707
|
+
});
|
|
708
|
+
server.tool('gitea_wiki_page_edit', 'Edit an existing wiki page', {
|
|
709
|
+
...OwnerRepo,
|
|
710
|
+
page_name: z.string().describe('Current page name/slug'),
|
|
711
|
+
content: z.string().describe('New page content (markdown)'),
|
|
712
|
+
title: z.string().optional().describe('New page title (to rename)'),
|
|
713
|
+
message: z.string().optional().describe('Commit message for the wiki change'),
|
|
714
|
+
...ConnectionParam,
|
|
715
|
+
}, async ({ owner, repo, page_name, content, title, message, connection }) => {
|
|
716
|
+
const body = {
|
|
717
|
+
content_base64: Buffer.from(content).toString('base64'),
|
|
718
|
+
};
|
|
719
|
+
if (title !== undefined)
|
|
720
|
+
body.title = title;
|
|
721
|
+
if (message !== undefined)
|
|
722
|
+
body.message = message;
|
|
723
|
+
return formatResponse(await clientFor(connection).patch(`/repos/${owner}/${repo}/wiki/page/${page_name}`, body));
|
|
724
|
+
});
|
|
725
|
+
server.tool('gitea_wiki_page_delete', 'Delete a wiki page', {
|
|
726
|
+
...OwnerRepo,
|
|
727
|
+
page_name: z.string().describe('Page name/slug to delete'),
|
|
728
|
+
...ConnectionParam,
|
|
729
|
+
}, async ({ owner, repo, page_name, connection }) => formatResponse(await clientFor(connection).delete(`/repos/${owner}/${repo}/wiki/page/${page_name}`)));
|
|
693
730
|
// ── Notifications ───────────────────────────────────────────────────────
|
|
694
731
|
server.tool('gitea_notifications_list', 'List notifications for the authenticated user', {
|
|
695
732
|
status_types: z.string().optional().describe('Comma-separated: read, unread, pinned'),
|
|
@@ -1077,14 +1114,22 @@ server.tool('gitea_metadata_update', 'Update repo metadata settings (merges with
|
|
|
1077
1114
|
repo: z.string().describe('Repository name'),
|
|
1078
1115
|
name: z.string().optional().describe('Project name'),
|
|
1079
1116
|
org: z.string().optional().describe('Organization'),
|
|
1117
|
+
description: z.string().optional().describe('Project description'),
|
|
1080
1118
|
version: z.string().optional().describe('Version string (e.g. 06.00.00)'),
|
|
1081
1119
|
version_prefix: z.string().optional().describe('Tag prefix for version display (e.g. v1.26.1-moko.)'),
|
|
1082
1120
|
license_spdx: z.string().optional().describe('SPDX license identifier'),
|
|
1121
|
+
license_name: z.string().optional().describe('Human-readable license name (e.g. GNU General Public License v3)'),
|
|
1122
|
+
element_name: z.string().optional().describe('Extension element name (e.g. pkg_mokosuitecrm, mod_mokojoomhero)'),
|
|
1083
1123
|
platform: z.string().optional().describe('Platform (joomla, wordpress, dolibarr, go, mcp, platform, generic)'),
|
|
1124
|
+
standards_version: z.string().optional().describe('mokoplatform standards version (e.g. 05.01.00)'),
|
|
1125
|
+
standards_source: z.string().optional().describe('URL to standards repo'),
|
|
1126
|
+
maintainer: z.string().optional().describe('Maintainer name (e.g. Moko Consulting)'),
|
|
1127
|
+
maintainer_url: z.string().optional().describe('Maintainer website URL'),
|
|
1084
1128
|
info_url: z.string().optional().describe('Extension info/product page URL'),
|
|
1085
|
-
target_version: z.string().optional().describe('Target platform version regex (e.g.
|
|
1129
|
+
target_version: z.string().optional().describe('Target platform version regex (e.g. 6..*)'),
|
|
1086
1130
|
php_minimum: z.string().optional().describe('Minimum PHP version (e.g. 8.1)'),
|
|
1087
|
-
|
|
1131
|
+
language: z.string().optional().describe('Primary language (e.g. PHP, Go, TypeScript)'),
|
|
1132
|
+
extension_type: z.string().optional().describe('Extension type (component, module, plugin, package, template, library, file)'),
|
|
1088
1133
|
entry_point: z.string().optional().describe('Build entry point path'),
|
|
1089
1134
|
...ConnectionParam,
|
|
1090
1135
|
}, async ({ owner, repo, connection, ...fields }) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mokoconsulting/mcp-mokogitea-api",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "MCP server for Gitea REST API v1 operations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -29,6 +29,6 @@
|
|
|
29
29
|
"author": "Moko Consulting <hello@mokoconsulting.tech>",
|
|
30
30
|
"repository": {
|
|
31
31
|
"type": "git",
|
|
32
|
-
"url": "https://git.mokoconsulting.tech/MokoConsulting/
|
|
32
|
+
"url": "https://git.mokoconsulting.tech/MokoConsulting/mcp-mokogitea-api.git"
|
|
33
33
|
}
|
|
34
34
|
}
|
package/src/client.ts
CHANGED
|
@@ -52,7 +52,21 @@ export class GiteaClient {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
async delete(endpoint: string, body?: unknown): Promise<ApiResponse> {
|
|
55
|
-
|
|
55
|
+
if (body === undefined) {
|
|
56
|
+
return this.request(this.buildUrl(endpoint), 'DELETE');
|
|
57
|
+
}
|
|
58
|
+
// Use fetch for DELETE+body — node:https drops the body on some
|
|
59
|
+
// proxy/TLS configurations, causing the server to see an empty request.
|
|
60
|
+
const url = this.buildUrl(endpoint);
|
|
61
|
+
const resp = await fetch(url, {
|
|
62
|
+
method: 'DELETE',
|
|
63
|
+
headers: { ...this.headers },
|
|
64
|
+
body: JSON.stringify(body),
|
|
65
|
+
});
|
|
66
|
+
const raw = await resp.text();
|
|
67
|
+
let data: unknown;
|
|
68
|
+
try { data = JSON.parse(raw); } catch { data = raw; }
|
|
69
|
+
return { status: resp.status, data };
|
|
56
70
|
}
|
|
57
71
|
|
|
58
72
|
private buildUrl(endpoint: string, params?: Record<string, string>): string {
|
package/src/index.ts
CHANGED
|
@@ -1059,6 +1059,59 @@ server.tool(
|
|
|
1059
1059
|
async ({ owner, repo, page_name, connection }) => formatResponse(await clientFor(connection).get(`/repos/${owner}/${repo}/wiki/page/${page_name}`)),
|
|
1060
1060
|
);
|
|
1061
1061
|
|
|
1062
|
+
server.tool(
|
|
1063
|
+
'gitea_wiki_page_create',
|
|
1064
|
+
'Create a new wiki page',
|
|
1065
|
+
{
|
|
1066
|
+
...OwnerRepo,
|
|
1067
|
+
title: z.string().describe('Page title'),
|
|
1068
|
+
content: z.string().describe('Page content (markdown)'),
|
|
1069
|
+
message: z.string().optional().describe('Commit message for the wiki change'),
|
|
1070
|
+
...ConnectionParam,
|
|
1071
|
+
},
|
|
1072
|
+
async ({ owner, repo, title, content, message, connection }) => {
|
|
1073
|
+
const body: Record<string, unknown> = {
|
|
1074
|
+
title,
|
|
1075
|
+
content_base64: Buffer.from(content).toString('base64'),
|
|
1076
|
+
};
|
|
1077
|
+
if (message !== undefined) body.message = message;
|
|
1078
|
+
return formatResponse(await clientFor(connection).post(`/repos/${owner}/${repo}/wiki/pages`, body));
|
|
1079
|
+
},
|
|
1080
|
+
);
|
|
1081
|
+
|
|
1082
|
+
server.tool(
|
|
1083
|
+
'gitea_wiki_page_edit',
|
|
1084
|
+
'Edit an existing wiki page',
|
|
1085
|
+
{
|
|
1086
|
+
...OwnerRepo,
|
|
1087
|
+
page_name: z.string().describe('Current page name/slug'),
|
|
1088
|
+
content: z.string().describe('New page content (markdown)'),
|
|
1089
|
+
title: z.string().optional().describe('New page title (to rename)'),
|
|
1090
|
+
message: z.string().optional().describe('Commit message for the wiki change'),
|
|
1091
|
+
...ConnectionParam,
|
|
1092
|
+
},
|
|
1093
|
+
async ({ owner, repo, page_name, content, title, message, connection }) => {
|
|
1094
|
+
const body: Record<string, unknown> = {
|
|
1095
|
+
content_base64: Buffer.from(content).toString('base64'),
|
|
1096
|
+
};
|
|
1097
|
+
if (title !== undefined) body.title = title;
|
|
1098
|
+
if (message !== undefined) body.message = message;
|
|
1099
|
+
return formatResponse(await clientFor(connection).patch(`/repos/${owner}/${repo}/wiki/page/${page_name}`, body));
|
|
1100
|
+
},
|
|
1101
|
+
);
|
|
1102
|
+
|
|
1103
|
+
server.tool(
|
|
1104
|
+
'gitea_wiki_page_delete',
|
|
1105
|
+
'Delete a wiki page',
|
|
1106
|
+
{
|
|
1107
|
+
...OwnerRepo,
|
|
1108
|
+
page_name: z.string().describe('Page name/slug to delete'),
|
|
1109
|
+
...ConnectionParam,
|
|
1110
|
+
},
|
|
1111
|
+
async ({ owner, repo, page_name, connection }) =>
|
|
1112
|
+
formatResponse(await clientFor(connection).delete(`/repos/${owner}/${repo}/wiki/page/${page_name}`)),
|
|
1113
|
+
);
|
|
1114
|
+
|
|
1062
1115
|
// ── Notifications ───────────────────────────────────────────────────────
|
|
1063
1116
|
|
|
1064
1117
|
server.tool(
|
|
@@ -1667,14 +1720,22 @@ server.tool(
|
|
|
1667
1720
|
repo: z.string().describe('Repository name'),
|
|
1668
1721
|
name: z.string().optional().describe('Project name'),
|
|
1669
1722
|
org: z.string().optional().describe('Organization'),
|
|
1723
|
+
description: z.string().optional().describe('Project description'),
|
|
1670
1724
|
version: z.string().optional().describe('Version string (e.g. 06.00.00)'),
|
|
1671
1725
|
version_prefix: z.string().optional().describe('Tag prefix for version display (e.g. v1.26.1-moko.)'),
|
|
1672
1726
|
license_spdx: z.string().optional().describe('SPDX license identifier'),
|
|
1727
|
+
license_name: z.string().optional().describe('Human-readable license name (e.g. GNU General Public License v3)'),
|
|
1728
|
+
element_name: z.string().optional().describe('Extension element name (e.g. pkg_mokosuitecrm, mod_mokojoomhero)'),
|
|
1673
1729
|
platform: z.string().optional().describe('Platform (joomla, wordpress, dolibarr, go, mcp, platform, generic)'),
|
|
1730
|
+
standards_version: z.string().optional().describe('mokoplatform standards version (e.g. 05.01.00)'),
|
|
1731
|
+
standards_source: z.string().optional().describe('URL to standards repo'),
|
|
1732
|
+
maintainer: z.string().optional().describe('Maintainer name (e.g. Moko Consulting)'),
|
|
1733
|
+
maintainer_url: z.string().optional().describe('Maintainer website URL'),
|
|
1674
1734
|
info_url: z.string().optional().describe('Extension info/product page URL'),
|
|
1675
|
-
target_version: z.string().optional().describe('Target platform version regex (e.g.
|
|
1735
|
+
target_version: z.string().optional().describe('Target platform version regex (e.g. 6..*)'),
|
|
1676
1736
|
php_minimum: z.string().optional().describe('Minimum PHP version (e.g. 8.1)'),
|
|
1677
|
-
|
|
1737
|
+
language: z.string().optional().describe('Primary language (e.g. PHP, Go, TypeScript)'),
|
|
1738
|
+
extension_type: z.string().optional().describe('Extension type (component, module, plugin, package, template, library, file)'),
|
|
1678
1739
|
entry_point: z.string().optional().describe('Build entry point path'),
|
|
1679
1740
|
...ConnectionParam,
|
|
1680
1741
|
},
|
package/tsconfig.json
CHANGED