-
Notifications
You must be signed in to change notification settings - Fork 4
146 lines (133 loc) · 6.02 KB
/
ci.yml
File metadata and controls
146 lines (133 loc) · 6.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
name: ci
# Self-host CI: 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.
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
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: Self-host smoke (freshly-built mcpp builds itself again)
run: |
MCPP=$(realpath "$(find target -type f -name mcpp -printf '%T@ %p\n' | sort -rn | head -1 | cut -d' ' -f2)")
"$MCPP" build
"$MCPP" test
- name: Fresh user experience (xlings install mcpp → new → run)
continue-on-error: true
run: |
# Test real user flow with xlings-distributed mcpp.
# May fail if xlings mcpp version lacks recent fixes.
TMP=$(mktemp -d)
cd "$TMP"
"$MCPP" new hello
cd hello
"$MCPP" run