Skip to content

Commit d5ecac2

Browse files
committed
docker windows test
1 parent 7b03f98 commit d5ecac2

6 files changed

Lines changed: 56 additions & 85 deletions

File tree

.github/workflows/docker-windows.yaml

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,35 @@ jobs:
165165
docker run --rm "$IMAGE_TAG" cmd /c "mise exec -- rustpython -c \"print('et-rp ok')\""
166166
echo "::endgroup::"
167167
168-
- name: Build stage precompile
168+
# Build target depends on base: nanoserver stops at `precompile` (no
169+
# python/dotnet/test-runtime; the test stage doesn't exist there),
170+
# servercore goes all the way through `test` so the next two steps can
171+
# `docker run` the suite. Both targets compose with the precompile-stage
172+
# layer cache from the build-minimal step above.
173+
- name: Build stage precompile (nanoserver) / test (servercore)
169174
env:
170175
DOCKERFILE: ${{ steps.dockerfile.outputs.dockerfile }}
171176
run: |
177+
if [ "${{ matrix.base }}" = "servercore" ]; then
178+
target=test
179+
tag="-t et-windows-test"
180+
else
181+
target=precompile
182+
tag=""
183+
fi
172184
args="-f $DOCKERFILE ${{ matrix.build_arg }} --build-arg MISE_ENV"
173-
args="$args --target precompile"
185+
args="$args --target $target $tag"
174186
docker build $args .
187+
188+
# Run the test suite split the same way docker-linux does: cargo-test-other
189+
# (workspace minus et-ws-web-runner) and test-ws-web-runner (Deno-runtime
190+
# gated, self-skips on hosts that can't satisfy it). Each runs in a fresh
191+
# container so the per-phase compile target/ doesn't share the writable
192+
# layer with the other phase. servercore-only -- Nano has no test stage.
193+
- name: Run cargo-test-other
194+
if: matrix.base == 'servercore'
195+
run: docker run --rm et-windows-test mise run cargo-test-other
196+
197+
- name: Run test-ws-web-runner
198+
if: matrix.base == 'servercore'
199+
run: docker run --rm et-windows-test mise run test-ws-web-runner

.github/workflows/test.yaml

Lines changed: 3 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,9 @@ jobs:
4141
# use the busybox-w32 ash that mise installs in `_setup_all` (the same
4242
# shell `MISE_BASH_PATH` already points at for `shell = "bash"` tasks on
4343
# the Windows Docker images). Avoids Git Bash's MSYS fork-emulation
44-
# cygheap pathology -- see OLD_NOTES.md for the captured error
45-
# signatures and the diagnostic harness that found the root cause. The
46-
# path matches the version pin in `.mise/config.windows.toml`'s
47-
# [tools."http:busybox"] entry. The `Set HOME = USERPROFILE on Windows`
48-
# step below explicitly overrides back to `shell: bash` because it
49-
# runs BEFORE `Install mise + tools` (which is what installs
50-
# busybox-w32). All later run-bodies use ash.
44+
# cygheap pathology on long-running mise task chains. The path matches
45+
# the version pin in `.mise/config.windows.toml`'s [tools."http:busybox"]
46+
# entry.
5147
defaults:
5248
run:
5349
shell: >-
@@ -117,48 +113,6 @@ jobs:
117113
sudo apt-get update
118114
sudo apt-get install -y mesa-vulkan-drivers
119115
120-
# Empirical probe: does the GHA windows-latest VM populate HOME in its
121-
# default env, or is the next step (Pre-mise: HOME = USERPROFILE)
122-
# genuinely load-bearing? Prints HOME/USERPROFILE from both Git Bash
123-
# (which auto-sets HOME from USERPROFILE on its own) and cmd (which
124-
# doesn't, so its output reflects only what the parent env has).
125-
# cmd resolves an unset var by leaving the literal `%HOME%` token in
126-
# the output, so `HOME=[%HOME%]` is the unambiguous "unset" signal;
127-
# `HOME=[]` means defined-but-empty; `HOME=[C:\Users\...]` means set.
128-
# Remove this step once the answer is captured in OLD_NOTES.md.
129-
- name: "Pre-mise: probe HOME on Windows"
130-
if: runner.os == 'Windows'
131-
timeout-minutes: 1
132-
# Same `shell:` rationale as the next step -- runs before
133-
# `Install mise + tools` so we can't use the job's busybox default.
134-
shell: bash --noprofile --norc -euo pipefail {0}
135-
run: |
136-
echo "=== Git Bash perspective ==="
137-
echo " HOME=[$HOME] USERPROFILE=[$USERPROFILE]"
138-
echo "=== cmd.exe perspective ==="
139-
# `cmd //c` (double slash) -- the single-slash form is rewritten by
140-
# MSYS path-translation as a Unix path, dropping cmd into interactive
141-
# mode and skipping the echo.
142-
cmd //c "echo HOME=[%HOME%] USERPROFILE=[%USERPROFILE%]"
143-
144-
# mise's Tera renderer expects $HOME to be set when evaluating env.HOME
145-
# in [vars] (config.toml has e.g. `conda_openssl = "{{ env.HOME }}/.local
146-
# /share/mise/installs/conda-openssl/3"`). MSYS bash auto-sets HOME from
147-
# USERPROFILE; pwsh and cmd do not, so mise tasks invoked from a pwsh
148-
# step fail with `Variable env.HOME not found in context while rendering
149-
# __tera_one_off`. Plumb HOME = USERPROFILE so every subsequent step
150-
# (incl. our pwsh diagnostic ones) sees it.
151-
- name: "Pre-mise: HOME = USERPROFILE on Windows"
152-
if: false
153-
# runner.os == 'Windows'
154-
timeout-minutes: 1
155-
# Explicit `shell: bash` because the job-level defaults point at the
156-
# busybox ash that's installed by the next step (Install mise +
157-
# tools), so we can't use it here yet. Git Bash is on the runner
158-
# image by default.
159-
shell: bash --noprofile --norc -euo pipefail {0}
160-
run: echo "HOME=$USERPROFILE" >> "$GITHUB_ENV"
161-
162116
- name: Install mise + tools
163117
uses: ./.github/actions/install-mise-tools
164118
timeout-minutes: 20

Dockerfile.windows

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,8 @@ RUN curl -fsSL -o vc_redist.exe https://aka.ms/vs/17/release/vc_redist.x64.exe &
4040
(vc_redist.exe /install /quiet /norestart || ver>nul) && `
4141
del vc_redist.exe
4242

43-
# Empirical probe: confirms Server Core leaves HOME unset by default
44-
# (USERPROFILE is set). cmd resolves an unset var by leaving the literal
45-
# `%HOME%` token in the output, so `HOME=[%HOME%]` is the unambiguous
46-
# "unset" signal here. Counterpart to the `Pre-mise: probe HOME on
47-
# Windows` step in test.yaml -- one captures the GHA windows-latest VM
48-
# state, this one captures the Server Core container base-image state.
49-
# Remove once the result is documented in OLD_NOTES.md.
50-
RUN echo before-env: HOME=[%HOME%] USERPROFILE=[%USERPROFILE%]
43+
# Should show literal `%HOME%` token in the output as HOME is unset.
44+
RUN echo HOME=[%HOME%] USERPROFILE=[%USERPROFILE%]
5145

5246
# Set HOME to the admin profile so the container has a sane home (Server Core
5347
# sets USERPROFILE but leaves HOME unset by default).
@@ -170,3 +164,12 @@ RUN (if exist C:\token\gh_token set /p GITHUB_TOKEN=<C:\token\gh_token) & `
170164
# --- precompile: build the WASM/JS modules. ---
171165
FROM prefetch AS precompile
172166
RUN mise run build-modules && if exist target rmdir /s /q target
167+
168+
# --- test: the full suite (Rust + every loaded guest language). ---
169+
# Compiled AND run at `docker run` time (precompile keeps no target/), so the
170+
# multi-GB debug test binaries never bake into a layer -- they live in the
171+
# ephemeral container and vanish when it exits. Sister to the Linux Dockerfile's
172+
# `test` stage; wgpu compute on Windows resolves through DX12 / WARP, so no
173+
# extra runtime packages are needed here.
174+
FROM precompile AS test
175+
CMD ["mise", "run", "test"]

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,10 @@ images when their respective `Dockerfile` is modified.
175175

176176
[`Dockerfile.nanoserver`](Dockerfile.nanoserver) starts from **Nano Server**
177177
(the smallest Windows base, ~120 MB) — which has no installer stack, or shell.
178+
Python and .Net do not work on this base.
179+
180+
[`Dockerfile.windows`](Dockerfile.windows) is the **Server Core** variant
181+
(~1.25 GB base) — the fuller Windows image, and all languages are supported.
178182

179183
A `gh_token` file (a GitHub token) in the build context is **optional** for a
180184
manual `Dockerfile.nanoserver` build — without it, mise uses GitHub's anonymous

config/ast-grep/rules/gha-no-step-shell.yaml

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,11 @@ message: |
55
Don't set `shell:` on a workflow step. Every workflow defaults to bash
66
(defaults.run.shell) and steps must use it -- write the step in bash (e.g.
77
`sc`/`net`/`printf` instead of PowerShell cmdlets, even on Windows runners,
8-
which have Git Bash) rather than overriding the shell per step. Carve-outs:
9-
(1) steps whose `name:` starts with `Pre-mise:` (steps that run BEFORE
10-
`Install mise + tools` and so can't use the mise-managed default shell --
11-
e.g. setting HOME from USERPROFILE on Windows); (2) `shell: msys2 {0}`
12-
(the wrapper that msys2/setup-msys2 requires for steps running inside
13-
its MINGW64 env -- Git Bash isn't a substitute). The matching conftest
14-
rule in `config/conftest/policy/gha/gha.rego` applies the same allow-list.
8+
which have Git Bash) rather than overriding the shell per step. One
9+
carve-out: `shell: msys2 {0}` (the wrapper that msys2/setup-msys2 requires
10+
for steps running inside its MINGW64 env -- Git Bash isn't a substitute).
11+
The matching conftest rule in `config/conftest/policy/gha/gha.rego`
12+
applies the same allow-list.
1513
files:
1614
- .github/workflows/*.yaml
1715
rule:
@@ -20,16 +18,7 @@ rule:
2018
- inside:
2119
kind: block_sequence
2220
stopBy: end
21+
# `shell: msys2 {0}` is the wrapper msys2/setup-msys2 documents
22+
# as the shell entry for steps that run inside its MINGW64 env.
2323
- not:
24-
any:
25-
# Tightly scoped to the IMMEDIATE step's block_mapping (no
26-
# `stopBy: end`), so a single `Pre-mise:`-named step elsewhere
27-
# in the file doesn't whitewash unrelated step-shell overrides.
28-
- inside:
29-
kind: block_mapping
30-
has:
31-
kind: block_mapping_pair
32-
regex: '^name:\s*"?Pre-mise:'
33-
# `shell: msys2 {0}` is the wrapper msys2/setup-msys2 documents
34-
# as the shell entry for steps that run inside its MINGW64 env.
35-
- regex: '^shell:\s*msys2\b'
24+
regex: '^shell:\s*msys2\b'

config/conftest/policy/gha/gha.rego

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,13 @@ deny contains msg if {
1717
}
1818

1919
# Steps must not override the shell -- rely on the workflow default (write the
20-
# step in bash rather than switching to PowerShell on Windows runners). Two
21-
# carve-outs: (1) `name:` prefix `Pre-mise:` (steps that run BEFORE
22-
# `Install mise + tools` and so can't use the mise-managed default shell --
23-
# e.g. setting HOME from USERPROFILE on Windows); (2) `shell: msys2 {0}`
24-
# (the wrapper msys2/setup-msys2 requires for steps running inside its
25-
# MINGW64 env -- Git Bash isn't a substitute).
20+
# step in bash rather than switching to PowerShell on Windows runners). One
21+
# carve-out: `shell: msys2 {0}` (the wrapper msys2/setup-msys2 requires for
22+
# steps running inside its MINGW64 env -- Git Bash isn't a substitute).
2623
deny contains msg if {
2724
some name, job in input.jobs
2825
some step in job.steps
2926
step.shell
30-
not startswith(step.name, "Pre-mise:")
3127
not startswith(step.shell, "msys2 ")
3228
msg := sprintf("job %q sets shell: on a step; use the workflow default", [name])
3329
}

0 commit comments

Comments
 (0)