-
Notifications
You must be signed in to change notification settings - Fork 12
173 lines (159 loc) · 8.05 KB
/
Copy pathci-aarch64-fresh-install.yml
File metadata and controls
173 lines (159 loc) · 8.05 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
name: ci-aarch64-fresh-install
# End-to-end "fresh install" of the whole ecosystem on a NATIVE aarch64 host,
# exactly as a new aarch64-Linux / Termux(-proot) user would:
#
# curl quick_install.sh | bash -> installs aarch64 xlings (static musl)
# xlings install mcpp -> installs aarch64 mcpp (static musl)
# mcpp new / build / run -> NATIVE aarch64 build (pulls the native
# musl-gcc toolchain from the ecosystem)
#
# Validates that every published aarch64 asset (xlings, mcpp, musl-gcc) lines
# up and that mcpp can build & run a real `import std` program natively on
# aarch64 — no cross, no qemu. Runs on GitHub's native ARM64 runner.
on:
workflow_dispatch:
schedule:
- cron: '0 6 * * 1' # weekly Mon 06:00 UTC
pull_request:
branches: [ main ]
paths:
- 'src/build/build_program.cppm'
- 'src/platform/process.cppm'
- 'tests/e2e/168_build_mcpp_musl_host_static.sh'
- '.github/workflows/ci-aarch64-fresh-install.yml'
push:
branches: [ main ]
paths:
- '.github/workflows/ci-aarch64-fresh-install.yml'
permissions:
contents: read
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
fresh-install:
name: fresh install + native build (aarch64 / glibc)
runs-on: ubuntu-24.04-arm
timeout-minutes: 60
env:
# Verbose every mcpp invocation — cold bootstrap path (src/cli.cppm).
MCPP_VERBOSE: "1"
steps:
# NB: the checkout deliberately comes LAST, after every fresh-install
# step below — see the comment above it.
- name: System info
run: |
uname -a
echo "arch: $(uname -m)" # aarch64 on this runner
- name: Fresh-install xlings (curl | bash)
env:
XLINGS_NON_INTERACTIVE: '1'
run: |
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash
echo "$HOME/.xlings/subos/current/bin" >> "$GITHUB_PATH"
echo "$HOME/.xlings/bin" >> "$GITHUB_PATH"
- name: Verify xlings + GLOBAL mirror
run: |
xlings --version
xlings config --mirror GLOBAL 2>/dev/null || true
xlings update -y 2>/dev/null || xlings update 2>/dev/null || true
- name: Fresh-install mcpp via xlings
run: |
xlings install mcpp -y
mcpp --version
mcpp self config --mirror GLOBAL 2>/dev/null || true
- name: Refresh mcpp package index (force latest xim-pkgindex)
run: |
# mcpp seeds a baseline index with a freshness TTL marker, so a plain
# `index update` can no-op within the window. Force the latest index
# so this run validates the native build against current packages.
mcpp index update || true
idx="$HOME/.mcpp/registry/data/xim-pkgindex"
rm -rf "$idx"
git clone --depth 1 https://github.com/openxlings/xim-pkgindex "$idx"
grep -n "skipping relocation\|os.isfile(path.join(bindir" "$idx/pkgs/m/musl-gcc.lua" | head -2 || true
- name: Native build + run an `import std` program
run: |
work=$(mktemp -d); cd "$work"
mcpp new hello
cd hello
# default src uses import std (C++23)
mcpp build
out=$(mcpp run 2>/dev/null || true)
echo "program output: $out"
bin=$(find target -type f -path '*/bin/hello' | head -1)
file "$bin"
file "$bin" | grep -q "ARM aarch64" || { echo "expected aarch64 ELF"; exit 1; }
- name: Self-host — build mcpp + xlings from source natively
run: |
# mcpp/xlings manifests pin a glibc default toolchain; on aarch64 the
# musl-static target is the published path, so build with --target.
#
# On a pull_request, self-host the code UNDER REVIEW rather than
# upstream main. Cloning main meant this gate never saw the PR at
# all: a change that breaks the from-source build passed here and
# only failed after merge, and — the way this surfaced — a fix to
# the repo's own bootstrap pin was untestable, because the fix was
# on the branch while the clone was of main. Outside a PR there is
# no head ref and main is exactly right.
ref='${{ github.event.pull_request.head.sha }}'
repo='${{ github.event.pull_request.head.repo.clone_url }}'
[ -n "$ref" ] || ref='${{ github.sha }}'
[ -n "$repo" ] || repo='https://github.com/mcpp-community/mcpp'
# fetch-by-sha rather than `clone --depth 1`, which cannot take one.
git init -q /tmp/mcpp-src
cd /tmp/mcpp-src
git remote add origin "$repo"
git fetch -q --depth 1 origin "$ref"
git checkout -q FETCH_HEAD
echo "self-hosting $repo @ $ref"
mcpp self config --mirror GLOBAL 2>/dev/null || true
mcpp build --target aarch64-linux-musl
# Absolute: it is used again after `cd /tmp/xlings-src` below.
m=$(find "$PWD/target/aarch64-linux-musl" -type f -path '*/bin/mcpp' | head -1)
file "$m" | grep -q "ARM aarch64" || { echo "expected aarch64 mcpp"; exit 1; }
"$m" --version
git clone --depth 1 https://github.com/openxlings/xlings /tmp/xlings-src
cd /tmp/xlings-src
# "$m", not `mcpp`: the just-built binary is the code under review,
# and building xlings with the INSTALLED one meant this half of the
# gate never saw the PR — the same defect the clone-ref comment above
# records, one line further down. It surfaced the same way: a fix for
# an aarch64-only failure in exactly this build could not be
# validated here, because the binary running it predated the fix.
#
# MCPP_HOME must be carried over explicitly: mcpp derives it from the
# BINARY's location, so a binary sitting in /tmp/mcpp-src/target would
# otherwise adopt an empty home and re-bootstrap the whole ecosystem
# instead of reusing what the fresh-install steps above provisioned.
export MCPP_HOME=$(mcpp self env | awk -F'= *' '/^MCPP_HOME/{print $2; exit}')
echo "reusing MCPP_HOME=$MCPP_HOME"
test -d "$MCPP_HOME" || { echo "could not determine MCPP_HOME"; exit 1; }
"$m" build --target aarch64-linux-musl
x=$(find target/aarch64-linux-musl -type f -path '*/bin/xlings' | head -1)
file "$x" | grep -q "ARM aarch64" || { echo "expected aarch64 xlings"; exit 1; }
"$x" --version
# ── PR regression gate ────────────────────────────────────────────────
# Everything above is the fresh-install charter: it must run exactly as a
# new user's machine does. Check out only NOW — this repo's .xlings.json
# declares an `mcpp` WORKSPACE pin, so with the checkout present in
# $GITHUB_WORKSPACE `xlings install mcpp` installs workspace-scoped
# instead of globally: the steps above would silently validate the pinned
# version rather than the freshly published one, and bare `mcpp` stops
# resolving anywhere outside the workspace.
- uses: actions/checkout@v4
with:
persist-credentials: false
# The PR's own source, then the musl host-helper regression against it.
# This is the only runner where a musl toolchain is the NATIVE one, so it
# is the only place #295 can actually be reproduced.
- name: Build current mcpp source for native regression tests
run: |
mcpp build --target aarch64-linux-musl
self=$(find target/aarch64-linux-musl -type f -path '*/bin/mcpp' | head -1)
test -x "$self"
self=$(realpath "$self")
"$self" --version
echo "MCPP_SELF=$self" >> "$GITHUB_ENV"
- name: "Regression: build.mcpp host helper is self-contained (#295)"
run: MCPP="$MCPP_SELF" bash tests/e2e/168_build_mcpp_musl_host_static.sh