-
Notifications
You must be signed in to change notification settings - Fork 6
192 lines (175 loc) · 8.17 KB
/
Copy pathci-linux-e2e.yml
File metadata and controls
192 lines (175 loc) · 8.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
name: ci-linux-e2e
# The e2e suite (tests/e2e/run_all.sh, ~18 min) split out of ci-linux.yml so it
# runs in PARALLEL with the build/unit/toolchain-matrix job instead of tacked on
# after it. Both workflows share the same cache lineage (mcpp sandbox + xlings +
# target/), so this job restores a warm build and the only added wall-clock vs.
# the inline version is one extra warm `mcpp build`. Net per-PR critical path
# drops from "build + … + e2e" to max(build+matrix, build+e2e).
#
# Paired workflows: ci-linux.yml (build + unit + toolchain matrix + integration),
# ci-macos.yml, ci-windows.yml.
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
workflow_dispatch:
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
e2e:
name: e2e suite (linux x86_64, self-host)
runs-on: ubuntu-24.04
timeout-minutes: 45
env:
MCPP_HOME: /home/runner/.mcpp
# NOTE: do NOT force MCPP_VERBOSE here. The e2e suite includes tests that
# assert mcpp's DEFAULT (quiet) output — e.g. 48_build_error_output and
# 53_namespaced_cache_label — which forced verbose would break. Verbose is
# set only in the fresh-install workflows (cold bootstrap, no such asserts).
# A specific test that needs verbose passes `--verbose` itself.
steps:
- uses: actions/checkout@v4
# Same cache lineage as ci-linux.yml so this job lands on a warm
# toolchain/sandbox instead of re-installing it. Both workflows read
# (and may save) the same keys; actions/cache tolerates concurrent
# "already exists" saves.
- name: Cache mcpp sandbox
uses: actions/cache@v4
with:
path: ~/.mcpp
key: mcpp-sandbox-${{ runner.os }}-ci-${{ hashFiles('mcpp.toml', '.xlings.json') }}
restore-keys: |
mcpp-sandbox-${{ runner.os }}-ci-
- name: Cache xlings
uses: actions/cache@v4
with:
path: ~/.xlings
key: xlings-${{ runner.os }}-v2-${{ hashFiles('.xlings.json') }}
restore-keys: |
xlings-${{ runner.os }}-v2-
- name: Bootstrap mcpp via xlings
env:
XLINGS_NON_INTERACTIVE: '1'
XLINGS_VERSION: '0.4.30'
run: |
tarball="xlings-${XLINGS_VERSION}-linux-x86_64.tar.gz"
curl -fsSL -o "/tmp/${tarball}" \
"https://github.com/d2learn/xlings/releases/download/v${XLINGS_VERSION}/${tarball}"
tar -xzf "/tmp/${tarball}" -C /tmp
"/tmp/xlings-${XLINGS_VERSION}-linux-x86_64/subos/default/bin/xlings" self install
export PATH="$HOME/.xlings/subos/default/bin:$PATH"
xlings --version
xlings install mcpp -y
MCPP="$HOME/.xlings/subos/default/bin/mcpp"
test -x "$MCPP"
"$MCPP" --version
echo "MCPP=$MCPP" >> "$GITHUB_ENV"
echo "XLINGS_BIN=$HOME/.xlings/subos/default/bin/xlings" >> "$GITHUB_ENV"
- name: Cache target/ (build artifacts + BMIs)
uses: actions/cache@v4
with:
path: target
key: mcpp-target-${{ runner.os }}-${{ hashFiles('src/**', 'tests/**', 'mcpp.toml', 'mcpp.lock') }}
restore-keys: |
mcpp-target-${{ runner.os }}-
- name: Configure mirror + Build mcpp from source (self-host)
run: |
export MCPP_VENDORED_XLINGS="$XLINGS_BIN"
"$XLINGS_BIN" config --mirror GLOBAL 2>/dev/null || true
"$MCPP" self config --mirror GLOBAL 2>/dev/null || true
"$MCPP" build
- name: E2E suite
# Per-test 600s timeout lives in tests/e2e/run_all.sh and identifies
# WHICH test hung; this caps the whole suite so a hang fails fast.
timeout-minutes: 25
run: |
# Point the e2e runner at the freshly-built binary, not the
# bootstrap one. Tests cd into mktemp -d, so $MCPP must be
# absolute or the relative path breaks under the temp cwd.
MCPP=$(realpath "$(find target -type f -name mcpp -printf '%T@ %p\n' | sort -rn | head -1 | cut -d' ' -f2)")
test -x "$MCPP"
export MCPP
# Tests that set MCPP_HOME to a fresh tmpdir need an xlings to
# bootstrap from; surface the xlings binary installed above.
export MCPP_VENDORED_XLINGS="$XLINGS_BIN"
test -x "$MCPP_VENDORED_XLINGS"
# GitHub-hosted runners are outside CN; keep CI toolchain downloads on
# the global mirror while mcpp's default remains CN for fresh local
# sandboxes. E2E tests with their own MCPP_HOME read this variable.
export MCPP_E2E_TOOLCHAIN_MIRROR=GLOBAL
"$MCPP" self config --mirror "$MCPP_E2E_TOOLCHAIN_MIRROR"
"$MCPP" self config
# Pin the global default so test 28 (default-toolchain path) gets a
# deterministic GNU answer instead of an auto-install pick.
"$MCPP" toolchain default gcc@16.1.0
# Warm musl once so fresh-home e2e tests inherit the payload.
"$MCPP" toolchain install gcc 15.1.0-musl
bash tests/e2e/run_all.sh
# ──────────────────────────────────────────────────────────────────
# Hermetic (no host toolchain): the ONLY environment class that
# faithfully reproduces issue #195. Standard runners ship gcc +
# libc6-dev, so a sandbox toolchain that leaks to the host's CRT
# still links "green" there; this container has no compiler and no
# host Scrt1.o, so any leak fails loudly. Builds PR code with the
# bootstrap mcpp, then runs the llvm flow end-to-end.
# ──────────────────────────────────────────────────────────────────
hermetic:
name: hermetic e2e (no host toolchain, container)
runs-on: ubuntu-24.04
container: debian:stable-slim
timeout-minutes: 60
env:
XLINGS_NON_INTERACTIVE: '1'
steps:
- name: Install base utilities (NO compiler)
run: |
apt-get update -qq
apt-get install -y -qq curl ca-certificates git xz-utils unzip
# The whole point of this job: no host toolchain, no host CRT.
! command -v gcc
! command -v cc
test ! -e /usr/lib/x86_64-linux-gnu/Scrt1.o
test ! -e /usr/lib/gcc
- uses: actions/checkout@v4
# Payload cache (downloads only — the container still has no host
# toolchain, which is the property under test).
- name: Cache mcpp sandbox payloads
uses: actions/cache@v4
with:
path: ~/.mcpp
key: mcpp-hermetic-${{ hashFiles('mcpp.toml') }}
restore-keys: |
mcpp-hermetic-
- name: Bootstrap xlings + released mcpp
run: |
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash -s v0.4.62
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
xlings update
xlings install mcpp -y -g
MCPP_BOOT="$HOME/.xlings/subos/current/bin/mcpp"
"$MCPP_BOOT" --version
"$MCPP_BOOT" self config --mirror GLOBAL
echo "MCPP_BOOT=$MCPP_BOOT" >> "$GITHUB_ENV"
- name: Build PR mcpp from source (sandbox gcc only)
run: |
"$MCPP_BOOT" build
MCPP=$(realpath "$(find target -type f -name mcpp -printf '%T@ %p\n' | sort -rn | head -1 | cut -d' ' -f2)")
test -x "$MCPP"
"$MCPP" --version
echo "MCPP=$MCPP" >> "$GITHUB_ENV"
- name: "issue #195 reproduction: manifest llvm toolchain, fresh"
run: |
cd "$(mktemp -d)"
"$MCPP" new hello195
cd hello195
printf '\n[toolchain]\nlinux = "llvm@22.1.8"\n' >> mcpp.toml
printf 'import std;\nint main() { std::println("hello {}", 195); return 0; }\n' > src/main.cpp
"$MCPP" run
- name: Hermetic llvm e2e subset
run: |
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
export MCPP
bash tests/e2e/86_llvm_hermetic_link.sh
bash tests/e2e/37_llvm_import_std.sh