Repository navigation
Run all samples on a Windows runner from Git Bash - #142
Open
paolosalvatori wants to merge 21 commits into
Open
paolosalvatori wants to merge 21 commits into
paolosalvatori wants to merge 21 commits into
Conversation
run-samples.sh registered 26 of the 27 sample variants that ship scripts; the Python variant of web-app-cosmosdb-nosql-api was the one missing, so CI only ever ran its .NET counterpart. It is registered next to the .NET entry with the same deploy, validate and call steps, and, like it, is not added to ARM64_SAMPLE_DIRS. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
Git Bash and MSYS2 shells rewrite every argument that looks like an absolute POSIX path before starting a Windows program, so Azure values such as the Cosmos DB partition key path /username, resource IDs and the Front Door origin path reached az as Windows paths (SMF-963). The README now asks Windows users of these shells to export MSYS_NO_PATHCONV=1, which turns the rewriting off, and explains why. With the rewriting off, the local files the scripts hand to Windows programs need their Windows form: the temporary files read by curl and jq, the Python checks of the Event Hubs samples, the API Management definition and policy, the downloaded blob and the QR code. A native_path helper in each of these scripts returns that form through cygpath when it exists and the path unchanged otherwise, so Linux, macOS and WSL behave exactly as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
The Event Hubs and Event Hubs with Event Grid deployments write their function and dashboard archives to an absolute path under the scripts folder. Git Bash ships no zip, and a zip.exe built for Windows cannot open a /c/... path once MSYS_NO_PATHCONV=1 is set, so the archive path now goes through native_path as well; a zip from MSYS2 accepts the C:/... form too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
A manual run with the new windows input runs, instead of the Linux matrix, seven samples on windows-latest from Git Bash, with MSYS_NO_PATHCONV=1 set as the README asks Windows users to do: the samples whose scripts pass a Cosmos DB partition key, resource IDs, Front Door paths, or local files read by az, curl, jq, python and zip. The emulator is a Linux image and Docker on the Windows runner runs Windows containers, so the job starts Docker Engine inside an Ubuntu WSL 2 distribution, runs the emulator there, and reaches it from Windows over ports WSL forwards to localhost. lstk finds the running container by its name, so run-samples.sh drives each sample exactly as it does on Linux. Git Bash ships no zip, so a shim hands zip -r to the 7-Zip the runner image ships. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
This was referenced Oct 23, 2026
Git for Windows refuses to check out a path whose last component ends with a period, so a clone of this repository on Windows stops with "error: invalid path 'samples/web-app-cosmosdb-nosql-api/python/scripts/...'" and leaves no working tree. The file named "..." is empty, nothing references it, and it arrived by accident in 0f07d42. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
…ged one
Installing docker.io in the WSL distribution already starts a Docker daemon on the Unix socket alone, so the daemon the job started with TCP port 2375 exited at once ("process with PID 1063 is still running"), the readiness check passed against the packaged daemon, and the Windows docker CLI found nothing on the port.
The step now stops the packaged daemon (its systemd units, or its PID file without systemd), starts its own, and waits on the TCP endpoint.
The Docker Engine log step runs only once WSL is set up, since its wsl-bash shell does not exist before that.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
paolosalvatori
had a problem deploying
to
AZURE
October 23, 2026 14:32 — with
GitHub Actions
Failure
paolosalvatori
had a problem deploying
to
AZURE
October 23, 2026 14:32 — with
GitHub Actions
Failure
paolosalvatori
had a problem deploying
to
AZURE
October 23, 2026 14:32 — with
GitHub Actions
Failure
paolosalvatori
had a problem deploying
to
AZURE
October 23, 2026 14:32 — with
GitHub Actions
Failure
paolosalvatori
had a problem deploying
to
AZURE
October 23, 2026 14:32 — with
GitHub Actions
Failure
paolosalvatori
had a problem deploying
to
AZURE
October 23, 2026 14:32 — with
GitHub Actions
Failure
paolosalvatori
had a problem deploying
to
AZURE
October 23, 2026 14:32 — with
GitHub Actions
Failure
The Windows job takes its matrix from the setup job, which on a manual run with the windows input selects every sample on amd64, the architecture of the Windows runner, and the Linux matrix stays out of that run. It now provides what the remaining samples need: Java for the Service Bus sample, the zip MSYS2 ships (the 7-Zip shim dropped zip's -x exclusions), psql from the PostgreSQL the image installs, and the Go sqlcmd release, pinned with its SHA-256. As in the Linux job, a failed sample is retried once on a fresh emulator. lstk 1.4.0 cannot register its Azure CLI cloud on Windows when the CLI sits under C:\\Program Files: cmd.exe cuts the command line that carries the cloud configuration's JSON at that space. A junction without spaces, first on the PATH, works around it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
paolosalvatori
had a problem deploying
to
AZURE
October 23, 2026 15:01 — with
GitHub Actions
Failure
paolosalvatori
had a problem deploying
to
AZURE
October 23, 2026 15:01 — with
GitHub Actions
Failure
With MSYS_NO_PATHCONV=1 these shells no longer turn a /dev/null argument into nul for Windows programs, so a Windows curl given -o /dev/null cannot open its output and exits with code 23 as soon as a response has a body. The MySQL readiness loops would then read HTTP_CODE as 200000, the status followed by their || echo "000" fallback, and never finish. A null_device helper returns NUL for a Windows curl in these shells and /dev/null everywhere else, MSYS2's own curl included, and the 23 curl calls that discard a body in 11 scripts use it. The README says so, and tells script authors to do the same. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
Maven's mvn launcher is a shell script that hands its own paths, such as its classpath, to Java, a Windows program on Windows, and relies on Git Bash and MSYS2 converting them. With MSYS_NO_PATHCONV=1 Java received the POSIX paths and stopped with "Could not find or load main class org.codehaus.plexus.classworlds.launcher.Launcher", as the Windows job showed. The three deploy scripts of the Service Bus sample run mvn in a subshell that unsets the variable, and the README tells script authors to do the same for such launchers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
… sample runs it Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Unhandled CRLF output from native Windows tools causes deterministic failures in sample comparisons and numeric checks.
2 open issues
What changed in this PR
Adds an on-demand Windows CI path to exercise the sample suite from Git Bash with MSYS_NO_PATHCONV=1, complementing the Windows compatibility changes in #141.
Changes:
- Adds a manual
windowsinput that selects the full amd64 sample matrix instead of Linux jobs. - Runs Docker Engine and the LocalStack emulator inside WSL 2, accessible from Windows tools.
- Installs sample prerequisites and adds retry handling and diagnostic logs.
| File | Description |
|---|---|
.github/workflows/run-samples.yml |
Adds Windows dispatch routing, WSL-backed emulator setup, tooling, sample execution and retries. |
Review effort: Balanced
… programs Windows programs such as the Azure CLI and jq end every line with a carriage return, which Bash keeps in $(...) and read, so a name or an ID read from az --output tsv carries a trailing \r. In the Windows CI run, the App Configuration sample's private endpoint failed twice with ResourceNotFound for a key vault that existed, its name ending in that \r. MSYS2's bash, which Git Bash ships, drops carriage returns from command substitution and read when its igncr option is on, and an exported SHELLOPTS passes the option to the scripts, so the README asks for set -o igncr and export SHELLOPTS next to MSYS_NO_PATHCONV=1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
…the README asks The README asks Windows users for set -o igncr and export SHELLOPTS. Exporting SHELLOPTS in a step would also hand the step's own -e and pipefail to the sample scripts, so the job turns the option on for every bash through BASH_ENV instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
On Windows the Azure CLI ends every line with a carriage return, and bash's igncr option drops it from $(...) and read but not from mapfile. The App Configuration samples read several fields at once with mapfile, so in the Windows CI the key vault ID kept its \r and the private endpoint failed with ResourceNotFound, and the AKS sample read the cluster's OIDC and workload identity flags as "true\r". Every mapfile that reads az output, in those samples and in the AKS cluster scripts, now reads it through tr -d '\r', which changes nothing on Linux and macOS, and the README says igncr does not cover mapfile. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
With DNS tunneling, on by default, the containers of the Docker Engine in WSL could not reach the 10.255.255.254 resolver WSL configures, so their lookups timed out: the Docker Engine log held dozens of "failed to query external DNS server" errors, and the Container Apps runtime could not pull the sample's image (ImagePullBackOff). Without tunneling, WSL hands out the NAT device on the host as the DNS server, which containers reach too (https://learn.microsoft.com/windows/wsl/troubleshooting#common-issues). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
…eachable call-web-app.sh compares the certificate the web app loaded from Key Vault with the one it serves on port 8443, and reaches that port through the container's IP address. The host can reach that address only when Docker runs natively on Linux; with Docker Desktop on Windows and macOS, and in the Windows CI, the .NET script timed out and failed a deployment that worked. Both scripts now record whether the earlier call through the container IP succeeded, and when it did not, they say so and skip the certificate check. On Linux the check runs as before, the .NET one failing when HTTPS on port 8443 is broken. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
Brings in #141, squash-merged as 82017ac, so this pull request shows only its own change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
DrisDary
approved these changes
Oct 26, 2026
DrisDary
left a comment
Contributor
There was a problem hiding this comment.
Thanks @paolosalvatori windows makes sence
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Motivation
#141 asks Windows users of Git Bash and MSYS2 to export
MSYS_NO_PATHCONV=1and adapts the scripts to it, but the Samples CI runs only on Linux, so nothing checks that the samples work from Git Bash.This adds a Windows job that runs every sample there, on demand, as a reproduction of that setup.
It is stacked on #141 and will be retargeted to
mainonce that pull request merges.Fixes SMF-980
Changes
windowsinput of the manual run starts the newwindowsjob instead of the Linux matrix. The setup job then selects every sample, on amd64, the architecture of the Windows runner, whateverrun_modeandarchsay.windows-latestand uses Git Bash, the defaultbashshell of Windows runners, withMSYS_NO_PATHCONV=1set as the README asks.run-samples.shdrives each sample exactly as in the Linux job, and a failed sample is retried once on a fresh emulator, as there.Vampire/setup-wsl) and runs the emulator there withdocker run. The Windows docker CLI andlstkreach that engine throughDOCKER_HOST=tcp://127.0.0.1:2375, which WSL forwards to the runner's localhost. Installingdocker.ioalready starts a daemon on the Unix socket alone, so the job stops it and starts one that also listens on TCP, and waits on the TCP endpoint.set -o igncr), turned on for every bash throughBASH_ENV, since exportingSHELLOPTSin a step would hand the step's own-eandpipefailto the sample scripts.lstk1.4.0 cannot register its Azure CLI cloud on Windows when the CLI sits underC:\Program Files: it passes the cloud configuration's JSON toaz.cmd, andcmd.executs that command line at the space ('C:\Program' is not recognized). A junction without spaces, first on the PATH, works around it untillstkpasses the JSON another way.zipMSYS2 ships,psqlfrom the image's PostgreSQL, the Gosqlcmdrelease pinned with its SHA-256, and Java 25 for the Service Bus sample. A step prints their versions.Tests
actionlintwithshellcheckon the workflow and on each bash step, and the repository's pre-commit hooks (zizmor,gitleaks)...., and Maven'smvnlauncher needs the path conversion (both fixed in Run the scripts from Git Bash and MSYS2 on Windows #141); the Docker daemon the package started (fixed here); and thelstkcloud registration above (worked around here).Related
🤖 Generated with Claude Code
https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh