register openkal-windows 0.10.1 #55
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: openkal-compat | |
| # Measures the members listed in tests/openkal/members.toml in an openkal graph | |
| # and records the result the site labels packages by. See docs/openkal-compat.md. | |
| # | |
| # It does not gate pull requests that touch other descriptors: openkal is still | |
| # moving, and a label is a statement about a measurement rather than a condition | |
| # of merging. The regression comparison below becomes a required check only when | |
| # the repository variable OPENKAL_RATCHET is `on`. | |
| on: | |
| schedule: | |
| - cron: "0 7 * * 0" | |
| workflow_dispatch: | |
| inputs: | |
| members: | |
| description: "Space-separated members to measure (empty = every listed member)" | |
| required: false | |
| default: "" | |
| mcpp_ref: | |
| description: "Branch of mcpp-community/mcpp to build and measure against (empty = the released pin)" | |
| required: false | |
| default: "" | |
| pull_request: | |
| paths: | |
| - "pkgs/**/*.lua" | |
| - "tests/openkal/**" | |
| - ".xpkgindex/openkal-compat.json" | |
| - ".github/workflows/openkal-compat.yml" | |
| permissions: | |
| contents: read | |
| env: | |
| # Moves together with index.toml's `min_mcpp` and tests/openkal/pins.toml's | |
| # `mcpp` -- the "The pins agree with this workflow" step below fails the | |
| # run if this drifts from pins.toml. See the comment beside `mcpp` in | |
| # pins.toml for why this pin, not just validate.yml's, is gated by the | |
| # index floor. | |
| MCPP_VERSION: "2026.9.21.3" | |
| # CROSS-VALIDATION BEFORE A RELEASE, NOT AFTER IT. | |
| # | |
| # Empty in an ordinary run, so this measurement keeps using the RELEASED | |
| # engine the pin above names. Set it -- workflow_dispatch input, or the | |
| # repository variable -- and the same measurement runs against mcpp built | |
| # from that ref instead. | |
| # | |
| # THIS EXISTS BECAUSE AN ENGINE CHANGE'S REAL LOAD IS HERE. mcpp's own CI | |
| # cannot see a defect that appears only in a real dependency graph; this | |
| # repository holds thirty such graphs and could not see the engine until it | |
| # had been published. 2026.9.20.1 shipped and, within a day, the four | |
| # members that stop at `windows.h` through a borrowed `__CYGWIN__` made a | |
| # second release necessary -- a reading this job could have produced before | |
| # the first one merged. Every ecosystem repository that mcpp's changes reach | |
| # already honours this variable; this workflow was the gap. | |
| MCPP_SOURCE_REF: ${{ github.event.inputs.mcpp_ref || vars.MCPP_SOURCE_REF }} | |
| XLINGS_NON_INTERACTIVE: "1" | |
| jobs: | |
| measure: | |
| name: measure (linux, windows through wine) | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 240 | |
| outputs: | |
| members: ${{ steps.select.outputs.members }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| # A pull request measures the members its change can affect; the schedule | |
| # and a request with no members measure every listed member. | |
| - name: Select the members | |
| id: select | |
| shell: bash | |
| run: | | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| files=$(git diff --name-only "origin/${{ github.base_ref }}...HEAD") | |
| members=$(python3 tests/openkal/compat.py select $files) | |
| else | |
| members="${{ github.event.inputs.members }}" | |
| [ -n "$members" ] || members=$(python3 tests/openkal/compat.py select tests/openkal/) | |
| fi | |
| echo "members=$members" >> "$GITHUB_OUTPUT" | |
| echo "measuring: ${members:-nothing}" | |
| - name: Download mcpp | |
| if: steps.select.outputs.members != '' | |
| shell: bash | |
| run: | | |
| archive="mcpp-${MCPP_VERSION}-linux-x86_64.tar.gz" | |
| curl -L -fsS -o "$archive" \ | |
| "https://github.com/mcpp-community/mcpp/releases/download/v${MCPP_VERSION}/${archive}" | |
| tar -xzf "$archive" | |
| root="$PWD/mcpp-${MCPP_VERSION}-linux-x86_64" | |
| echo "$root/bin" >> "$GITHUB_PATH" | |
| echo "MCPP_HOME=$root" >> "$GITHUB_ENV" | |
| # The released engine above is the BOOTSTRAP when a ref is under | |
| # review: mcpp builds itself and there is no other compiler for it | |
| # here. | |
| # | |
| # THE BUILD REPLACES THE BINARY INSIDE THE RELEASED ROOT, rather than | |
| # being prepended to PATH beside its own `target/` directory. An | |
| # earlier revision did the latter and the measurement stopped at | |
| # | |
| # error: xlings binary not found | |
| # | |
| # because a released archive carries a BUNDLED xlings that mcpp | |
| # resolves relative to its own location, and a freshly built binary | |
| # has no such neighbour. Overwriting `bin/mcpp` in place keeps that | |
| # root --- its bundled xlings, its layout, `MCPP_HOME`, the PATH | |
| # entry already exported above --- exactly as the released engine | |
| # left it, and changes only the one file under review. | |
| if [ -n "${MCPP_SOURCE_REF:-}" ]; then | |
| src="$RUNNER_TEMP/mcpp-src" | |
| git clone --quiet --depth 1 --branch "$MCPP_SOURCE_REF" \ | |
| https://github.com/mcpp-community/mcpp.git "$src" | |
| # `.xlings.json` at mcpp's root pins the mcpp that compiles mcpp, | |
| # and that pin does not move when mcpp is released, so a build | |
| # inside the checkout would try to install a version the index may | |
| # no longer carry. What is wanted is the source compiled by the | |
| # engine installed above, which removing the file leaves. | |
| rm -f "$src/.xlings.json" | |
| ( cd "$src" && "$root/bin/mcpp" build --release ) | |
| built=$(find "$src/target" -type f -name mcpp | head -1) | |
| [ -n "$built" ] \ | |
| || { echo "::error::mcpp did not build from $MCPP_SOURCE_REF"; exit 1; } | |
| cp "$built" "$root/bin/mcpp" | |
| # Reported from the path the measurement will actually run, not | |
| # from the build directory: a copy that did not land looks exactly | |
| # like one that did until something has been measured with the | |
| # wrong engine. | |
| echo "under review: $("$root/bin/mcpp" --version) (from $MCPP_SOURCE_REF)" | |
| fi | |
| # The Windows cross headers of the host are installed deliberately. A | |
| # graph that reached them would build differently with them present, so a | |
| # result that is the same here and on a runner without them is evidence | |
| # that the graph is closed. Wine runs the Windows members' tests. | |
| - name: Host headers the graph must not reach, and a runner for Windows | |
| if: steps.select.outputs.members != '' | |
| shell: bash | |
| run: | | |
| sudo apt-get update -qq | |
| sudo apt-get install -y -qq mingw-w64 wine64 > /dev/null | |
| ls /usr/x86_64-w64-mingw32/include/windows.h | |
| command -v wine || sudo ln -s "$(command -v wine64)" /usr/local/bin/wine | |
| wine --version | |
| - name: The pins agree with this workflow | |
| if: steps.select.outputs.members != '' | |
| shell: bash | |
| run: | | |
| pinned=$(sed -n 's/^mcpp *= *"\(.*\)"/\1/p' tests/openkal/pins.toml) | |
| if [ "$pinned" != "$MCPP_VERSION" ]; then | |
| echo "::error::tests/openkal/pins.toml names mcpp $pinned and this workflow installs $MCPP_VERSION" | |
| exit 1 | |
| fi | |
| - name: Measure | |
| if: steps.select.outputs.members != '' | |
| shell: bash | |
| run: | | |
| mcpp self config --mirror GLOBAL | |
| args=() | |
| for m in ${{ steps.select.outputs.members }}; do args+=(--member "$m"); done | |
| python3 tests/openkal/compat.py run "${args[@]}" --out openkal-compat.json | |
| - uses: actions/upload-artifact@v4 | |
| if: steps.select.outputs.members != '' | |
| with: | |
| name: openkal-compat | |
| path: openkal-compat.json | |
| - name: No published label regressed | |
| if: steps.select.outputs.members != '' | |
| shell: bash | |
| continue-on-error: ${{ vars.OPENKAL_RATCHET != 'on' }} | |
| run: | | |
| python3 tests/openkal/compat.py check \ | |
| --results openkal-compat.json --baseline .xpkgindex/openkal-compat.json | |
| - name: Summary | |
| if: always() && steps.select.outputs.members != '' | |
| shell: bash | |
| run: | | |
| [ -f openkal-compat.json ] || exit 0 | |
| python3 - <<'PY' >> "$GITHUB_STEP_SUMMARY" | |
| import json | |
| r = json.load(open("openkal-compat.json")) | |
| # Counted per target, and `refused` counted apart from `fails`: a | |
| # member told before compilation that this graph does not supply a | |
| # capability it asked for has been answered correctly, and adding it | |
| # to a failure figure turns that figure into a score the build tool | |
| # is judged by. | |
| tally = {} | |
| for e in r["members"].values(): | |
| for t, rec in e["targets"].items(): | |
| tally.setdefault(t, {}).setdefault(rec["status"], 0) | |
| tally[t][rec["status"]] += 1 | |
| print("| target | runs | builds | fails | refused |") | |
| print("| --- | --- | --- | --- | --- |") | |
| for t in sorted(tally): | |
| c = tally[t] | |
| print(f"| {t} | {c.get('runs',0)} | {c.get('builds',0)} " | |
| f"| {c.get('fails',0)} | {c.get('refused',0)} |") | |
| print() | |
| print("| member | target | result | first diagnostic |") | |
| print("| --- | --- | --- | --- |") | |
| for m, e in sorted(r["members"].items()): | |
| for t, rec in sorted(e["targets"].items()): | |
| d = rec.get("diagnostic", "").replace("|", "\\|") | |
| print(f"| {m} | {t} | {rec['status']} | {d} |") | |
| PY | |
| # Only this job may write. It runs for the default branch only, never for a | |
| # pull request or a measurement requested on another branch. | |
| propose: | |
| name: propose the measurement | |
| needs: measure | |
| if: needs.measure.outputs.members != '' && github.event_name != 'pull_request' && github.event.inputs.members == '' && github.ref == 'refs/heads/main' | |
| runs-on: ubuntu-24.04 | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: openkal-compat | |
| # A scheduled or requested measurement that differs from the published file | |
| # is proposed as a pull request rather than committed, so that a label | |
| # changes only through review. | |
| - name: Propose the new measurement | |
| shell: bash | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| python3 - <<'PY' | |
| import json | |
| new = json.load(open("openkal-compat.json")) | |
| old = json.load(open(".xpkgindex/openkal-compat.json")) | |
| same = {k: v for k, v in new.items() if k != "measured"} == \ | |
| {k: v for k, v in old.items() if k != "measured"} | |
| open("same.txt", "w").write("1" if same else "0") | |
| PY | |
| if [ "$(cat same.txt)" = "1" ]; then echo "the measurement is unchanged"; exit 0; fi | |
| branch="bot/openkal-compat-$(date +%Y%m%d)" | |
| cp openkal-compat.json .xpkgindex/openkal-compat.json | |
| git config user.name "mcpp-index-bot" | |
| git config user.email "bot@mcpplibs.invalid" | |
| git checkout -b "$branch" | |
| git add .xpkgindex/openkal-compat.json | |
| git commit -m "openkal compatibility: the measurement of $(date +%F)" | |
| git push -f origin "$branch" | |
| gh pr create --base main --head "$branch" \ | |
| --title "openkal compatibility: the measurement of $(date +%F)" \ | |
| --body "Measured by .github/workflows/openkal-compat.yml run ${{ github.run_id }}. See the run summary for every member and target." \ | |
| || echo "a pull request for $branch already exists" | |