Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
9d61a0b
chore: 2026.10.10.1; bootstrap from 2026.10.8.1; the design record
Sunrisepeak Oct 9, 2026
7f863fa
feat(workspace): the prefix carries the meaning -- [workspace.X] laye…
Sunrisepeak Oct 9, 2026
c7df53e
feat(manifest): the key registry; publish writes the workspace layer …
Sunrisepeak Oct 9, 2026
bc289c8
fix(modules): the module declaration decides the role, the extension …
Sunrisepeak Oct 9, 2026
904664a
fix(build-program): an action's output has one writer, and out_dir is…
Sunrisepeak Oct 9, 2026
ad58c5b
feat(toolchain): --toolchain replacing a declared toolchain says so (…
Sunrisepeak Oct 9, 2026
adddd0f
fix(build): the toolchain's library path prefixes its tools, not ninj…
Sunrisepeak Oct 9, 2026
5f42969
fix(platform): a command string's shell is resolved, not /bin/sh by a…
Sunrisepeak Oct 9, 2026
d08bc01
feat(platform): an Android host is recognised and reported, not given…
Sunrisepeak Oct 9, 2026
1655f0c
feat(install): the hint follows the failure's class (D22); extraction…
Sunrisepeak Oct 9, 2026
7146c4e
fix(windows): the SDK is found where its installer recorded it; the M…
Sunrisepeak Oct 9, 2026
6af0689
fix(indices): the index router reads [workspace.indices] and the posi…
Sunrisepeak Oct 9, 2026
680808c
test(e2e): 893-901 -- the workspace layer and its compat reading, con…
Sunrisepeak Oct 9, 2026
0c47db0
docs(workspace): the prefix carries the meaning; ci: Termux fresh-ins…
Sunrisepeak Oct 9, 2026
0c212bc
docs: SPEC-004 1.14 and SPEC-007 0.8; 04, 20, 30 and their zh counter…
Sunrisepeak Oct 9, 2026
910d551
docs(changelog): 2026.10.10.1
Sunrisepeak Oct 9, 2026
eeea6aa
chore: pin xlings 2026.10.10.2
Sunrisepeak Oct 9, 2026
c28e2ee
fix(build): the resource compiler takes the toolchain's library path too
Sunrisepeak Oct 9, 2026
0856e8a
fix(build): the managed tools run on their own RPATH; the library pat…
Sunrisepeak Oct 9, 2026
576e8f9
fix(build-program): the program's directory is made beside its per-co…
Sunrisepeak Oct 9, 2026
82c1d87
ci(docs): the key registry and the field reference agree; docs/04 nam…
Sunrisepeak Oct 9, 2026
58a3d02
fix(toolchain): the override warning names a path outside the project…
Sunrisepeak Oct 9, 2026
01e3e2a
fix(build): a program's out dir is beside its cache; emit build-datab…
Sunrisepeak Oct 9, 2026
0f9c782
fix(index): index list and the router read the same effective indices…
Sunrisepeak Oct 9, 2026
42e9ca5
ci: the offscreen example's shaders are looked for in the outDir reso…
Sunrisepeak Oct 9, 2026
879a3af
fix(fetch): a failed install names the first address's failure, not o…
Sunrisepeak Oct 9, 2026
26943c7
test(e2e): an inherited subos comes with the ledger that registers it…
Sunrisepeak Oct 10, 2026
ab9dc24
test(e2e): a tool read from build.ninja is run as a command line
Sunrisepeak Oct 10, 2026
21936a0
chore: drop two build logs committed by mistake
Sunrisepeak Oct 10, 2026
cdb8c9a
docs(changelog): the install diagnostic, index list and the emit reuse
Sunrisepeak Oct 10, 2026
3a77484
Revert "test(e2e): an inherited subos comes with the ledger that regi…
Sunrisepeak Oct 10, 2026
511ba6e
ci(e2e): the index payloads e2e 32, 33 and 40 link are installed with…
Sunrisepeak Oct 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
800 changes: 800 additions & 0 deletions .agents/docs/2026-10-10-one-source-one-meaning-design.md

Large diffs are not rendered by default.

169 changes: 169 additions & 0 deletions .agents/docs/2026-10-10-one-source-one-meaning-repro.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#!/usr/bin/env bash
# Reproductions for .agents/docs/2026-10-10-one-source-one-meaning-design.md.
# Prints what each case observes; asserts nothing.
#
# MCPP=<path to mcpp> bash 2026-10-10-one-source-one-meaning-repro.sh
#
# R1 conditional dialect_cxxflags in three positions (#786, #785)
# R2 action output shared by two profiles (out_dir has no configuration)
# R3 #778 on Linux: member target cleared, workspace ninja log kept
# R4 #790: implementation partition in a .cpp, rebuilt every time
# R5 interface unit (`export module`) in a .cpp
# R6 implementation partition in a .cpp imported by the interface
set -u
MCPP="${MCPP:-mcpp}"
LLVM="${LLVM:-llvm@23.1.3}"
T=$(mktemp -d)
echo "mcpp: $("$MCPP" --version 2>&1 | head -1) work: $T"
binrun() { local b; b=$(find target -path '*/bin/*' -name "$1" -type f -newer "$2" 2>/dev/null | xargs -r ls -t | head -1); [ -n "$b" ] && "$b" || echo "(no binary)"; }

# ── R1 ────────────────────────────────────────────────────────────────
main_dial() { cat > "$1" <<'EOF'
#include <cstdio>
#ifndef DIAL
#define DIAL 0
#endif
int main() { std::printf("DIAL=%d\n", DIAL); }
EOF
}
app_toml() { cat <<EOF
[package]
name = "app"
version = "0.1.0"
[build]
sources = ["main.cpp"]
[targets.app]
kind = "bin"
main = "main.cpp"
$1
EOF
}
COND1='[target.'"'"'cfg(os = "linux")'"'"'.build]
dialect_cxxflags = ["-DDIAL=1"]'
COND2='[target.'"'"'cfg(os = "linux")'"'"'.build]
dialect_cxxflags = ["-DDIAL=2"]'
mkdir -p "$T/r1/ws-root/app" "$T/r1/member/app" "$T/r1/standalone"
printf '[workspace]\nmembers = ["app"]\n%s\n' "$COND1" > "$T/r1/ws-root/mcpp.toml"
app_toml "" > "$T/r1/ws-root/app/mcpp.toml"; main_dial "$T/r1/ws-root/app/main.cpp"
printf '[workspace]\nmembers = ["app"]\n' > "$T/r1/member/mcpp.toml"
app_toml "$COND2" > "$T/r1/member/app/mcpp.toml"; main_dial "$T/r1/member/app/main.cpp"
app_toml "$COND2" > "$T/r1/standalone/mcpp.toml"; main_dial "$T/r1/standalone/main.cpp"
for c in ws-root member; do
(cd "$T/r1/$c" && "$MCPP" build -p app > build.log 2>&1; echo "R1 $c: $(binrun app mcpp.toml) warnings: $(grep -ci warn build.log)")
done
(cd "$T/r1/standalone" && "$MCPP" build > build.log 2>&1; echo "R1 standalone: $(binrun app mcpp.toml)")

# ── R2 ────────────────────────────────────────────────────────────────
mkdir -p "$T/r2/src"; cd "$T/r2"
cat > mcpp.toml <<'EOF'
[package]
name = "gp"
version = "0.1.0"
[build]
sources = ["src/main.cpp"]
[targets.gp]
kind = "bin"
main = "src/main.cpp"
EOF
cat > src/main.cpp <<'EOF'
#include <cstdio>
const char* gen_profile();
int main() { std::printf("GEN=%s\n", gen_profile()); }
EOF
printf '#!/bin/sh\nprintf '"'"'const char* gen_profile() { return "%%s"; }\\n'"'"' "$1" > "$2"\n' > gen.sh
cat > build.mcpp <<'EOF'
import std;
import mcpp;
int main() {
const auto root = std::filesystem::path(mcpp::manifest_dir());
const auto out = (std::filesystem::path(mcpp::out_dir()) / "gen.cpp").generic_string();
const auto gen = (root / "gen.sh").generic_string();
mcpp::action a;
a.id = "gen";
a.role = mcpp::roles::source;
a.arg("sh").arg(gen.c_str()).arg(mcpp::profile()).arg(out.c_str())
.input(gen.c_str()).output(out.c_str()).submit();
return 0;
}
EOF
for p in "" --release ""; do
"$MCPP" build $p > build.log 2>&1 || tail -5 build.log
echo "R2 build ${p:-(dev)}: $(binrun gp gen.sh)"
done
echo "R2 out_dir: $(find target -name gen.cpp | head -3 | tr '\n' ' ')"

# ── R3 ────────────────────────────────────────────────────────────────
mkdir -p "$T/r3/app"; cd "$T/r3"
printf '[workspace]\nmembers = ["app"]\n' > mcpp.toml
cat > app/mcpp.toml <<'EOF'
[package]
namespace = "repro"
name = "app"
version = "0.0.1"
[build]
sources = []
[targets.resource_test]
kind = "bin"
main = "main.cpp"
EOF
printf 'extern const char* resource();\nint main() { return resource()[0] == '"'"'R'"'"' ? 0 : 1; }\n' > app/main.cpp
printf '#!/bin/sh\nprintf '"'"'const char* resource() { return "RESOURCE"; }\\n'"'"' > "$1"\n' > app/gen.sh
cat > app/build.mcpp <<'EOF'
import std;
import mcpp;
int main() {
const auto root = std::filesystem::path(mcpp::manifest_dir());
const auto out = (std::filesystem::path(mcpp::out_dir()) / "generated.cpp").generic_string();
const auto gen = (root / "gen.sh").generic_string();
mcpp::action a;
a.id = "generate:resource";
a.role = mcpp::roles::source;
a.arg("sh").arg(gen.c_str()).arg(out.c_str()).input(gen.c_str()).output(out.c_str()).submit();
return 0;
}
EOF
"$MCPP" build -p app --release > b1.log 2>&1; echo "R3 first: rc=$? size=$(stat -c %s app/target/.build-mcpp/out/generated.cpp 2>/dev/null)"
mv app/target saved-app-target
"$MCPP" build -p app --release > b2.log 2>&1; echo "R3 after clearing member target: rc=$? size=$(stat -c %s app/target/.build-mcpp/out/generated.cpp 2>/dev/null) $(grep -m1 -o 'undefined reference[^)]*' b2.log)"

# ── R4–R6 ─────────────────────────────────────────────────────────────
mod_pkg() { # dir, extra-for-repro.cppm
mkdir -p "$1/src"
cat > "$1/mcpp.toml" <<EOF
[package]
name = "repro"
version = "0.1.0"
[toolchain]
default = "$LLVM"
[targets.repro]
kind = "bin"
main = "src/main.cpp"
EOF
printf 'export module repro;\nexport import :api;\n%s\n' "$2" > "$1/src/repro.cppm"
printf 'export module repro:api;\nexport auto answer() -> int;\n' > "$1/src/api.cppm"
printf 'module repro:api_impl;\nimport :api;\nauto answer() -> int { return 42; }\n' > "$1/src/api_impl.cpp"
printf 'import repro;\nimport std;\nauto main() -> int { std::println("{}", answer()); }\n' > "$1/src/main.cpp"
}
mod_pkg "$T/r4" ""; cd "$T/r4"
for i in 1 2 3; do "$MCPP" build --verbose > b$i.log 2>&1; done
echo "R4 build 2: $(grep -cE '^\[[0-9]+/' b2.log) steps; build 3: $(grep -cE '^\[[0-9]+/' b3.log) steps"
echo "R4 pcm files: $(find target -name '*.pcm' -path '*pcm.cache*' -printf '%f ' 2>/dev/null)"

mod_pkg "$T/r6" "import :api_impl;"; cd "$T/r6"
"$MCPP" build > b.log 2>&1; echo "R6 import of the .cpp partition: rc=$? $(grep -m1 -o "fatal error: .*" b.log)"

mkdir -p "$T/r5/src"; cd "$T/r5"
cat > mcpp.toml <<EOF
[package]
name = "r5"
version = "0.1.0"
[toolchain]
default = "$LLVM"
[targets.r5]
kind = "bin"
main = "src/main.cpp"
EOF
printf 'export module r5;\nexport auto answer() -> int { return 42; }\n' > src/r5.cpp
printf 'import r5;\nimport std;\nauto main() -> int { std::println("{}", answer()); }\n' > src/main.cpp
"$MCPP" build > b1.log 2>&1; r1=$?; "$MCPP" build --verbose > b2.log 2>&1
echo "R5 interface in .cpp: rc=$r1 $(grep -m1 -oE '(error|fatal error): .*' b1.log) second build: $(grep -cE '^\[[0-9]+/' b2.log) steps"
4 changes: 3 additions & 1 deletion .agents/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ superseded_by: 2026-09-07-....md # when status is superseded
---
```

329 records.
330 records.

## By subject

Expand All @@ -30,6 +30,7 @@ Records that declare one. Everything else is listed by date below.

### design

- [一处来源,一种含义:工作空间的传递语义、生成输出、模块角色与首次运行(#786、#785、#778、#790)](2026-10-10-one-source-one-meaning-design.md) — landed
- [2026.10.5.3 发布方案:32 位 x86 的架构词汇、资源编译器的识别与增量(#776 后续)](2026-10-06-windows-x86-arch-vocabulary-and-rc-follow-ups-design.md) — active
- [下一个版本的发布方案:标准库模块、原生 MSVC LTO 与导出发现、共享库的链接配置、Windows 参数引号(#768 后续、#770、#771)](2026-10-05-std-module-pair-msvc-lto-and-export-discovery-design.md) — active
- [`mcpp run` hands the terminal to the program, and the follow-ups of #761, #763 and #765 (#766)](2026-10-05-run-terminal-handoff-and-766-follow-ups-design.md) — landed
Expand Down Expand Up @@ -123,6 +124,7 @@ Records that declare one. Everything else is listed by date below.

### 2026-10

- [一处来源,一种含义:工作空间的传递语义、生成输出、模块角色与首次运行(#786、#785、#778、#790)](2026-10-10-one-source-one-meaning-design.md) — landed
- [LLVM 23.1.3 Part 2:Linux aarch64 默认工具链与 glibc 生态闭环](2026-10-08-llvm-2313-linux-aarch64-ecosystem-part2-design.md) — active
- [LLVM 23.1.3 全平台统一默认:跨仓库联动方案(mcpp × xim-pkgindex)](2026-10-07-llvm-2313-unified-default-cross-repo-design.md) — active
- [2026.10.5.3 发布方案:32 位 x86 的架构词汇、资源编译器的识别与增量(#776 后续)](2026-10-06-windows-x86-arch-vocabulary-and-rc-follow-ups-design.md) — active
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/bootstrap-mcpp/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ inputs:
# `package.name`, so one of the two was simply unreachable — and which one
# depended on the machine, which is why CI failed on `compat:lua` on
# Windows and `mcpplibs.capi:lua` on Linux. Never pin below that.
default: '2026.10.8.1'
default: '2026.10.10.2'

outputs:
sandbox-key:
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/setup-macos-llvm/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ inputs:
# Floor imposed by the index, not a routine bump — see
# .github/actions/bootstrap-mcpp/action.yml for why 0.4.69 is required
# (two packages named `lua` in one repo need openxlings/xlings#381).
default: '2026.10.8.1'
default: '2026.10.10.2'
image:
description: >
The runner label the job runs on (macos-15, xcode-27). It is part of the
Expand Down
54 changes: 54 additions & 0 deletions .github/tools/check_manifest_key_classes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env python3
"""The key registry and the documents that list its keys agree (SPEC-004 §2).
`modules/manifest/src/key_registry.cppm` states the class of every key once,
and the parser reads its `[build]` keys from there. A key the registry adds
and the field reference does not mention, or a shared table the workspace
chapter does not list, is the drift this check stops:
- every `[build]` key of the registry is named in docs/04 and docs/zh/04;
- every table the registry marks shared has a `[workspace.<table>]` row in
docs/07 and docs/zh/07 (`profile.<name>` as `[workspace.profile.<name>]`,
the `target.<sel>` rows as `[workspace.target.<selector>]`).
"""
import pathlib
import re
import sys

ROOT = pathlib.Path(__file__).resolve().parents[2]
ROW = re.compile(r'\{"([^"]+)",\s*"([^"]*)",\s*KeyScope::(\w+),\s*KeyMerge::(\w+),\s*(true|false),\s*(true|false)\s*\}')


def main() -> int:
rows = ROW.findall((ROOT / "modules/manifest/src/key_registry.cppm").read_text())
if not rows:
print("FAIL: no rows read from key_registry.cppm")
return 1
problems = []
for lang in ("", "zh/"):
ref = (ROOT / f"docs/{lang}04-mcpp-toml.md").read_text()
ws = (ROOT / f"docs/{lang}07-workspace.md").read_text()
for table, key, _scope, _merge, shared, _cond in rows:
if table == "build" and key and f"`{key}`" not in ref and f"{key} " not in ref:
problems.append(f"docs/{lang}04-mcpp-toml.md does not name [build] {key}")
if shared == "true" and not key:
mirror = {
"profile.<name>": "[workspace.profile.<name>]",
"package": "[workspace.package]",
}.get(table)
if table.startswith("target.<sel>"):
mirror = "[workspace.target.<selector>]"
if mirror is None:
mirror = f"[workspace.{table}"
if mirror not in ws:
problems.append(f"docs/{lang}07-workspace.md does not list {mirror}")
for p in problems:
print(f"FAIL: {p}")
if problems:
return 1
print(f"OK: {len(rows)} registry rows agree with docs/04 and docs/07 (en, zh)")
return 0


if __name__ == "__main__":
sys.exit(main())
15 changes: 15 additions & 0 deletions .github/tools/out_dir.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh
# Prints where `mcpp::out_dir()` pointed for the root package in the newest
# build of the package in the current directory: its `outDir` in
# resolution.json. Each configuration has its own output directory, so a check
# reads it instead of naming target/.build-mcpp/out.
r=$(ls -t target/*/*/resolution.json 2>/dev/null | head -1)
[ -n "$r" ] || { echo "out_dir.sh: no resolution.json under target/" >&2; exit 1; }
py=$(command -v python3 || command -v python)
d=$("$py" -c 'import json, sys
for p in json.load(open(sys.argv[1])).get("graph", {}).get("packages", []):
if p.get("root"):
print(p.get("outDir", ""))
break' "$r")
[ -n "$d" ] || { echo "out_dir.sh: $r records no outDir for the root package" >&2; exit 1; }
echo "$d"
98 changes: 98 additions & 0 deletions .github/tools/termux_fresh_install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/usr/bin/env bash
# A fresh mcpp in Termux: `mcpp new` and `mcpp run` with the default toolchain
# (design 2026-10-10 §13, D27). Two places, because neither has both halves
# of a phone:
#
# docker <tarball> termux/termux-docker (aarch64): Termux's bionic
# userland and paths, on a native arm64 runner. It
# has no `/bin`; Android 10 and later do
# (`/bin -> /system/bin`), which is mcpp's baseline,
# so the link is made first. No SELinux.
# emulator-download <tarball>, then emulator-run
# An Android 14 emulator (x86_64, KVM) with the
# debuggable Termux APK; commands run through
# `run-as com.termux`, in the app's SELinux domain,
# where link(2) is refused -- the half that made
# every install of the managed glibc fail.
#
# <tarball> is a release archive (`mcpp-<v>-linux-<arch>.tar.gz`) or a URL.
# Exits non-zero unless the program built and printed its line.
set -euo pipefail
MODE="${1:?mode}"
WORK="${RUNNER_TEMP:-/tmp}/termux-fresh"
mkdir -p "$WORK/logs"
S="${GITHUB_STEP_SUMMARY:-/dev/null}"
WANT="hello from termux"

fetch() { # $1 = tarball path or URL, $2 = destination
case "$1" in
http*) curl -fsSL --retry 3 -o "$2" "$1" ;;
*) cp "$1" "$2" ;;
esac
}

# The script that runs inside Termux. POSIX sh: under run-as there is only the
# system shell, and in termux-docker it is the same file.
cat > "$WORK/inside.sh" <<'SH'
#!/bin/sh
set -u
TARBALL="$1"; HOME="$2"; export HOME
export TMPDIR="$HOME/tmp"; mkdir -p "$TMPDIR" "$HOME/dist"
tar -xzf "$TARBALL" -C "$HOME/dist"
MCPP=$(find "$HOME/dist" -path '*/bin/mcpp' -type f | head -1)
"$MCPP" --version
"$MCPP" self env --format json | grep -o '"android":[a-z]*'
cd "$HOME" && rm -rf hello && "$MCPP" new hello >/dev/null
cd hello
printf 'import std;\nint main() { std::println("hello from termux"); }\n' > src/main.cpp
timeout 5400 "$MCPP" run
SH
chmod 755 "$WORK/inside.sh"

case "$MODE" in
docker)
fetch "${2:?tarball}" "$WORK/mcpp.tar.gz"
chmod -R a+rX "$WORK"; chmod 777 "$WORK/logs"
docker pull -q termux/termux-docker:aarch64
set +e
docker run --rm --privileged --entrypoint /system/bin/sh \
-v "$WORK:/mnt/w" termux/termux-docker:aarch64 \
-c 'ln -s /system/bin /bin && exec /entrypoint.sh sh /mnt/w/inside.sh /mnt/w/mcpp.tar.gz /data/data/com.termux/files/home' \
2>&1 | tee "$WORK/logs/docker.log"
set -e
;;
emulator-download)
fetch "${2:?tarball}" "$WORK/mcpp.tar.gz"
curl -fsSL --retry 3 -o "$WORK/termux.apk" \
"https://github.com/termux/termux-app/releases/download/v0.118.3/termux-app_v0.118.3+github-debug_x86_64.apk"
exit 0
;;
emulator-run)
A=/data/data/com.termux/files
adb wait-for-device
adb install -r "$WORK/termux.apk" >/dev/null
adb shell am start -n com.termux/com.termux.app.TermuxActivity >/dev/null
for _ in $(seq 1 60); do
adb shell run-as com.termux ls "$A/usr/bin/sh" >/dev/null 2>&1 && break
sleep 5
done
for f in mcpp.tar.gz inside.sh; do
adb push "$WORK/$f" /data/local/tmp/ >/dev/null
adb shell chmod 644 "/data/local/tmp/$f"
adb shell run-as com.termux cp "/data/local/tmp/$f" "$A/$f"
done
echo "SELinux: $(adb shell getenforce | tr -d '\r'); context: $(adb shell run-as com.termux cat /proc/self/attr/current | tr -d '\r\0')" \
| tee -a "$S"
set +e
adb shell run-as com.termux "$A/usr/bin/env" PREFIX="$A/usr" PATH="$A/usr/bin" \
LANG=en_US.UTF-8 sh "$A/inside.sh" "$A/mcpp.tar.gz" "$A/home" 2>&1 \
| tr -d '\r' | tee "$WORK/logs/emulator.log"
set -e
;;
*) echo "unknown mode $MODE"; exit 2 ;;
esac

log=$(ls "$WORK"/logs/*.log | head -1)
{ echo "### Termux ($MODE)"; echo '```'; tail -25 "$log"; echo '```'; } >> "$S"
grep -qx "$WANT" "$log" || { echo "FAIL: the program did not print '$WANT'"; exit 1; }
echo "PASS: mcpp new + run in Termux ($MODE)"
2 changes: 1 addition & 1 deletion .github/workflows/bootstrap-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
# Dormant (workflow_dispatch only), but kept in step with the rest —
# check_version_pins.sh holds it there. Floor: 0.4.69, below which the
# index cannot resolve two packages that share a short name.
XLINGS_VERSION: '2026.10.8.1'
XLINGS_VERSION: '2026.10.10.2'
steps:
- uses: actions/checkout@v4

Expand Down
Loading
Loading