4848 - os : macos-latest
4949 arch : arm64
5050 platform : darwin
51+ - os : windows-latest
52+ arch : x86_64
53+ platform : windows
5154
5255 steps :
5356 - uses : actions/checkout@v4
@@ -70,17 +73,26 @@ jobs:
7073 # Wait for installation to complete
7174 until xcode-select -p >/dev/null 2>&1; do sleep 5; done
7275
73- - name : Install uv
76+ - name : Install uv (Unix)
77+ if : matrix.platform != 'windows'
7478 run : |
7579 curl -LsSf https://astral.sh/uv/install.sh | sh
7680 echo "$HOME/.cargo/bin" >> $GITHUB_PATH
81+
82+ - name : Install uv (Windows)
83+ if : matrix.platform == 'windows'
84+ shell : pwsh
85+ run : |
86+ irm https://astral.sh/uv/install.ps1 | iex
87+ echo "$env:USERPROFILE\.local\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
7788
7889 - name : Cache uv environments
7990 uses : actions/cache@v3
8091 with :
8192 path : |
8293 ~/.cache/uv
8394 ~/.local/share/uv
95+ ~\AppData\Local\uv\cache
8496 key : ${{ runner.os }}-uv-${{ hashFiles('**/pyproject.toml') }}
8597 restore-keys : |
8698 ${{ runner.os }}-uv-
@@ -120,6 +132,10 @@ jobs:
120132 platform : darwin
121133 arch : arm64
122134 binary_name : apm-darwin-arm64
135+ - os : windows-latest
136+ platform : windows
137+ arch : x86_64
138+ binary_name : apm-windows-x86_64
123139
124140 runs-on : ${{ matrix.os }}
125141 permissions :
@@ -149,19 +165,34 @@ jobs:
149165 until xcode-select -p >/dev/null 2>&1; do sleep 5; done
150166 brew install upx
151167
152- - name : Install uv
168+ - name : Install uv (Unix)
169+ if : matrix.platform != 'windows'
153170 run : |
154171 curl -LsSf https://astral.sh/uv/install.sh | sh
155172 echo "$HOME/.cargo/bin" >> $GITHUB_PATH
173+
174+ - name : Install uv (Windows)
175+ if : matrix.platform == 'windows'
176+ shell : pwsh
177+ run : |
178+ irm https://astral.sh/uv/install.ps1 | iex
179+ echo "$env:USERPROFILE\.local\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
156180
157181 - name : Install Python dependencies
158182 run : |
159183 uv sync --extra dev --extra build
160184
161- - name : Build binary
185+ - name : Build binary (Unix)
186+ if : matrix.platform != 'windows'
162187 run : |
163188 chmod +x scripts/build-binary.sh
164189 uv run ./scripts/build-binary.sh
190+
191+ - name : Build binary (Windows)
192+ if : matrix.platform == 'windows'
193+ shell : pwsh
194+ run : |
195+ uv run pwsh scripts/windows/build-binary.ps1
165196
166197 - name : Upload binary as workflow artifact
167198 uses : actions/upload-artifact@v4
@@ -171,7 +202,11 @@ jobs:
171202 ./dist/${{ matrix.binary_name }}
172203 ./dist/${{ matrix.binary_name }}.sha256
173204 ./scripts/test-release-validation.sh
205+ ./scripts/windows/test-release-validation.ps1
206+ ./scripts/test-dependency-integration.sh
207+ ./scripts/windows/test-dependency-integration.ps1
174208 ./scripts/github-token-helper.sh
209+ ./scripts/windows/github-token-helper.ps1
175210 include-hidden-files : true # Required to include .apm directories
176211 retention-days : 30
177212 if-no-files-found : error
@@ -202,6 +237,10 @@ jobs:
202237 arch : arm64
203238 platform : darwin
204239 binary_name : apm-darwin-arm64
240+ - os : windows-latest
241+ arch : x86_64
242+ platform : windows
243+ binary_name : apm-windows-x86_64
205244
206245 runs-on : ${{ matrix.os }}
207246 permissions :
@@ -236,15 +275,24 @@ jobs:
236275 # Wait for installation to complete
237276 until xcode-select -p >/dev/null 2>&1; do sleep 5; done
238277
239- - name : Install uv
278+ - name : Install uv (Unix)
279+ if : matrix.platform != 'windows'
240280 run : |
241281 curl -LsSf https://astral.sh/uv/install.sh | sh
242282 echo "$HOME/.cargo/bin" >> $GITHUB_PATH
283+
284+ - name : Install uv (Windows)
285+ if : matrix.platform == 'windows'
286+ shell : pwsh
287+ run : |
288+ irm https://astral.sh/uv/install.ps1 | iex
289+ echo "$env:USERPROFILE\.local\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
243290
244291 - name : Install test dependencies
245292 run : uv sync --extra dev
246293
247- - name : Run integration tests
294+ - name : Run integration tests (Unix)
295+ if : matrix.platform != 'windows'
248296 env :
249297 APM_E2E_TESTS : " 1"
250298 GITHUB_TOKEN : ${{ secrets.GH_MODELS_PAT }} # Models access
@@ -255,6 +303,18 @@ jobs:
255303 uv run ./scripts/test-integration.sh
256304 timeout-minutes : 20
257305
306+ - name : Run integration tests (Windows)
307+ if : matrix.platform == 'windows'
308+ shell : pwsh
309+ env :
310+ APM_E2E_TESTS : " 1"
311+ GITHUB_TOKEN : ${{ secrets.GH_MODELS_PAT }}
312+ GITHUB_APM_PAT : ${{ secrets.GH_CLI_PAT }}
313+ ADO_APM_PAT : ${{ secrets.ADO_APM_PAT }}
314+ run : |
315+ uv run pwsh scripts/windows/test-integration.ps1 -SkipBuild
316+ timeout-minutes : 20
317+
258318# Release validation tests - Final pre-release validation of shipped binary
259319 release-validation :
260320 name : Release Validation
@@ -279,6 +339,10 @@ jobs:
279339 arch : arm64
280340 platform : darwin
281341 binary_name : apm-darwin-arm64
342+ - os : windows-latest
343+ arch : x86_64
344+ platform : windows
345+ binary_name : apm-windows-x86_64
282346
283347 runs-on : ${{ matrix.os }}
284348 permissions :
@@ -308,9 +372,10 @@ jobs:
308372 uses : actions/download-artifact@v4
309373 with :
310374 name : ${{ matrix.binary_name }}
311- path : /tmp/apm-isolated-test/
375+ path : ${{ matrix.platform == 'windows' && 'D:\apm-isolated-test' || ' /tmp/apm-isolated-test/' }}
312376
313- - name : Make binary executable and verify isolation
377+ - name : Make binary executable and verify isolation (Unix)
378+ if : matrix.platform != 'windows'
314379 run : |
315380 cd /tmp/apm-isolated-test
316381
@@ -322,24 +387,54 @@ jobs:
322387 # Make the binary executable
323388 chmod +x ./dist/${{ matrix.binary_name }}/apm
324389
325- - name : Create APM symlink for testing
390+ - name : Create APM symlink for testing (Unix)
391+ if : matrix.platform != 'windows'
326392 run : |
327393 cd /tmp/apm-isolated-test
328394 ln -s "$(pwd)/dist/${{ matrix.binary_name }}/apm" "$(pwd)/apm"
329395 echo "/tmp/apm-isolated-test" >> $GITHUB_PATH
396+
397+ - name : Verify binary and add to PATH (Windows)
398+ if : matrix.platform == 'windows'
399+ shell : pwsh
400+ run : |
401+ cd D:\apm-isolated-test
402+
403+ # Debug: List the downloaded structure
404+ Write-Host "Downloaded structure:"
405+ Get-ChildItem -Recurse -Filter "apm.exe"
406+ Get-ChildItem .\dist\
407+
408+ # Add binary directory to PATH
409+ $binDir = "D:\apm-isolated-test\dist\${{ matrix.binary_name }}"
410+ echo $binDir | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
330411
331- - name : Run release validation tests
412+ - name : Run release validation tests (Unix)
413+ if : matrix.platform != 'windows'
332414 env :
333- APM_E2E_TESTS : " 1" # Avoids interactive prompts for MCP env values with apm install
415+ APM_E2E_TESTS : " 1"
334416 GITHUB_TOKEN : ${{ secrets.GH_MODELS_PAT }}
335- GITHUB_APM_PAT : ${{ secrets.GH_CLI_PAT }} # Primary: APM module access
336- ADO_APM_PAT : ${{ secrets.ADO_APM_PAT }} # Azure DevOps module access
417+ GITHUB_APM_PAT : ${{ secrets.GH_CLI_PAT }}
418+ ADO_APM_PAT : ${{ secrets.ADO_APM_PAT }}
337419 run : |
338420 cd /tmp/apm-isolated-test
339421 chmod +x scripts/test-release-validation.sh
340422 ./scripts/test-release-validation.sh
341423 timeout-minutes : 20
342424
425+ - name : Run release validation tests (Windows)
426+ if : matrix.platform == 'windows'
427+ shell : pwsh
428+ env :
429+ APM_E2E_TESTS : " 1"
430+ GITHUB_TOKEN : ${{ secrets.GH_MODELS_PAT }}
431+ GITHUB_APM_PAT : ${{ secrets.GH_CLI_PAT }}
432+ ADO_APM_PAT : ${{ secrets.ADO_APM_PAT }}
433+ run : |
434+ cd D:\apm-isolated-test
435+ .\scripts\windows\test-release-validation.ps1
436+ timeout-minutes : 20
437+
343438
344439 create-release :
345440 name : Create GitHub Release
@@ -395,6 +490,32 @@ jobs:
395490 exit 1
396491 fi
397492 done
493+
494+ binary="apm-windows-x86_64"
495+ artifact_dir="${binary}"
496+ binary_dir="${artifact_dir}/dist/${binary}"
497+ if [ -d "$binary_dir" ] && [ -f "$binary_dir/apm.exe" ]; then
498+ echo "Processing $binary_dir directory..."
499+ (
500+ cd "${artifact_dir}/dist"
501+ zip -qr "../../${binary}.zip" "${binary}"
502+ )
503+ if command -v sha256sum &> /dev/null; then
504+ sha256sum "${binary}.zip" > "${binary}.zip.sha256"
505+ elif command -v shasum &> /dev/null; then
506+ shasum -a 256 "${binary}.zip" > "${binary}.zip.sha256"
507+ fi
508+ echo "Created ${binary}.zip"
509+ else
510+ echo "ERROR: Binary directory $binary_dir not found or $binary_dir/apm.exe missing"
511+ echo "Artifact directory contents:"
512+ ls -la "$artifact_dir/" || echo "Directory $artifact_dir does not exist"
513+ if [ -d "$artifact_dir/dist" ]; then
514+ echo "Dist directory contents:"
515+ ls -la "$artifact_dir/dist/"
516+ fi
517+ exit 1
518+ fi
398519
399520 - name : Determine release type
400521 id : release_type
@@ -430,6 +551,8 @@ jobs:
430551 ./dist/apm-darwin-x86_64.tar.gz.sha256
431552 ./dist/apm-darwin-arm64.tar.gz
432553 ./dist/apm-darwin-arm64.tar.gz.sha256
554+ ./dist/apm-windows-x86_64.zip
555+ ./dist/apm-windows-x86_64.zip.sha256
433556
434557 # Publish to PyPI (only stable releases from public repo)
435558 publish-pypi :
@@ -533,3 +656,42 @@ jobs:
533656 "linux_arm64": "${{ steps.checksums.outputs.linux-arm64-sha }}"
534657 }
535658 }
659+
660+ # Update Scoop bucket (only stable releases from public repo)
661+ update-scoop :
662+ name : Update Scoop Bucket
663+ runs-on : ubuntu-latest
664+ needs : [test, build, integration-tests, release-validation, create-release, publish-pypi]
665+ # TODO: Enable once downstream repository and secrets are configured (see #88)
666+ if : false && github.ref_type == 'tag' && needs.create-release.outputs.is_private_repo != 'true' && needs.create-release.outputs.is_prerelease != 'true'
667+ permissions :
668+ contents : read
669+
670+ steps :
671+ - name : Extract Windows checksum from GitHub release
672+ id : checksums
673+ run : |
674+ RELEASE_TAG="${{ github.ref_name }}"
675+ curl -L -o apm-windows-x86_64.zip.sha256 \
676+ "https://github.com/${{ github.repository }}/releases/download/$RELEASE_TAG/apm-windows-x86_64.zip.sha256"
677+ WINDOWS_X86_64_SHA=$(cat apm-windows-x86_64.zip.sha256 | cut -d' ' -f1)
678+ echo "windows-x86_64-sha=$WINDOWS_X86_64_SHA" >> $GITHUB_OUTPUT
679+ echo "Windows x86_64 SHA: $WINDOWS_X86_64_SHA"
680+
681+ - name : Trigger Scoop bucket repository update
682+ uses : peter-evans/repository-dispatch@v3
683+ with :
684+ token : ${{ secrets.GH_PKG_PAT }}
685+ repository : microsoft/scoop-apm
686+ event-type : bucket-update
687+ client-payload : |
688+ {
689+ "release": {
690+ "version": "${{ github.ref_name }}",
691+ "tag": "${{ github.ref_name }}",
692+ "repository": "${{ github.repository }}"
693+ },
694+ "checksums": {
695+ "windows_x86_64": "${{ steps.checksums.outputs.windows-x86_64-sha }}"
696+ }
697+ }
0 commit comments