-
Notifications
You must be signed in to change notification settings - Fork 5
164 lines (149 loc) · 7.02 KB
/
ci-linux.yml
File metadata and controls
164 lines (149 loc) · 7.02 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
name: ci-linux
# Self-host CI on Linux: mcpp builds mcpp. The bootstrap mcpp comes from
# `xlings install mcpp` (xim:mcpp in the xlings package index), so this
# workflow no longer depends on a previous-release tarball — the
# chicken-and-egg now lives upstream in the xlings index.
#
# Paired workflows: 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:
build-and-test:
name: build + test (linux x86_64, self-host)
runs-on: ubuntu-24.04
timeout-minutes: 60
env:
# MCPP_HOME pinned so the cache key below restores into the
# same path mcpp resolves at runtime.
MCPP_HOME: /home/runner/.mcpp
steps:
- uses: actions/checkout@v4
# Cache mcpp's sandbox: the toolchain (musl-gcc + binutils +
# glibc + linux-headers + patchelf + ninja) takes minutes to
# install on a cold runner. Key on the workspace manifest so a
# toolchain change in mcpp.toml refreshes the cache; restore-keys
# provide a layered fallback so near-misses still skip the slow
# toolchain installs.
- name: Cache mcpp sandbox
uses: actions/cache@v4
with:
path: ~/.mcpp
key: mcpp-sandbox-${{ runner.os }}-${{ hashFiles('mcpp.toml', '.xlings.json') }}
restore-keys: |
mcpp-sandbox-${{ runner.os }}-
# Cache xlings + its locally installed packages (xim:mcpp etc.).
# Saves the xlings bootstrap roundtrip + the mcpp xpkg download
# on hot runs.
- 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: |
# Always install the pinned version — cache may hold an older
# xlings whose sysroot/packages are incompatible.
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
# xim:mcpp — `xlings install` is idempotent so cache hits skip
# the download.
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"
# Cache the build directory: precise key on src/ + manifest
# so a no-source-change run lands on a full hit. Layered
# restore-keys let mid-run partial hits keep BMI/dyndep state
# for proper incremental builds.
- 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"
# Set GLOBAL mirror via xlings directly (bootstrap mcpp may lack --mirror flag)
"$XLINGS_BIN" config --mirror GLOBAL 2>/dev/null || true
"$MCPP" self config --mirror GLOBAL 2>/dev/null || true
"$MCPP" build
- name: Unit + integration tests via `mcpp test`
run: |
# Use freshly-built mcpp for test (it has --mirror support)
MCPP_FRESH=$(realpath "$(find target -type f -name mcpp -printf '%T@ %p\n' | sort -rn | head -1 | cut -d' ' -f2)")
"$MCPP_FRESH" self config --mirror GLOBAL
"$MCPP_FRESH" test
- name: E2E suite
# Step-level guard: a single hung test (historically 10_env_command.sh
# on slow xlings/network) used to eat the full 60-min job budget.
# Cap the suite at 25 min so a hang fails fast and we still have room
# for the downstream toolchain steps. Per-test 600s timeout lives in
# tests/e2e/run_all.sh and identifies WHICH test hung.
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 so they don't have to reinstall the sandbox.
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 (which exercises the
# default-toolchain path) gets a deterministic GNU answer
# instead of whatever auto-install picks on a fresh sandbox.
"$MCPP" toolchain default gcc@16.1.0
bash tests/e2e/run_all.sh
- name: Save freshly-built mcpp for toolchain tests
run: |
MCPP=$(realpath "$(find target -type f -name mcpp -printf '%T@ %p\n' | sort -rn | head -1 | cut -d' ' -f2)")
cp "$MCPP" /tmp/mcpp-fresh
echo "MCPP=/tmp/mcpp-fresh" >> "$GITHUB_ENV"
- name: "Toolchain: GCC — build mcpp + test"
run: |
"$MCPP" clean
"$MCPP" build 2>&1 | tee build.log; grep -q "Resolved gcc@16.1.0" build.log
"$MCPP" test
- name: "Toolchain: musl-gcc — build mcpp (--target)"
run: |
"$MCPP" clean
"$MCPP" build --target x86_64-linux-musl 2>&1 | tee build.log; grep -q "Resolved gcc@15.1.0-musl" build.log
- name: "Toolchain: LLVM — build mcpp"
run: |
"$MCPP" toolchain install llvm 20.1.7
# Override project toolchain to use LLVM for this build
sed -i 's/^default = "gcc@16.1.0"/default = "llvm@20.1.7"/' mcpp.toml
"$MCPP" clean
"$MCPP" build 2>&1 | tee build.log; grep -q "Resolved llvm@20.1.7" build.log
# Restore
sed -i 's/^default = "llvm@20.1.7"/default = "gcc@16.1.0"/' mcpp.toml