GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — mcpp/.github/workflows/ci-aarch64-fresh-install.yml at main · mcpp-community/mcpp 407 lines (392 loc) · 20.7 KB / Copy pathci-aarch64-fresh-install.ymlFile metadata and controls407 lines (392 loc) · 20.7 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 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 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: inputs: xim_pkgindex_ref: description: 'Candidate xim-pkgindex SHA or branch; empty runs ordinary released fresh-install' type: string required: false default: '' mcpp_run_id: description: 'CI run with a successful native build of exactly this dispatched mcpp head' type: string required: false default: '' schedule: - cron: '0 6 * * 1' # weekly Mon 06:00 UTC pull_request: branches: [ main ] paths: - 'src/build/build_program.cppm' - 'src/run/run.cpp' - '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 actions: read concurrency: group: ci-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: fresh-install: if: github.event_name != 'workflow_dispatch' || inputs.xim_pkgindex_ref == '' 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" # A bare `git clone` here fails the whole job on a runner DNS # hiccup. The policy lives in .github/tools/git_clone_retry.sh — # but this job checks the repository out LAST ON PURPOSE (a # `.xlings.json` in the workspace re-points where `xlings install` # writes, so an early checkout silently changes what the # fresh-install steps above are testing). The helper therefore does # not exist on disk yet, and the retry is spelled inline. Same # policy: retry every failure, bounded, git's own message survives. clone_retry() { local rc dest="${@: -1}" for i in 1 2 3 4; do rc=0; git clone "$@" || rc=$? [ "$rc" = 0 ] && return 0 [ "$i" = 4 ] && return "$rc" [ -e "$dest" ] && rm -rf -- "$dest" echo "clone_retry: attempt $i failed (exit $rc); retrying" >&2 sleep $((i * 5)) done } clone_retry --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" # The clone's .xlings.json declares `workspace.mcpp` — the BOOTSTRAP # pin, hand-maintained and deliberately lagging the newest release. # It is scoped to the working directory and beats anything installed, # so every `mcpp` below resolved the bootstrap version, which the # fresh-install steps above never installed: # # [error] xlings: version '2026.8.6.2' not found for 'mcpp' # [error] available: 2026.8.8.2 # # "newest release != bootstrap pin" is the NORMAL state, so this step # failed on every run from the moment the two diverged — and it is # weekly, so nothing pointed at it. This step tests the freshly # installed RELEASED binary against a source tree; the bootstrap pin # has no standing in that question. install_released_mcpp.sh removes # it for exactly this reason on the x86_64 legs (its point 1); this # leg was written separately and never got it. rm -f .xlings.json mcpp self config --mirror GLOBAL 2>/dev/null || true # Two compiles at a time: the runner (4 vCPU, 16 GB) received a # shutdown signal twice at 656/689, with four of the engine's largest # module units compiling at once with debug information # (2026-10-28). The build is the same; only its width is not. MCPP_JOBS=2 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 # 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. # # Resolved HERE, before the cd below, and that placement is load- # bearing: `mcpp` is the shim, so it obeys whatever workspace pin the # CURRENT DIRECTORY carries — and the xlings checkout declares one too # (`workspace.mcpp = 2026.8.6.1`, its own bootstrap). Run from there, # this resolves a version nothing installed, MCPP_HOME comes back # empty, and the step dies on the guard below instead of on the real # cause. /tmp/mcpp-src has had its pin removed above, so ask from here. 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; } # Same inline retry as the index clone above, and for the same # reason — the checkout that would provide the shared helper is # deliberately the last step in this job. clone_retry() { local rc dest="${@: -1}" for i in 1 2 3 4; do rc=0; git clone "$@" || rc=$? [ "$rc" = 0 ] && return 0 [ "$i" = 4 ] && return "$rc" [ -e "$dest" ] && rm -rf -- "$dest" echo "clone_retry: attempt $i failed (exit $rc); retrying" >&2 sleep $((i * 5)) done } clone_retry --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. "$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: | # Third site of the same pin, and the reason to remove it here too: # this job installs `xlings install mcpp` (bare = latest) and NOTHING # else, so the bootstrap version the checkout pins is never on this # runner. Obeying the pin here does not select an older builder — it # selects one that does not exist. Same removal as the self-host step # above, same reason as install_released_mcpp.sh point 1. rm -f .xlings.json # Two compiles at a time, for the reason of the self-host step above. MCPP_JOBS=2 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 candidate-admission: name: candidate index + current mcpp native admission if: github.event_name == 'workflow_dispatch' && inputs.xim_pkgindex_ref != '' runs-on: ubuntu-24.04-arm timeout-minutes: 90 defaults: run: shell: bash env: XLINGS_NON_INTERACTIVE: '1' MCPP_E2E_MIRROR: GLOBAL MCPP_NATIVE_XIM_INDEX: ${{ github.workspace }}/_candidate-xim steps: - uses: actions/checkout@v4 - uses: actions/checkout@v4 with: repository: openxlings/xim-pkgindex ref: ${{ inputs.xim_pkgindex_ref }} path: _candidate-xim - name: Candidate admission contracts run: | echo "MCPP_NATIVE_REPORT_DIR=$RUNNER_TEMP/native-llvm-arm64" >> "$GITHUB_ENV" python3 tests/scripts/test_native_candidate_admission.py - name: Verify and download this head's successful native mcpp build env: GH_TOKEN: ${{ github.token }} MCPP_SOURCE_RUN: ${{ inputs.mcpp_run_id }} run: python3 .github/tools/download_native_admission_mcpp.py "$MCPP_SOURCE_RUN" "$RUNNER_TEMP/mcpp-built" - uses: ./.github/actions/bootstrap-mcpp - name: Seed the candidate index before installing the native runtime run: | set -euo pipefail mkdir -p "$MCPP_NATIVE_REPORT_DIR" git -C "$MCPP_NATIVE_XIM_INDEX" rev-parse HEAD | tee "$MCPP_NATIVE_REPORT_DIR/xim-commit.txt" printf '%s\n' "$GITHUB_SHA" > "$MCPP_NATIVE_REPORT_DIR/mcpp-commit.txt" python3 .github/tools/seed_native_xim_index.py "$HOME/.mcpp" "$MCPP_NATIVE_XIM_INDEX" echo "MCPP_HOME=$HOME/.mcpp" >> "$GITHUB_ENV" "$XLINGS_BIN" --version - name: Use this head's mcpp against the candidate runtime run: bash .github/actions/use-built-mcpp/use.sh linux-aarch64 GLOBAL - name: Install, build, run and pack the native GNU default with candidate recipes env: MCPP: ${{ env.MCPP_FRESH }} run: | set -euo pipefail bash .github/tools/check_aarch64_llvm_payload.sh 2>&1 | tee "$RUNNER_TEMP/native-llvm-arm64/admission.log" grep -qF 'PASS: native ARM64 LLVM installs, builds and runs' "$RUNNER_TEMP/native-llvm-arm64/admission.log" - name: GNU self-host with LLVM 23.1.3 on native ARM64 run: | set -euo pipefail python3 .github/tools/seed_native_xim_index.py --verify "$MCPP_HOME" "$MCPP_NATIVE_XIM_INDEX" marker="$MCPP_NATIVE_REPORT_DIR/gnu-build-start" touch "$marker" "$MCPP_FRESH" build --toolchain [email protected] --target aarch64-linux-gnu 2>&1 | tee "$MCPP_NATIVE_REPORT_DIR/gnu-selfhost.log" mapfile -t binaries < <(find "$GITHUB_WORKSPACE/target/aarch64-linux-gnu" -type f -path '*/bin/mcpp' -newer "$marker") [ "${#binaries[@]}" = 1 ] || { echo "expected one newly built GNU mcpp, found ${#binaries[@]}"; exit 1; } gnu=$(realpath "${binaries[0]}") readelf -hW "$gnu" | tee "$MCPP_NATIVE_REPORT_DIR/gnu-mcpp-header.txt" grep -q 'Machine:.*AArch64' "$MCPP_NATIVE_REPORT_DIR/gnu-mcpp-header.txt" readelf -lW "$gnu" | tee "$MCPP_NATIVE_REPORT_DIR/gnu-mcpp-program-headers.txt" python3 - "$MCPP_HOME" "$MCPP_NATIVE_REPORT_DIR/gnu-mcpp-program-headers.txt" <<'PY' import pathlib, re, sys home = pathlib.Path(sys.argv[1]).resolve() text = pathlib.Path(sys.argv[2]).read_text() match = re.search(r'Requesting program interpreter: ([^\]]+)', text) assert match, text loader = pathlib.Path(match.group(1)).resolve() loader.relative_to(home / 'registry/data/xpkgs/xim-x-glibc') assert loader.name == 'ld-linux-aarch64.so.1', loader PY "$gnu" --version | tee "$MCPP_NATIVE_REPORT_DIR/gnu-mcpp-version.txt" printf '%s\n' "$gnu" > "$MCPP_NATIVE_REPORT_DIR/gnu-mcpp-binary.txt" echo "MCPP_NATIVE_GNU=$gnu" >> "$GITHUB_ENV" - name: The GNU self-host runs the complete native unit and integration suite run: | set -euo pipefail "$MCPP_NATIVE_GNU" test --toolchain [email protected] --target aarch64-linux-gnu 2>&1 | tee "$MCPP_NATIVE_REPORT_DIR/gnu-tests.log" - name: Preserve native ELF and link evidence when the suite fails if: failure() run: | set -euo pipefail evidence="$MCPP_NATIVE_REPORT_DIR/native-link-evidence" mkdir -p "$evidence" while IFS= read -r -d '' binary; do relative="${binary#target/}" mkdir -p "$evidence/$(dirname "$relative")" cp "$binary" "$evidence/$relative" readelf -aW "$binary" > "$evidence/$relative.readelf.txt" done < <(find target/aarch64-linux-gnu -type f -path '*/bin/unit' -print0) while IFS= read -r -d '' plan; do relative="${plan#target/}" mkdir -p "$evidence/$(dirname "$relative")" cp "$plan" "$evidence/$relative" done < <(find target/aarch64-linux-gnu -type f -name build.ninja -print0) - name: GNU mcpp builds the LLVM path host helper (804 LLVM case only) env: MCPP: ${{ env.MCPP_NATIVE_GNU }} MCPP_E2E_804_LLVM_HOST_ONLY: '1' run: | set -euo pipefail bash tests/e2e/804_a_path_host_tool_builds_with_its_chosen_toolchain.sh 2>&1 | tee "$MCPP_NATIVE_REPORT_DIR/gnu-llvm-host-helper.log" grep -qF 'PASS: 804 native LLVM path host helper (LLVM case only)' "$MCPP_NATIVE_REPORT_DIR/gnu-llvm-host-helper.log" - uses: actions/checkout@v4 with: repository: mcpp-community/mcpp-index ref: main path: _native-mcpp-index - name: Four real index members consume the native LLVM GNU ecosystem run: | set -euo pipefail git -C _native-mcpp-index rev-parse HEAD | tee "$MCPP_NATIVE_REPORT_DIR/mcpp-index-commit.txt" python3 .github/tools/seed_native_xim_index.py --verify "$MCPP_HOME" "$MCPP_NATIVE_XIM_INDEX" adapter="$RUNNER_TEMP/mcpp-llvm-gnu-consumer" cat > "$adapter" <<'SH' #!/usr/bin/env bash set -euo pipefail case "${1:-}" in build|test|run) set -- "$@" --toolchain [email protected] --target aarch64-linux-gnu ;; esac { printf 'GNU consumer argv:'; printf ' %q' "$@"; printf '\n'; } >> "$MCPP_NATIVE_REPORT_DIR/index-consumer-argv.log" exec "$MCPP_NATIVE_GNU" "$@" SH chmod +x "$adapter" cd _native-mcpp-index MCPP="$adapter" MCPP_VERBOSE=1 MCPP_TIMINGS="$MCPP_NATIVE_REPORT_DIR/index-members.tsv" \ bash tests/run_members.sh cjson sqlite3 fmtlib.fmt nlohmann.json 2>&1 | tee "$MCPP_NATIVE_REPORT_DIR/index-members.log" python3 - "$MCPP_NATIVE_REPORT_DIR/index-members.tsv" <<'PY' import pathlib, sys rows = [line.split('\t') for line in pathlib.Path(sys.argv[1]).read_text().splitlines()] assert len(rows) == 4, rows assert {row[1] for row in rows} == {'cjson', 'sqlite3', 'fmtlib.fmt', 'nlohmann.json'}, rows assert all(row[2] == 'ok' for row in rows), rows PY - name: The real openkal stack runs as native ARM64 without skipping env: MCPP: ${{ env.MCPP_NATIVE_GNU }} MCPP_E2E_EXPECT_ARCH: aarch64 run: | set -euo pipefail export MCPP_OPENKAL_INDEX="$GITHUB_WORKSPACE/_native-mcpp-index" bash tests/e2e/286_the_openkal_stack_still_builds.sh 2>&1 | tee "$RUNNER_TEMP/native-llvm-arm64/openkal.log" ! grep -q '^SKIP:' "$RUNNER_TEMP/native-llvm-arm64/openkal.log" grep -qF 'OK: the openkal stack builds, links statically and runs' "$RUNNER_TEMP/native-llvm-arm64/openkal.log" grep -qxF 'openkal hosted threads: isolation, destructors and concurrent unwind ok' "$RUNNER_TEMP/native-llvm-arm64/openkal.log" grep -qxF 'openkal indexed JSON: dump, parse, literals and ordered_json ok' "$RUNNER_TEMP/native-llvm-arm64/openkal.log" - uses: actions/upload-artifact@v4 if: always() with: name: candidate-native-ecosystem-admission path: ${{ runner.temp }}/native-llvm-arm64 if-no-files-found: warn |
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |