Skip to content

Run all samples on a Windows runner from Git Bash - #142

Draft
paolosalvatori wants to merge 10 commits into
smf-963-web-app-cosmosdb-nosql-api-sample-fails-on-windows-git-bashfrom
windows-git-bash-samples-ci
Draft

paolosalvatori wants to merge 10 commits into
smf-963-web-app-cosmosdb-nosql-api-sample-fails-on-windows-git-bashfrom
windows-git-bash-samples-ci

Conversation

@paolosalvatori

@paolosalvatori paolosalvatori commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

#141 asks Windows users of Git Bash and MSYS2 to export MSYS_NO_PATHCONV=1 and 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 main once that pull request merges.

Fixes SMF-980

Changes

  • A new windows input of the manual run starts the new windows job instead of the Linux matrix. The setup job then selects every sample, on amd64, the architecture of the Windows runner, whatever run_mode and arch say.
  • The job runs on windows-latest and uses Git Bash, the default bash shell of Windows runners, with MSYS_NO_PATHCONV=1 set as the README asks. run-samples.sh drives each sample exactly as in the Linux job, and a failed sample is retried once on a fresh emulator, as there.
  • 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 (Vampire/setup-wsl) and runs the emulator there with docker run. The Windows docker CLI and lstk reach that engine through DOCKER_HOST=tcp://127.0.0.1:2375, which WSL forwards to the runner's localhost. Installing docker.io already 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.
  • As the README asks, bash drops the carriage returns Windows programs print (set -o igncr), turned on for every bash through BASH_ENV, since exporting SHELLOPTS in a step would hand the step's own -e and pipefail to the sample scripts.
  • WSL's DNS tunneling is turned off: with it, the containers of the Docker Engine in WSL could not reach WSL's resolver, and the Container Apps runtime could not pull images; without it, WSL hands out the NAT device on the host as the DNS server, which containers reach too.
  • lstk 1.4.0 cannot register its Azure CLI cloud on Windows when the CLI sits under C:\Program Files: it passes the cloud configuration's JSON to az.cmd, and cmd.exe cuts that command line at the space ('C:\Program' is not recognized). A junction without spaces, first on the PATH, works around it until lstk passes the JSON another way.
  • The tools the samples need and the Windows image lacks or keeps off the PATH: the zip MSYS2 ships, psql from the image's PostgreSQL, the Go sqlcmd release pinned with its SHA-256, and Java 25 for the Service Bus sample. A step prints their versions.

Tests

  • actionlint with shellcheck on the workflow and on each bash step, and the repository's pre-commit hooks (zizmor, gitleaks).
  • The first manual runs stopped before any sample ran and found four Windows problems: Git for Windows refused the empty file named ..., and Maven's mvn launcher 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 the lstk cloud registration above (worked around here).
  • This manual run runs every sample with all of them fixed.

Related

🤖 Generated with Claude Code

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
paolosalvatori and others added 2 commits October 23, 2026 16:32
…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
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
paolosalvatori requested a balanced review from Copilot October 23, 2026 15:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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 windows input 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

Comment thread .github/workflows/run-samples.yml
Comment thread .github/workflows/run-samples.yml
paolosalvatori and others added 4 commits October 23, 2026 17:28
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
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

This branch was successfully deployed

1 active deployment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants