Repository navigation
Run the scripts from Git Bash and MSYS2 on Windows - #141
Open
paolosalvatori wants to merge 9 commits into
Open
paolosalvatori wants to merge 9 commits into
paolosalvatori wants to merge 9 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
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 <[email protected]> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The upstream MSYS2 setup and remaining native Windows curl null-output paths leave Windows compatibility issues unresolved.
2 open issues
What changed in this PR
This PR improves Windows shell compatibility for the Azure samples by documenting path-conversion settings and explicitly converting local file paths passed to external tools.
Changes:
- Adds Git Bash and MSYS2 setup guidance.
- Converts temporary files, API definitions, Python script paths and archive destinations with
native_path. - Registers the Python Cosmos DB NoSQL sample in the shared sample runner.
| File | Description |
|---|---|
| samples/url-shortener/python/scripts/validate.sh | Converts the downloaded QR file path. |
| samples/function-app-managed-identity/python/scripts/test.sh | Converts the blob download destination. |
| samples/function-app-front-door/python/scripts/validate.sh | Converts response temporary-file paths. |
| samples/function-app-front-door/python/scripts/call-front-door.sh | Converts response temporary-file paths. |
| samples/eventhubs/python/terraform/deploy.sh | Converts function and dashboard archive destinations. |
| samples/eventhubs/python/scripts/validate.sh | Converts Python check paths. |
| samples/eventhubs/python/scripts/run-pipeline.sh | Converts Python paths and the function archive destination. |
| samples/eventhubs/python/scripts/deploy.sh | Converts function and dashboard archive destinations. |
| samples/eventhubs/python/bicep/deploy.sh | Converts function and dashboard archive destinations. |
| samples/eventhubs-eventgrid/python/terraform/deploy.sh | Converts the processor archive destination. |
| samples/eventhubs-eventgrid/python/scripts/validate.sh | Converts the Python check path. |
| samples/eventhubs-eventgrid/python/scripts/run-pipeline.sh | Converts Python reader paths. |
| samples/eventhubs-eventgrid/python/scripts/deploy.sh | Converts the processor archive destination. |
| samples/eventhubs-eventgrid/python/bicep/deploy.sh | Converts the processor archive destination. |
| samples/api-management-function-app/python/scripts/validate.sh | Converts response temporary-file paths. |
| samples/api-management-function-app/python/scripts/deploy.sh | Converts the API definition and policy directory path. |
| samples/api-management-function-app/python/scripts/call-api.sh | Converts response temporary-file paths. |
| run-samples.sh | Registers the Python Cosmos DB NoSQL sample. |
| README.md | Documents Windows shell setup and path handling. |
Review effort: Balanced
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 <[email protected]> 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 <[email protected]> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
… 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> Claude-Session: https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh
This branch was previously 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
Running the
web-app-cosmosdb-nosql-apisample from Git Bash on Windows fails at the Cosmos DB container step withInvalid partition key path found, and the script then carries on and deploys a web app whose container does not exist, as reported in SMF-963.When Git Bash, or any other shell built on MSYS2, starts a Windows program such as the Azure CLI, it rewrites every argument that looks like an absolute POSIX path into a Windows path, so
--partition-key-path /usernamereachesazasC:/Program Files/Git/username.The same happens to the resource IDs the scripts pass to
--scopeor--idsand to the Front Door origin and probe paths, so the problem is not limited to one sample.Our CI does not see it because it runs on Linux, where these arguments reach
azunchanged.Setting
MSYS_NO_PATHCONV=1turns the rewriting off, in Git Bash and in MSYS2 shells alike.Git for Windows also cannot check out the repository at all, because of an empty file named
....Fixes SMF-978
Changes
README.mdgets a "Windows: Git Bash and MSYS2" section under "Local Testing": it asks Windows users of these shells to runexport MSYS_NO_PATHCONV=1,set -o igncrandexport SHELLOPTSbefore any script, explains why, and covers making the setting permanent, recognizing these shells with$MSYSTEM, and turning the conversion back on.az,curl,jq,pythonorzipnow passes it through a smallnative_pathhelper, which returnscygpath -mof the path in Git Bash and MSYS2 and the path unchanged everywhere else, so Linux, macOS and WSL behave exactly as before:curlandjqin the API Management, Front Door and URL shortener scripts;function-app-managed-identity/python/scripts/test.sh;api-management-function-app/python/scripts/deploy.sh;zip, in the scripts, Bicep and Terraform variants (Git Bash ships nozip, and azip.exebuilt for Windows needs the converted path too)./dev/nullas theNULdevice, so the 23 curl calls that discard a response body, in 11 scripts, pass it-o "$(null_device)":NULfor a Windows curl in Git Bash and MSYS2,/dev/nulleverywhere else, MSYS2's own curl under/usr/binincluded. Without it, a Windows curl exited with code 23 on any response with a body, and the MySQL deploy scripts never left their readiness loop.mvnlauncher is a shell script that hands its own paths to Java and relies on the conversion, so the three Service Bus deploy scripts run it as(unset MSYS_NO_PATHCONV; mvn ...); with the variable set, Java could not find Maven's launcher class.jqend their lines with a carriage return, which Bash keeps in$(...)andread, so the README also asks forset -o igncrandexport SHELLOPTS: the bash of Git Bash and MSYS2 then drops it.mapfilekeeps the carriage return even then, so the App Configuration scripts, which read several fields at once with it, strip it withtr -d '\r'; without that, the sample failed on Windows withResourceNotFoundfor a key vault whose ID carried the carriage return....insamples/web-app-cosmosdb-nosql-api/python/scripts/is removed: Git for Windows refuses to check out a path whose last component ends with a period, so a clone on Windows stopped witherror: invalid pathand left no working tree.The file arrived by accident in 0f07d42 and nothing references it.
run-samples.shregisterssamples/web-app-cosmosdb-nosql-api/python, the one sample variant with scripts that was missing from the list, next to its .NET counterpart, so CI also runs the variant this fix started from.Tests
bash -non every edited script, andshellcheckreports the same findings as onmainfor each of them.C:/...form whencygpathis on the PATH.null_devicereturns/dev/nullwithoutcygpath,NULwithcygpathand a native curl first on the PATH, and/dev/nullwithcygpathand/usr/bin/curl.git ls-treefinds no other path that Windows refuses: no name that ends with a period or a space, no reserved device name, no character such as:....and the Maven launcher.Related
🤖 Generated with Claude Code
https://claude.ai/code/session_01DhZ2ojsEXd2SGMo7s9uiZh