Skip to content

Commit f303655

Browse files
committed
feat: Windows CI adds unit tests, E2E suite, and self-host smoke
Align Windows CI with Linux/macOS: - mcpp test (unit + integration tests) - E2E suite with WINDOWS_SKIP list (inherits MACOS_SKIP + Windows- specific exclusions for symlinks, LLVM Unix paths, pack/install.sh) - Self-host smoke (freshly-built mcpp builds itself again) - Package + smoke-test + upload artifact
1 parent 6255c27 commit f303655

2 files changed

Lines changed: 67 additions & 59 deletions

File tree

.github/workflows/ci-windows.yml

Lines changed: 43 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,23 @@
11
name: ci-windows
22

3-
# Windows CI for mcpp.
4-
# Step 1: Bootstrap mcpp via xlings (same as Linux/macOS).
5-
# Step 2: Self-host — use mcpp to build itself (LLVM + MSVC STL import std).
6-
# Step 3: Package the self-hosted binary into a distributable zip.
3+
# Windows CI for mcpp — validates LLVM/Clang as the Windows toolchain.
4+
# Same flow as Linux (ci.yml) and macOS (ci-macos.yml):
5+
# xlings install mcpp → self-host build → unit tests → E2E → smoke
76

87
on:
98
push:
10-
branches: [ feat/windows-support ]
9+
branches: [ feat/windows-support, main ]
1110
pull_request:
1211
branches: [ main ]
13-
paths:
14-
- 'src/toolchain/**'
15-
- 'src/build/**'
16-
- 'src/cli.cppm'
17-
- '.github/workflows/ci-windows.yml'
1812
workflow_dispatch:
1913

2014
concurrency:
2115
group: ci-windows-${{ github.ref }}
2216
cancel-in-progress: true
2317

2418
jobs:
25-
windows-build:
26-
name: Windows x64 — build + self-host
19+
build-and-test:
20+
name: build + test (windows x64, self-host)
2721
runs-on: windows-latest
2822
timeout-minutes: 45
2923
steps:
@@ -63,19 +57,15 @@ jobs:
6357
test -f "$MCPP"
6458
"$MCPP" --version
6559
echo "MCPP=$MCPP" >> "$GITHUB_ENV"
66-
echo "XLINGS_BIN=$USERPROFILE/.xlings/subos/default/bin/xlings.exe" >> "$GITHUB_ENV"
60+
XLINGS_BIN=$(cygpath -w "$USERPROFILE/.xlings/subos/default/bin/xlings.exe")
61+
echo "XLINGS_BIN=$XLINGS_BIN" >> "$GITHUB_ENV"
6762
68-
- name: Self-host — mcpp builds itself
63+
- name: Build mcpp from source (self-host)
6964
shell: bash
7065
run: |
71-
echo "=== Self-host: mcpp builds mcpp ==="
72-
"$MCPP" --version
73-
74-
# mcpp build uses LLVM on Windows (from mcpp.toml: windows = "llvm@20.1.7")
75-
XLINGS_WIN=$(cygpath -w "$XLINGS_BIN")
76-
export MCPP_VENDORED_XLINGS="$XLINGS_WIN"
66+
export MCPP_VENDORED_XLINGS="$XLINGS_BIN"
7767
78-
# Pre-seed mcpp sandbox with the already-installed LLVM from xlings
68+
# Pre-seed mcpp sandbox with xlings LLVM (avoids redundant download)
7969
MCPP_XPKGS="$USERPROFILE/.mcpp/registry/data/xpkgs"
8070
XLINGS_XPKGS="$USERPROFILE/.xlings/data/xpkgs"
8171
if [ -d "$XLINGS_XPKGS/xim-x-llvm" ]; then
@@ -87,18 +77,37 @@ jobs:
8777
8878
"$MCPP" build
8979
90-
# Find the self-hosted binary
91-
SELF_MCPP=$(find target -name "mcpp.exe" -path "*/bin/*" | head -1)
92-
test -n "$SELF_MCPP" || {
93-
echo "FAIL: self-host build did not produce mcpp.exe"
94-
find target -name "*.exe" 2>/dev/null
95-
exit 1
96-
}
97-
SELF_MCPP=$(cd "$(dirname "$SELF_MCPP")" && pwd)/$(basename "$SELF_MCPP")
98-
echo "Self-hosted binary: $SELF_MCPP"
99-
"$SELF_MCPP" --version
80+
- name: Unit + integration tests via mcpp test
81+
shell: bash
82+
run: |
83+
MCPP_FRESH=$(find target -name "mcpp.exe" -path "*/bin/*" | head -1)
84+
MCPP_FRESH=$(cd "$(dirname "$MCPP_FRESH")" && pwd)/$(basename "$MCPP_FRESH")
85+
echo "Self-hosted binary: $MCPP_FRESH"
86+
"$MCPP_FRESH" --version
87+
"$MCPP_FRESH" test
10088
101-
echo "MCPP_SELF=$SELF_MCPP" >> "$GITHUB_ENV"
89+
- name: E2E suite
90+
shell: bash
91+
run: |
92+
MCPP=$(find target -name "mcpp.exe" -path "*/bin/*" | head -1)
93+
MCPP=$(cd "$(dirname "$MCPP")" && pwd)/$(basename "$MCPP")
94+
test -f "$MCPP"
95+
export MCPP
96+
export MCPP_VENDORED_XLINGS="$XLINGS_BIN"
97+
export MCPP_E2E_TOOLCHAIN_MIRROR=GLOBAL
98+
"$MCPP" self config --mirror "$MCPP_E2E_TOOLCHAIN_MIRROR" 2>/dev/null || true
99+
"$MCPP" toolchain default llvm@20.1.7 2>/dev/null || true
100+
bash tests/e2e/run_all.sh
101+
102+
- name: Self-host smoke (freshly-built mcpp builds itself again)
103+
shell: bash
104+
run: |
105+
MCPP=$(find target -name "mcpp.exe" -path "*/bin/*" | head -1)
106+
MCPP=$(cd "$(dirname "$MCPP")" && pwd)/$(basename "$MCPP")
107+
export MCPP_VENDORED_XLINGS="$XLINGS_BIN"
108+
"$MCPP" build
109+
"$MCPP" --version
110+
echo ":: Self-host smoke PASS"
102111
103112
- name: Package Windows release zip
104113
id: package
@@ -109,38 +118,26 @@ jobs:
109118
WRAPPER="mcpp-${VERSION}-${PLAT}"
110119
ZIPNAME="${WRAPPER}.zip"
111120
112-
echo "Packaging $ZIPNAME ..."
121+
MCPP_SELF=$(find target -name "mcpp.exe" -path "*/bin/*" | head -1)
122+
MCPP_SELF=$(cd "$(dirname "$MCPP_SELF")" && pwd)/$(basename "$MCPP_SELF")
113123
114124
STAGING=$(mktemp -d)
115125
mkdir -p "$STAGING/$WRAPPER/bin"
116126
mkdir -p "$STAGING/$WRAPPER/registry/bin"
117127
118-
# Binary: self-hosted build
119-
echo "Packaging binary: $MCPP_SELF"
120128
cp "$MCPP_SELF" "$STAGING/$WRAPPER/bin/mcpp.exe"
121-
122-
# Launcher batch script
123129
printf '@echo off\r\n"%%~dp0bin\\mcpp.exe" %%*\r\n' > "$STAGING/$WRAPPER/mcpp.bat"
124-
125-
# Metadata
126130
cp README.md "$STAGING/$WRAPPER/" 2>/dev/null || true
127131
cp LICENSE "$STAGING/$WRAPPER/" 2>/dev/null || true
128132
129-
# Bundle xlings
130133
XLINGS_EXE="$USERPROFILE/.xlings/subos/default/bin/xlings.exe"
131134
if [ -f "$XLINGS_EXE" ]; then
132135
cp "$XLINGS_EXE" "$STAGING/$WRAPPER/registry/bin/xlings.exe"
133-
echo "Bundled xlings.exe"
134-
else
135-
echo "::warning::xlings.exe not found at $XLINGS_EXE"
136136
fi
137137
138-
# Create zip
139138
mkdir -p dist
140139
(cd "$STAGING" && 7z a -tzip "$ZIPNAME" "$WRAPPER")
141140
cp "$STAGING/$ZIPNAME" "dist/$ZIPNAME"
142-
143-
# SHA256
144141
(cd dist && sha256sum "$ZIPNAME" > "$ZIPNAME.sha256")
145142
146143
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
@@ -150,25 +147,13 @@ jobs:
150147
- name: Smoke-test the packaged zip
151148
shell: bash
152149
run: |
153-
VERSION="${{ steps.package.outputs.version }}"
154150
ZIPNAME="${{ steps.package.outputs.zipname }}"
155151
WRAPPER="${ZIPNAME%.zip}"
156-
157152
SMOKE=$(mktemp -d)
158153
(cd "$SMOKE" && unzip -q "$GITHUB_WORKSPACE/dist/$ZIPNAME")
159-
160-
echo "=== Layout ==="
161-
find "$SMOKE/$WRAPPER" -type f
162-
163-
echo "=== Version check ==="
164154
"$SMOKE/$WRAPPER/bin/mcpp.exe" --version
165-
166-
echo "=== xlings bundled ==="
167155
test -f "$SMOKE/$WRAPPER/registry/bin/xlings.exe"
168-
169-
echo "=== Launcher ==="
170156
test -f "$SMOKE/$WRAPPER/mcpp.bat"
171-
172157
echo "Smoke-test passed"
173158
174159
- name: Upload artifact

tests/e2e/run_all.sh

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,32 @@ MACOS_SKIP=(
6060
33_multi_version_mangling.sh
6161
)
6262

63+
# Windows inherits all macOS skips (no GCC, no ELF, no patchelf) plus
64+
# additional Windows-specific exclusions.
65+
WINDOWS_SKIP=(
66+
"${MACOS_SKIP[@]}"
67+
# Symlinks (ln -sf) not available in Git Bash without elevated perms
68+
10_env_command.sh
69+
# LLVM tests hardcode Unix paths / binary names without .exe
70+
36_llvm_toolchain_basic.sh
71+
37_llvm_import_std.sh
72+
38_llvm_std_compat.sh
73+
39_llvm_multi_module.sh
74+
40_llvm_clang_scan_deps.sh
75+
41_llvm_incremental.sh
76+
# Pack is Linux/macOS only (patchelf, tar, musl)
77+
31_pack_publish_dry_run.sh
78+
# install.sh is a Unix shell script
79+
45_install_platform_mapping.sh
80+
)
81+
6382
should_skip() {
6483
local name="$1"
65-
if [[ "$OS" == "Darwin" ]]; then
84+
if [[ "$OS" == MINGW* || "$OS" == MSYS* || "$OS" == CYGWIN* ]]; then
85+
for skip in "${WINDOWS_SKIP[@]}"; do
86+
[[ "$name" == "$skip" ]] && return 0
87+
done
88+
elif [[ "$OS" == "Darwin" ]]; then
6689
for skip in "${MACOS_SKIP[@]}"; do
6790
[[ "$name" == "$skip" ]] && return 0
6891
done

0 commit comments

Comments
 (0)