77 workflow_dispatch :
88 inputs :
99 version :
10- description : ' Test version (e.g., 1.9.1-test )'
10+ description : ' Test version (e.g., 1.9.1-beta.1 )'
1111 required : true
1212 type : string
1313
@@ -62,25 +62,43 @@ jobs:
6262 GH_EVENT_NAME : ${{ github.event_name }}
6363 GH_INPUT_VERSION : ${{ github.event.inputs.version }}
6464 run : |
65+ set -euo pipefail
66+
6567 if [ "$GH_EVENT_NAME" = "workflow_dispatch" ]; then
6668 VERSION="$GH_INPUT_VERSION"
67- echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
68- echo "IS_TEST=true" >> $GITHUB_OUTPUT
69+ IS_TEST=true
70+ else
71+ VERSION=${GITHUB_REF#refs/tags/v}
72+ IS_TEST=false
73+ fi
74+
75+ # Validate version format before using it in later steps.
76+ if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+\.[0-9]+)?$ ]]; then
77+ echo "Invalid version format: $VERSION" >&2
78+ exit 1
79+ fi
80+
81+ {
82+ echo "VERSION<<EOF"
83+ echo "$VERSION"
84+ echo "EOF"
85+ } >> "$GITHUB_OUTPUT"
86+ echo "IS_TEST=$IS_TEST" >> "$GITHUB_OUTPUT"
87+
88+ if [ "$IS_TEST" = "true" ]; then
6989 echo "📝 Test version: $VERSION"
7090 # Update package.json version for test releases only
7191 npm version "$VERSION" --no-git-tag-version
7292 else
73- VERSION=${GITHUB_REF#refs/tags/v}
74- echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
75- echo "IS_TEST=false" >> $GITHUB_OUTPUT
7693 echo "🚀 Release version: $VERSION"
7794 # For tag-based releases, package.json was already updated by release script
7895 fi
7996
8097 - name : Resolve npm tag from version
8198 id : resolve_npm_tag
99+ env :
100+ VERSION : ${{ steps.get_version.outputs.VERSION }}
82101 run : |
83- VERSION="${{ steps.get_version.outputs.VERSION }}"
84102 if [[ "$VERSION" == *"-beta"* ]]; then
85103 NPM_TAG="beta"
86104 elif [[ "$VERSION" == *"-alpha"* ]]; then
@@ -95,30 +113,35 @@ jobs:
95113
96114 - name : Generate GitHub release notes (production releases only)
97115 if : github.event_name == 'push'
116+ env :
117+ VERSION : ${{ steps.get_version.outputs.VERSION }}
98118 run : |
99119 node scripts/generate-github-release-notes.mjs \
100- --version "${{ steps.get_version.outputs. VERSION }} " \
120+ --version "$VERSION" \
101121 --out github-release-body.md
102122
103123 - name : Create package
104124 run : npm pack
105125
106126 - name : Test publish (dry run for manual triggers)
107127 if : github.event_name == 'workflow_dispatch'
128+ env :
129+ NPM_TAG : ${{ steps.resolve_npm_tag.outputs.NPM_TAG }}
108130 run : |
109131 echo "🧪 Testing package creation (dry run)"
110- npm publish --dry-run --access public --tag "${{ steps.resolve_npm_tag.outputs. NPM_TAG }} "
132+ npm publish --dry-run --access public --tag "$NPM_TAG"
111133
112134 - name : Publish to NPM (production releases only)
113135 if : github.event_name == 'push'
136+ env :
137+ VERSION : ${{ steps.get_version.outputs.VERSION }}
138+ NPM_TAG : ${{ steps.resolve_npm_tag.outputs.NPM_TAG }}
114139 run : |
115- VERSION="${{ steps.get_version.outputs.VERSION }}"
116140 # Skip if this exact version is already published (idempotent reruns)
117141 if npm view xcodebuildmcp@"$VERSION" version >/dev/null 2>&1; then
118142 echo "✅ xcodebuildmcp@$VERSION already on NPM. Skipping publish."
119143 exit 0
120144 fi
121- NPM_TAG="${{ steps.resolve_npm_tag.outputs.NPM_TAG }}"
122145 echo "📦 Publishing to NPM with tag: $NPM_TAG"
123146 npm publish --access public --tag "$NPM_TAG"
124147
@@ -135,14 +158,17 @@ jobs:
135158 prerelease : false
136159
137160 - name : Summary
161+ env :
162+ IS_TEST : ${{ steps.get_version.outputs.IS_TEST }}
163+ VERSION : ${{ steps.get_version.outputs.VERSION }}
138164 run : |
139- if [ "${{ steps.get_version.outputs. IS_TEST }} " = "true" ]; then
140- echo "🧪 Test completed for version: ${{ steps.get_version.outputs. VERSION }} "
165+ if [ "$IS_TEST" = "true" ]; then
166+ echo "🧪 Test completed for version: $VERSION"
141167 echo "Ready for production release!"
142168 else
143169 echo "🎉 Production release completed!"
144- echo "Version: ${{ steps.get_version.outputs. VERSION }} "
145- echo "📦 NPM: https://www.npmjs.com/package/xcodebuildmcp/v/${{ steps.get_version.outputs. VERSION }} "
170+ echo "Version: $VERSION"
171+ echo "📦 NPM: https://www.npmjs.com/package/xcodebuildmcp/v/$VERSION"
146172 echo "📚 MCP Registry: publish attempted in separate job (mcp_registry)"
147173 fi
148174
@@ -152,18 +178,15 @@ jobs:
152178 runs-on : ubuntu-latest
153179 env :
154180 MCP_DNS_PRIVATE_KEY : ${{ secrets.MCP_DNS_PRIVATE_KEY }}
181+ VERSION : ${{ needs.release.outputs.version }}
155182 steps :
156183 - name : Checkout code
157184 uses : actions/checkout@v4
158185 with :
159186 fetch-depth : 0
160187
161- - name : Get version from tag
162- id : get_version_mcp
163- run : |
164- VERSION=${GITHUB_REF#refs/tags/v}
165- echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
166- echo "🚢 MCP publish for version: $VERSION"
188+ - name : Release version context
189+ run : echo "🚢 MCP publish for version: $VERSION"
167190
168191 - name : Missing secret — skip MCP publish
169192 if : env.MCP_DNS_PRIVATE_KEY == ''
@@ -238,12 +261,16 @@ jobs:
238261 run : npm ci --ignore-scripts
239262
240263 - name : Package portable artifact
264+ env :
265+ VERSION : ${{ needs.release.outputs.version }}
241266 run : |
242- npm run package:macos -- --arch "${{ matrix.arch }}" --version "${{ needs.release.outputs.version }} "
267+ npm run package:macos -- --arch "${{ matrix.arch }}" --version "$VERSION "
243268
244269 - name : Verify portable artifact
270+ env :
271+ VERSION : ${{ needs.release.outputs.version }}
245272 run : |
246- npm run verify:portable -- --archive "dist/portable/xcodebuildmcp-${{ needs.release.outputs.version } }-darwin-${{ matrix.arch }}.tar.gz"
273+ npm run verify:portable -- --archive "dist/portable/xcodebuildmcp-${VERSION }-darwin-${{ matrix.arch }}.tar.gz"
247274
248275 - name : Upload arch artifact
249276 uses : actions/upload-artifact@v4
@@ -283,8 +310,9 @@ jobs:
283310
284311 - name : Expand per-arch archives
285312 id : expand_archives
313+ env :
314+ VERSION : ${{ needs.release.outputs.version }}
286315 run : |
287- VERSION="${{ needs.release.outputs.version }}"
288316 ARM64_TGZ="dist/portable/arm64/xcodebuildmcp-${VERSION}-darwin-arm64.tar.gz"
289317 X64_TGZ="dist/portable/x64/xcodebuildmcp-${VERSION}-darwin-x64.tar.gz"
290318 ARM64_ROOT="dist/portable/unpacked/arm64/xcodebuildmcp-${VERSION}-darwin-arm64"
@@ -296,15 +324,19 @@ jobs:
296324 echo "X64_ROOT=$X64_ROOT" >> "$GITHUB_OUTPUT"
297325
298326 - name : Build universal portable artifact
327+ env :
328+ VERSION : ${{ needs.release.outputs.version }}
299329 run : |
300330 npm run package:macos:universal -- \
301- --version "${{ needs.release.outputs.version }} " \
331+ --version "$VERSION " \
302332 --arm64-root "${{ steps.expand_archives.outputs.ARM64_ROOT }}" \
303333 --x64-root "${{ steps.expand_archives.outputs.X64_ROOT }}"
304334
305335 - name : Verify universal portable artifact
336+ env :
337+ VERSION : ${{ needs.release.outputs.version }}
306338 run : |
307- npm run verify:portable -- --archive "dist/portable/xcodebuildmcp-${{ needs.release.outputs.version } }-darwin-universal.tar.gz"
339+ npm run verify:portable -- --archive "dist/portable/xcodebuildmcp-${VERSION }-darwin-universal.tar.gz"
308340
309341 - name : Upload universal artifact
310342 uses : actions/upload-artifact@v4
@@ -341,16 +373,18 @@ jobs:
341373 - name : Upload portable assets to GitHub Release
342374 env :
343375 GH_TOKEN : ${{ github.token }}
376+ VERSION : ${{ needs.release.outputs.version }}
377+ REPOSITORY : ${{ github.repository }}
344378 run : |
345- gh release upload "v${{ needs.release.outputs.version } }" \
346- dist/portable/arm64/xcodebuildmcp-${{ needs.release.outputs.version } }-darwin-arm64.tar.gz \
347- dist/portable/arm64/xcodebuildmcp-${{ needs.release.outputs.version } }-darwin-arm64.tar.gz.sha256 \
348- dist/portable/x64/xcodebuildmcp-${{ needs.release.outputs.version } }-darwin-x64.tar.gz \
349- dist/portable/x64/xcodebuildmcp-${{ needs.release.outputs.version } }-darwin-x64.tar.gz.sha256 \
350- dist/portable/universal/xcodebuildmcp-${{ needs.release.outputs.version } }-darwin-universal.tar.gz \
351- dist/portable/universal/xcodebuildmcp-${{ needs.release.outputs.version } }-darwin-universal.tar.gz.sha256 \
379+ gh release upload "v${VERSION }" \
380+ dist/portable/arm64/xcodebuildmcp-${VERSION }-darwin-arm64.tar.gz \
381+ dist/portable/arm64/xcodebuildmcp-${VERSION }-darwin-arm64.tar.gz.sha256 \
382+ dist/portable/x64/xcodebuildmcp-${VERSION }-darwin-x64.tar.gz \
383+ dist/portable/x64/xcodebuildmcp-${VERSION }-darwin-x64.tar.gz.sha256 \
384+ dist/portable/universal/xcodebuildmcp-${VERSION }-darwin-universal.tar.gz \
385+ dist/portable/universal/xcodebuildmcp-${VERSION }-darwin-universal.tar.gz.sha256 \
352386 --clobber \
353- --repo "${{ github.repository }} "
387+ --repo "$REPOSITORY "
354388
355389 update_homebrew_tap :
356390 if : github.event_name == 'push'
@@ -385,9 +419,11 @@ jobs:
385419
386420 - name : Generate formula
387421 if : env.HOMEBREW_TAP_DEPLOY_KEY != ''
422+ env :
423+ VERSION : ${{ needs.release.outputs.version }}
424+ REPOSITORY : ${{ github.repository }}
388425 run : |
389- VERSION="${{ needs.release.outputs.version }}"
390- FORMULA_BASE_URL="https://github.com/${{ github.repository }}/releases/download/v${VERSION}"
426+ FORMULA_BASE_URL="https://github.com/${REPOSITORY}/releases/download/v${VERSION}"
391427 ARM64_SHA="$(awk '{print $1}' dist/portable/arm64/xcodebuildmcp-${VERSION}-darwin-arm64.tar.gz.sha256)"
392428 X64_SHA="$(awk '{print $1}' dist/portable/x64/xcodebuildmcp-${VERSION}-darwin-x64.tar.gz.sha256)"
393429 npm run homebrew:formula -- \
@@ -405,9 +441,11 @@ jobs:
405441
406442 - name : Update tap repository
407443 if : env.HOMEBREW_TAP_DEPLOY_KEY != ''
444+ env :
445+ VERSION : ${{ needs.release.outputs.version }}
446+ REPOSITORY_OWNER : ${{ github.repository_owner }}
408447 run : |
409- VERSION="${{ needs.release.outputs.version }}"
410- git clone git@github.com:${{ github.repository_owner }}/homebrew-xcodebuildmcp.git tap-repo
448+ git clone git@github.com:${REPOSITORY_OWNER}/homebrew-xcodebuildmcp.git tap-repo
411449 mkdir -p tap-repo/Formula
412450 cp dist/homebrew/Formula/xcodebuildmcp.rb tap-repo/Formula/xcodebuildmcp.rb
413451 cd tap-repo
0 commit comments