@mokoconsulting/mcp-mokogitea-api 1.4.0 → 1.4.2

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.
@@ -4,8 +4,8 @@
4
4
  #
5
5
  # FILE INFORMATION
6
6
  # DEFGROUP: Gitea.Workflow
7
- # INGROUP: moko-platform.Release
8
- # REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
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 moko-platform tools
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/moko-platform/cli" ]; then
52
- echo "MOKO_CLI=/opt/moko-platform/cli" >> "$GITHUB_ENV"
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/moko-platform.git" \
56
- /tmp/moko-platform-api
57
- cd /tmp/moko-platform-api && composer install --no-dev --no-interaction --quiet
58
- echo "MOKO_CLI=/tmp/moko-platform-api/cli" >> "$GITHUB_ENV"
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: moko-platform.Release
8
- # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/moko-platform
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 moko-platform tools
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/moko-platform/cli/version_bump.php ] && [ -f /opt/moko-platform/vendor/autoload.php ]; then
75
- echo Using pre-installed /opt/moko-platform
76
- echo MOKO_CLI=/opt/moko-platform/cli >> $GITHUB_ENV
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/moko-platform-api
83
- CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git
84
- git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/moko-platform-api
85
- cd /tmp/moko-platform-api
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/moko-platform-api/cli >> $GITHUB_ENV
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 moko-platform tools
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/moko-platform/cli/version_bump.php ] && [ -f /opt/moko-platform/vendor/autoload.php ]; then
159
- echo Using pre-installed /opt/moko-platform
160
- echo MOKO_CLI=/opt/moko-platform/cli >> $GITHUB_ENV
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/moko-platform-api
167
- CLONE_URL=https://x-access-token:${MOKO_CLONE_TOKEN}@${MOKO_CLONE_HOST}/moko-platform.git
168
- git clone --depth 1 --branch main --quiet $CLONE_URL /tmp/moko-platform-api
169
- cd /tmp/moko-platform-api
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/moko-platform-api/cli >> $GITHUB_ENV
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 from CHANGELOG.md
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 ${{ secrets.MOKOGITEA_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/moko-platform
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
@@ -13,19 +13,6 @@
13
13
  name: "Generic: Project CI"
14
14
 
15
15
  on:
16
- push:
17
- branches:
18
- - main
19
- - dev
20
- - dev/**
21
- - rc/**
22
- - version/**
23
- pull_request:
24
- branches:
25
- - main
26
- - dev
27
- - dev/**
28
- - rc/**
29
16
  workflow_dispatch:
30
17
 
31
18
  permissions:
@@ -25,10 +25,6 @@
25
25
  name: "Universal: Secret Scanning"
26
26
 
27
27
  on:
28
- pull_request:
29
- branches:
30
- - main
31
- - 'dev/**'
32
28
  schedule:
33
29
  - cron: '0 5 * * 1' # Weekly Monday 05:00 UTC
34
30
  workflow_dispatch:
@@ -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
- if [ "$CURRENT" = "$PUBLISHED" ]; then
37
- npm version patch --no-git-tag-version
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 }}
@@ -96,6 +96,32 @@ jobs:
96
96
  echo "Branch policy: OK (${HEAD} → ${BASE})"
97
97
  echo "## Branch Policy: Passed" >> $GITHUB_STEP_SUMMARY
98
98
 
99
+ # ── Secret Scanning ──────────────────────────────────────────────────
100
+ gitleaks:
101
+ name: Secret Scan
102
+ runs-on: ubuntu-latest
103
+ steps:
104
+ - name: Checkout
105
+ uses: actions/checkout@v4
106
+ with:
107
+ fetch-depth: 0
108
+
109
+ - name: Install Gitleaks
110
+ run: |
111
+ GITLEAKS_VERSION="8.21.2"
112
+ curl -sSL "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \
113
+ | tar -xz -C /usr/local/bin gitleaks
114
+
115
+ - name: Scan PR commits for secrets
116
+ run: |
117
+ if gitleaks detect --source . --verbose \
118
+ --log-opts=${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} 2>&1; then
119
+ echo "**No secrets detected.**" >> $GITHUB_STEP_SUMMARY
120
+ else
121
+ echo "::error::Potential secrets detected in PR commits"
122
+ exit 1
123
+ fi
124
+
99
125
  # ── Code Validation ────────────────────────────────────────────────────
100
126
  validate:
101
127
  name: Validate PR
@@ -4,8 +4,249 @@
4
4
  #
5
5
  # FILE INFORMATION
6
6
  # DEFGROUP: Gitea.Workflow
7
- # INGROUP: moko-platform.Release
8
- # REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
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