-
-
Notifications
You must be signed in to change notification settings - Fork 11
349 lines (313 loc) Β· 13.3 KB
/
release.yml
File metadata and controls
349 lines (313 loc) Β· 13.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
name: π Release & Publish
# NOTE: This workflow requires a RELEASE_TOKEN secret to bypass branch protection rules
# The token needs the following permissions:
# - repo (full control)
# - workflow
# Without RELEASE_TOKEN, the workflow will fall back to GITHUB_TOKEN.
# NPM publishing uses OIDC Trusted Publishing (no NPM_TOKEN needed).
on:
push:
branches: [main]
workflow_dispatch:
# NOTE: release trigger removed β semantic-release on push handles NPM, Docker, and DXT.
# The release: [published] event caused duplicate runs (E403 on NPM, redundant Docker/DXT)
# because semantic-release creates the GitHub release, which re-triggered this workflow.
env:
NODE_VERSION: "22"
HUSKY: 0
CI: true
jobs:
# π·οΈ Semantic Release
semantic-release:
name: π·οΈ Semantic Release
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
permissions:
contents: write
issues: write
pull-requests: write
id-token: write # Required for NPM Trusted Publishing (OIDC)
outputs:
new-release-published: ${{ steps.semantic.outputs.new_release_published }}
new-release-version: ${{ steps.semantic.outputs.new_release_version }}
steps:
- name: π₯ Checkout Code
uses: actions/checkout@v6
with:
fetch-depth: 0
# Use RELEASE_TOKEN if available for bypassing branch protection rules
# Falls back to GITHUB_TOKEN if RELEASE_TOKEN is not set
token: ${{ secrets.RELEASE_TOKEN || secrets.GITHUB_TOKEN }}
- name: π¦ Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
- name: π¦ Install Dependencies
run: npm ci
env:
HUSKY: 0
- name: ποΈ Build Project
run: npm run build
env:
HUSKY: 0
- name: π§ͺ Run Essential Tests
run: |
# Run core tests that must pass for release
npm run test:ci || npm run test:typescript
env:
WORDPRESS_SITE_URL: https://example.com
WORDPRESS_USERNAME: test_user
WORDPRESS_APP_PASSWORD: test_password
CI: true
HUSKY: 0
- name: π·οΈ Semantic Release
id: semantic
uses: cycjimmy/semantic-release-action@v6
with:
extra_plugins: |
@semantic-release/changelog@6.0.3
@semantic-release/git@10.0.1
env:
# Use RELEASE_TOKEN if available for bypassing branch protection rules
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN || secrets.GITHUB_TOKEN }}
HUSKY: 0
NODE_OPTIONS: "--max-old-space-size=4096"
# NOTE: Fallback NPM Publish job removed β semantic-release handles NPM publishing
# via its @semantic-release/npm plugin. The fallback was only useful for manual GitHub
# releases, but those no longer trigger this workflow (release event removed above).
# π³ Docker Publish
docker-publish:
name: π³ Publish to Docker Hub
runs-on: ubuntu-latest
needs: semantic-release
if: needs.semantic-release.outputs.new-release-published == 'true'
permissions:
contents: read
packages: write
steps:
- name: π₯ Checkout Code
uses: actions/checkout@v6
- name: π³ Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: π Log in to Docker Hub
uses: docker/login-action@v4
with:
registry: docker.io
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: π Verify Docker Login
run: |
echo "Verifying Docker Hub login..."
docker info
echo "Docker Hub login successful"
- name: π Debug Release Info
run: |
echo "Release info debug:"
echo "New release published: ${{ needs.semantic-release.outputs.new-release-published }}"
echo "New release version: ${{ needs.semantic-release.outputs.new-release-version }}"
echo "GitHub ref: ${{ github.ref }}"
echo "GitHub ref name: ${{ github.ref_name }}"
echo "Event name: ${{ github.event_name }}"
echo "Is tag: ${{ startsWith(github.ref, 'refs/tags/') }}"
echo "Current working directory:"
pwd
echo "Git status:"
git status || true
echo "Git tags:"
git tag --sort=-version:refname | head -5 || true
- name: π Extract Metadata
id: meta
uses: docker/metadata-action@v5
with:
images: docker.io/docdyhr/mcp-wordpress
tags: |
type=ref,event=branch
type=raw,value=${{ needs.semantic-release.outputs.new-release-version }},enable=${{ needs.semantic-release.outputs.new-release-published == 'true' }}
type=raw,value=latest,enable={{is_default_branch}}
labels: |
org.opencontainers.image.title=MCP WordPress Server
org.opencontainers.image.description=Complete WordPress MCP Server with 59 management tools, intelligent caching, and real-time monitoring
org.opencontainers.image.version=${{ needs.semantic-release.outputs.new-release-version || github.ref_name }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.created={{date 'YYYY-MM-DDTHH:mm:ssZ'}}
org.opencontainers.image.source=https://github.com/docdyhr/mcp-wordpress
org.opencontainers.image.url=https://github.com/docdyhr/mcp-wordpress
org.opencontainers.image.documentation=https://github.com/docdyhr/mcp-wordpress#readme
org.opencontainers.image.licenses=MIT
- name: π Debug Extracted Tags
env:
META_TAGS: ${{ steps.meta.outputs.tags }}
META_LABELS: ${{ steps.meta.outputs.labels }}
META_JSON: ${{ steps.meta.outputs.json }}
run: |
echo "Extracted tags:"
echo "${META_TAGS}"
echo ""
echo "Extracted labels:"
echo "${META_LABELS}"
echo ""
echo "Metadata JSON:"
echo "${META_JSON}" | jq . 2>/dev/null || echo "${META_JSON}"
- name: ποΈ Build and Push Docker Image
id: docker-build
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
VERSION=${{ needs.semantic-release.outputs.new-release-version || github.ref_name }}
BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
VCS_REF=${{ github.sha }}
# v6 features
provenance: true
sbom: true
- name: π Retry Docker Build on Failure
if: failure() && steps.docker-build.outcome == 'failure'
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
VERSION=${{ needs.semantic-release.outputs.new-release-version || github.ref_name }}
BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
VCS_REF=${{ github.sha }}
provenance: true
sbom: true
- name: π Update Docker Hub Description
uses: peter-evans/dockerhub-description@v5
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
repository: docdyhr/mcp-wordpress
readme-filepath: ./README.md
- name: π― Verify Docker Push Success
id: verify-docker
env:
META_TAGS: ${{ steps.meta.outputs.tags }}
RELEASE_VERSION: ${{ needs.semantic-release.outputs.new-release-version || github.ref_name }}
run: |
echo "Docker build and push completed successfully"
echo "Published tags:"
echo "${META_TAGS}"
echo ""
echo "Version: ${RELEASE_VERSION}"
# Wait for Docker Hub propagation
echo "Waiting for Docker Hub propagation..."
sleep 30
# Verify the image was pushed successfully
VERSION="${RELEASE_VERSION}"
echo "Verifying Docker Hub publishing for version: $VERSION"
# Try to pull the image to verify it exists
if docker pull docdyhr/mcp-wordpress:$VERSION; then
echo "β
Successfully verified Docker image on Docker Hub"
echo "verification_status=success" >> $GITHUB_OUTPUT
else
echo "β Failed to verify Docker image on Docker Hub"
echo "verification_status=failure" >> $GITHUB_OUTPUT
exit 1
fi
- name: π¨ Docker Verification Failed - Create Alert
if: failure() && steps.verify-docker.outputs.verification_status == 'failure'
run: |
echo "::error title=Docker Publishing Verification Failed::Failed to verify Docker image publication"
echo "Manual intervention may be required to publish the Docker image"
# π¦ DXT Package Build and Upload
dxt-package:
name: π¦ Build and Upload DXT Package
runs-on: ubuntu-latest
needs: [semantic-release]
if: needs.semantic-release.result == 'success' && needs.semantic-release.outputs.new-release-published == 'true'
permissions:
contents: write
steps:
- name: π₯ Checkout Release Tag
uses: actions/checkout@v6
with:
# Checkout the release tag so package.json has the bumped version
ref: v${{ needs.semantic-release.outputs.new-release-version }}
fetch-depth: 0
- name: π¦ Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
- name: π¦ Install Dependencies
run: npm ci
env:
HUSKY: 0
- name: π¦ Install DXT CLI
run: npm install -g @anthropic-ai/dxt
env:
HUSKY: 0
- name: π Build DXT Package
run: npm run dxt:package:official
env:
HUSKY: 0
- name: π Verify DXT Package
run: |
ls -la mcp-wordpress.dxt
echo "DXT package size: $(du -h mcp-wordpress.dxt | cut -f1)"
file mcp-wordpress.dxt
# Verify version matches the release
node -e "const m = require('./package.json'); if (m.version !== '${{ needs.semantic-release.outputs.new-release-version }}') { console.error('Version mismatch:', m.version, 'vs', '${{ needs.semantic-release.outputs.new-release-version }}'); process.exit(1); } else { console.log('Version verified:', m.version); }"
- name: π€ Upload DXT Package to Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ needs.semantic-release.outputs.new-release-version }}
files: mcp-wordpress.dxt
token: ${{ secrets.GITHUB_TOKEN }}
- name: β
DXT Package Upload Success
run: |
echo "β
DXT package uploaded successfully!"
echo "π¦ Package: mcp-wordpress.dxt"
echo "π·οΈ Version: ${{ needs.semantic-release.outputs.new-release-version }}"
echo "π Download URL: https://github.com/docdyhr/mcp-wordpress/releases/download/v${{ needs.semantic-release.outputs.new-release-version }}/mcp-wordpress.dxt"
# π Post-Release Actions
post-release:
name: π Post-Release Actions
runs-on: ubuntu-latest
needs: [semantic-release, docker-publish, dxt-package]
if: always() && needs.semantic-release.outputs.new-release-published == 'true'
steps:
- name: π Release Summary
run: |
echo "π Release Pipeline Summary"
echo "=========================="
echo "π·οΈ Version: ${{ needs.semantic-release.outputs.new-release-version }}"
echo "π¦ NPM: Published (via semantic-release)"
echo "π³ Docker Status: ${{ needs.docker-publish.result }}"
echo "π¦ DXT Package Status: ${{ needs.dxt-package.result }}"
echo "π Semantic Release: ${{ needs.semantic-release.result }}"
echo "=========================="
- name: β
Success Notification
if:
needs.semantic-release.result == 'success' && needs.docker-publish.result == 'success' &&
needs.dxt-package.result == 'success'
run: |
echo "π Release completed successfully!"
echo "β
All components published successfully"
echo "π¦ NPM: Published"
echo "π³ Docker: Published"
echo "π¦ DXT Package: Uploaded"
- name: π¨ Failure Notification
if:
needs.semantic-release.result == 'failure' || needs.docker-publish.result == 'failure' ||
needs.dxt-package.result == 'failure'
run: |
echo "β Release had failures!"
echo "Please check the workflow logs and fix any issues."
echo "Semantic Release: ${{ needs.semantic-release.result }}"
echo "Docker Publish: ${{ needs.docker-publish.result }}"
echo "DXT Package: ${{ needs.dxt-package.result }}"
exit 1