probe(do-not-merge): capture the Windows exit-127 at compat:ffmpeg #421
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: validate | |
| on: | |
| pull_request: | |
| paths: ["pkgs/**/*.lua", "tests/**", "README.md", ".github/workflows/validate.yml"] | |
| push: | |
| branches: [main] | |
| schedule: | |
| # nightly full regression — exercises every workspace member regardless of diff | |
| - cron: "0 6 * * *" | |
| workflow_dispatch: | |
| env: | |
| # 0.0.106: SPEC-001 package identity (mcpp#280). `package.name` is a SINGLE | |
| # ATOMIC SEGMENT — all hierarchy lives in `package.namespace` — and mcpp | |
| # addresses a package by the LITERAL name it read, so descriptors no longer | |
| # repeat their namespace inside `name`. This index is migrated to the short | |
| # form, which is why min_mcpp/latest_mcpp move in lock-step: an older client | |
| # re-derives `<ns>.<short>`, misses, and reports a bare E_NOT_FOUND. Bundles | |
| # xlings 0.4.69, which keys its index by (namespace, name) so two packages | |
| # sharing a short name in one index are both addressable (xlings#381) — this | |
| # index now has three such pairs (imgui / ffmpeg / lua under compat vs the | |
| # default namespace). | |
| # 0.0.102: windows command-line ceiling (mcpp#261 — the clang scan rule got | |
| # its P1689 JSON through shell redirection, which forced a `cmd /c` wrapper | |
| # and with it cmd.exe's 8191-char limit; clang-scan-deps -o removes both, and | |
| # $local_includes-carrying rules now fall back to response files). The pin | |
| # matters here because a package consumed FROM the registry sits under a | |
| # ~124-char xpkgs path instead of its own ~23-char checkout, which is what | |
| # pushed the vendored-opencv scan command over the line. Also: purview-include | |
| # depfile tracking extended to Clang (#257 — stale BMI reuse), OS-conditional | |
| # `[build].flags` (#258), and per-OS splices keyed on the resolved target | |
| # rather than the host (#254). | |
| # 0.0.101: per-feature per-glob flags + per-OS features (mcpp#253) — what | |
| # lets opencv select its dnn gemm backend per platform. | |
| # 0.0.99: feature dep/feat forwarding (mcpp#243 — a feature can open a | |
| # feature OF a dependency, e.g. opencv `dnn` forwarding compat.opencv/dnn); | |
| # vendored xlings 0.4.67 for the >=2 index_repo install fix (mcpp#238 / | |
| # openxlings/xlings#374); build.mcpp compiled program named `.exe` on | |
| # Windows (mcpp#230 secondary surface, after the 0.0.96 scanner crash fix). | |
| # 0.0.98: closes the obj-path disambiguation follow-ups that gated the | |
| # source-build compat.opencv unification — #240 (link inputs now follow | |
| # the disambiguated object names, so a dependency + consumer sharing a | |
| # source basename like `src/main.cpp` no longer 'obj/main.o missing') and | |
| # #239 (absolute/`..` dep-generated source paths sanitized component-wise | |
| # so objects stay under obj/). Also: `MCPP_DEP_<NAME>_DIR` build.mcpp | |
| # contract (#241), consumer-side `default-features = false` (#242), and a | |
| # loud unknown-mcpp-key warning with did-you-mean (#237, replaces the | |
| # silent-ignore at build time). Carried from 0.0.97: default-namespace | |
| # index redirect (`[indices] default = { path }`), which turned the public | |
| # module packages (imgui/ffmpeg/opencv/tinyhttps) into ordinary workspace | |
| # members and retired the per-package reseeding smoke shells + their | |
| # dedicated jobs; synchronous nasm bootstrap (mcpp#232 — the `mcpp index | |
| # update` pre-step is gone), obj-path disambiguation (#233), spacey-defines | |
| # quoting (#234), purview-include depfile tracking (#235). Older floors of | |
| # note: 0.0.96 fixed the windows scanner symlink-escape crash (mcpp#230); | |
| # 0.0.94 fixed feature-gated `sources` under `mcpp test` (mcpp#218); 0.0.91 | |
| # added standard = "c++fly" to the resolver grammar, so c++fly descriptors | |
| # get the lint WARN below, not a hard grammar-parse rejection. | |
| MCPP_VERSION: "0.0.107" | |
| jobs: | |
| workspace: | |
| name: workspace (${{ matrix.platform }}) | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 150 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # PROBE: only Windows, and pinned to the instrumented debug build | |
| # published by mcpp's debug-win workflow (branch | |
| # debug/win127-instrumentation, prerelease tag v0.0.107-dbg). | |
| - platform: windows | |
| os: windows-latest | |
| suffix: windows-x86_64 | |
| ext: zip | |
| mcpp: bin/mcpp.exe | |
| xlings: registry/bin/xlings.exe | |
| mcpp_version: "0.0.107-dbg" | |
| env: | |
| MCPP_EFFECTIVE: ${{ matrix.mcpp_version }} | |
| steps: | |
| # Full history: the member-selection step below diffs against the PR | |
| # base to decide which workspace members to test. | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Restore mcpp registry cache | |
| uses: actions/cache@v4 | |
| with: | |
| # Holds toolchains AND the built compat packages (data/xpkgs), so a | |
| # repeat `mcpp test` rebuilds little. | |
| path: ~/.mcpp/registry | |
| key: mcpp-registry-${{ runner.os }}-${{ env.MCPP_EFFECTIVE }}-${{ hashFiles('pkgs/**/*.lua', 'tests/**', '.github/workflows/validate.yml') }} | |
| restore-keys: | | |
| mcpp-registry-${{ runner.os }}-${{ env.MCPP_EFFECTIVE }}- | |
| - name: Download mcpp | |
| shell: bash | |
| env: | |
| MCPP_ARCHIVE: mcpp-${{ env.MCPP_EFFECTIVE }}-${{ matrix.suffix }}.${{ matrix.ext }} | |
| MCPP_ROOT: mcpp-${{ env.MCPP_EFFECTIVE }}-${{ matrix.suffix }} | |
| run: | | |
| curl -L -fsS -o "$MCPP_ARCHIVE" \ | |
| "https://github.com/mcpp-community/mcpp/releases/download/v${MCPP_EFFECTIVE}/${MCPP_ARCHIVE}" | |
| case "$MCPP_ARCHIVE" in | |
| *.zip) powershell -NoProfile -Command "Expand-Archive -Force -Path '${MCPP_ARCHIVE}' -DestinationPath '.'" ;; | |
| *) tar -xzf "$MCPP_ARCHIVE" ;; | |
| esac | |
| root="$PWD/$MCPP_ROOT" | |
| mkdir -p "$HOME/.mcpp/registry" | |
| cp -a "$root/registry/." "$HOME/.mcpp/registry/" | |
| if [[ "$RUNNER_OS" == "Windows" ]]; then | |
| echo "MCPP=$(cygpath -m "$root/${{ matrix.mcpp }}")" >> "$GITHUB_ENV" | |
| echo "MCPP_VENDORED_XLINGS=$(cygpath -m "$root/${{ matrix.xlings }}")" >> "$GITHUB_ENV" | |
| echo "$(cygpath -m "$root/bin")" >> "$GITHUB_PATH" | |
| else | |
| echo "MCPP=$root/${{ matrix.mcpp }}" >> "$GITHUB_ENV" | |
| echo "MCPP_VENDORED_XLINGS=$root/${{ matrix.xlings }}" >> "$GITHUB_ENV" | |
| echo "$root/bin" >> "$GITHUB_PATH" | |
| fi | |
| # compat.ffmpeg / compat.opencv5 carry NASM .asm sources. No host | |
| # install and no index-refresh pre-step needed: mcpp >= 0.0.97 | |
| # resolves nasm itself through the same synchronous gate as the | |
| # toolchain (index refresh + install + payload check BEFORE the build | |
| # plans, mcpp#232). The sandbox copy lands in ~/.mcpp/registry, so | |
| # the cache carries it across runs. | |
| # ── Selective member testing ────────────────────────────────────── | |
| # `mcpp test --workspace` builds every member (opencv, ffmpeg, …) and | |
| # dominates CI wall-clock, while a PR almost always touches one | |
| # package. Map changed files → affected members and test only those: | |
| # pkgs/<x>/<lib>.lua → members whose mcpp.toml references <lib> | |
| # tests/examples/<m>/** → member <m> | |
| # Run the FULL workspace when the change can affect everything: | |
| # non-PR events (push to main, the nightly cron, dispatch), this | |
| # workflow file (it carries the mcpp version pins, so a version bump | |
| # always re-validates every package), a non-member edit to the | |
| # workspace manifest, or shared test scripts. Docs-only and tools/-only | |
| # changes select nothing. | |
| # Note: bash 3.2 on macOS runners — no associative arrays here. | |
| - name: Select affected workspace members | |
| shell: bash | |
| run: | | |
| full() { echo "MEMBERS=__ALL__" >> "$GITHUB_ENV"; echo "full run: $1"; exit 0; } | |
| [ "${{ github.event_name }}" = "pull_request" ] || full "event=${{ github.event_name }}" | |
| base="origin/${{ github.base_ref }}" | |
| changed=$(git diff --name-only "$base"...HEAD) | |
| printf 'changed files vs %s:\n%s\n' "$base" "$changed" | |
| sel="" | |
| add() { case " $sel " in *" $1 "*) ;; *) sel="$sel $1" ;; esac; } | |
| while IFS= read -r f; do | |
| [ -n "$f" ] || continue | |
| case "$f" in | |
| .github/workflows/validate.yml|tests/*.sh) full "$f" ;; | |
| mcpp.toml) | |
| # Workspace manifest. Every new-package PR appends to the | |
| # members list, so that alone must NOT force a full run: | |
| # select the added members; anything else in this file | |
| # (indices, settings) affects everyone → full. | |
| if ! diff -q <(git show "$base:mcpp.toml" | grep -v 'tests/examples/') \ | |
| <(grep -v 'tests/examples/' mcpp.toml) >/dev/null; then | |
| full "mcpp.toml non-member change" | |
| fi | |
| for p in $(comm -13 <(git show "$base:mcpp.toml" | grep -o 'tests/examples/[A-Za-z0-9._-]*' | sort -u) \ | |
| <(grep -o 'tests/examples/[A-Za-z0-9._-]*' mcpp.toml | sort -u)); do | |
| add "${p#tests/examples/}" | |
| done ;; | |
| tests/examples/*) | |
| m=${f#tests/examples/}; m=${m%%/*} | |
| # A deleted/renamed member dir implies a mcpp.toml edit, | |
| # which already forces a full run above. | |
| [ -d "tests/examples/$m" ] && add "$m" ;; | |
| pkgs/*.lua|pkgs/*/*.lua) | |
| lib=$(basename "$f" .lua); lib=${lib#compat.} | |
| hit=0 | |
| for mt in tests/examples/*/mcpp.toml; do | |
| if grep -q "$lib" "$mt"; then add "$(basename "$(dirname "$mt")")"; hit=1; fi | |
| done | |
| [ "$hit" = 1 ] || echo "note: no workspace member exercises $f" ;; | |
| # tools/ holds OFFLINE descriptor-generation and publishing | |
| # helpers (tools/compat-*/, tools/gtc/, publish_mcpp_index.sh). | |
| # Nothing under it is consumed by a package build: when one of | |
| # them actually changes a package, the generated pkgs/*.lua | |
| # changes with it and the rule above selects the right members. | |
| # So a tools/ edit alone selects nothing rather than forcing a | |
| # full workspace rebuild. | |
| *.md|docs/*|.agents/*|.github/*|tools/*) : ;; | |
| *) full "unclassified change: $f" ;; | |
| esac | |
| done <<EOF | |
| $changed | |
| EOF | |
| sel=${sel# } | |
| echo "MEMBERS=$sel" >> "$GITHUB_ENV" | |
| echo "selected members: ${sel:-<none>}" | |
| - name: mcpp test (workspace or affected members) | |
| shell: bash | |
| env: | |
| MCPP_INDEX_MIRROR: GLOBAL | |
| run: | | |
| "$MCPP" --version | |
| echo "=== ffmpeg member, instrumented ===" | |
| rc=0 | |
| "$MCPP" test -p tests/examples/ffmpeg 2>&1 | tail -120 || rc=$? | |
| echo "=== ffmpeg member exit status: $rc ===" | |
| exit $rc |