Repository navigation
Commit 93bec7b
Run all samples on a Windows runner from Git Bash (#142)
* Run the Python variant of web-app-cosmosdb-nosql-api in the samples CI
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
* Run the scripts from Git Bash and MSYS2 with MSYS_NO_PATHCONV=1
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
* Hand zip a Windows path for the archives the Event Hubs scripts build
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
* Run a few samples on a Windows runner from Git Bash
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
* Remove the empty file whose name breaks checkouts on Windows
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
* Start the Windows job's Docker Engine on TCP after stopping the packaged 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
* Run every sample in the Windows job
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
* Discard curl's responses through the NUL device in Git Bash and MSYS2
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
* Run Maven with the path conversion back on in the Service Bus sample
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
* Print Maven's version with the path conversion on, as the Service Bus sample runs it
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
* Tell Git Bash and MSYS2 users to drop the carriage returns of Windows 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
* Drop the carriage returns of Windows programs in the Windows job, as 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
* Strip the carriage return of the Azure CLI from the arrays mapfile fills
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
* Turn off WSL's DNS tunneling in the Windows job
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
* Skip the SQL Database certificate check where the container IP is unreachable
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
* Run the Bicep and Terraform variants of the custom-image web app sample in CI
samples/web-app-custom-image/{python,dotnet}/{bicep,terraform} had no entry in run-samples.sh, so
the Samples CI never deployed them. Each entry now deploys with the variant's deploy.sh, then checks
the resources with the sample's validate.sh and calls the app with call-web-app.sh, as the scripts
variant does: the Bicep and Terraform deployments use the same prefix, suffix and names. They run
on amd64 and arm64, like the scripts variant, through ARM64_SAMPLE_DIRS.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
* Choose Linux, Windows or both with a platform dropdown, as entries of one matrix
A manual run now picks where the selected tests run with the platform input: Linux (the default),
Windows, or all. build-matrix.sh puts one entry per test and platform in the matrix, a Windows
entry on the amd64 windows-latest runner whatever arch says, and one job runs them all, its
Windows-only and Linux-only steps gated on the entry's platform. GitHub lists a matrix job it skips
under its unexpanded name, so with a separate Windows job a pull request run showed
"Windows (Git Bash): ${{ matrix.name }}"; now a run lists only the jobs it runs, the Windows ones
as "Test: <sample> [Windows]". run_mode selects the tests on both platforms.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
* Run the custom-image Terraform sample's push script with bash, so it also works on Windows
Terraform's local-exec hands its command to cmd.exe on Windows, and cmd.exe cannot run
./push_image.sh ("'.' is not recognized as an internal or external command"), so the Terraform
variants of web-app-custom-image never pushed their image from Git Bash. interpreter = ["bash"]
runs the script with bash everywhere; Linux and macOS behave as before.
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>1 parent 39808b8 commit 93bec7b
5 files changed
Lines changed: 367 additions & 31 deletions
File tree
- .github
- scripts
- workflows
- samples/web-app-custom-image
- dotnet/terraform
- python/terraform
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
| 5 | + | |
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
10 | | - | |
| 10 | + | |
| 11 | + | |
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
16 | 23 | | |
17 | 24 | | |
18 | 25 | | |
19 | 26 | | |
20 | | - | |
| 27 | + | |
21 | 28 | | |
22 | 29 | | |
23 | 30 | | |
| |||
62 | 69 | | |
63 | 70 | | |
64 | 71 | | |
65 | | - | |
| 72 | + | |
66 | 73 | | |
67 | 74 | | |
| 75 | + | |
| 76 | + | |
68 | 77 | | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
| 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 | + | |
82 | 106 | | |
83 | 107 | | |
84 | 108 | | |
| |||
0 commit comments