Skip to content

fix: make the build.mcpp host helper self-contained on musl and MinGW… #20

fix: make the build.mcpp host helper self-contained on musl and MinGW…

fix: make the build.mcpp host helper self-contained on musl and MinGW… #20

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.
git clone --depth 1 https://github.com/mcpp-community/mcpp /tmp/mcpp-src
cd /tmp/mcpp-src
mcpp self config --mirror GLOBAL 2>/dev/null || true
mcpp build --target aarch64-linux-musl
m=$(find 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
mcpp 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