Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 9 additions & 0 deletions .agents/docs/2026-10-24-template-readiness.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Runnable template and native CI checkpoint

The default greeter template uses the upstream grpc namespace/API and generates a real service through the package-provided host plugin/rule. Both GCC 16 and LLVM 23 actual mcpp new consumers passed a loopback RPC plus the failure path. Template CI on source 839b61e passed; its Linux/macOS native workflow subsequently completed the advanced program but failed a stale generated-file assertion.

Current mcpp places generated files under an invocation/project directory. CI now checks common/types.pb.cc beside the actual orders_mock.grpc.pb.h instead of assuming target/.build-mcpp/out/common. It locates the Ninja graph by the generation edge rather than relying on filesystem order, which can select a host-tool graph. Local LLVM 23.1.3 mcpp run on examples/advanced passed in 3m40s; the produced nonempty shared-proto source, mock header and GENERATE edge descriptions were checked.

The pinned mcpp 2026.10.24.1 includes the object-layout cache fix for which the old MCPP_BUILD_CACHE=local workaround was added. Dropping that expired workaround lets sibling consumers reuse SDK objects; all examples still build and execute their generated code. Native source CI must revalidate the new checkpoint. Windows runtime remains unavailable with the declared OpenSSL provider; plugin/rule host-tool availability is tested separately through the index.

Root READMEs use the common concise style (52 lines per language); prior detailed guidance is under docs/. Package/runtime/plugin/rule versions stay coupled at 1.83.0.1. No merge, tag or release is included.
8 changes: 8 additions & 0 deletions .agents/docs/2026-10-25-unified-mwrap-checkpoint.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Unified mwrap first release

Package/module: `mcpplibs.mwrap.grpc`; upstream version: `1.83.0`.

This checkpoint migrates wrapper identity while retaining upstream API names and SDK sources.
Default README is English with a mandatory Chinese counterpart; original section order is preserved.
Validation and release evidence are recorded in the PR and the index ecosystem ledger.
No old release tag or source resource is rewritten.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Preserve upstream document bytes and original whitespace on every platform.
upstream/** -text -whitespace
71 changes: 30 additions & 41 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
name: CI

# Docs carry no build risk, and this workflow's linux leg is a ~2h serial
# gRPC build (see timeout-minutes below) — a markdown-only change would spend
# it twice, once on the PR and once again on main. `paths-ignore` on both
# The native leg builds gRPC and runs several generated-code consumers;
# a markdown-only change would spend that time twice, once on the PR and
# once again on main. `paths-ignore` on both
# triggers, not just the PR one, or the merge pays the second half anyway.
#
# Deliberately NOT ignored: mcpp.toml, build.mcpp, templates/, examples/,
Expand All @@ -29,25 +29,15 @@ env:
# and `rerun_if_changed_glob`, without which generate_all()
# would not re-run when a .proto is ADDED (no declared file's
# hash changes), silently never generating it
MCPP_VERSION: "2026.8.6.2"
MCPP_VERSION: "2026.10.24.1"

jobs:
build:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
# Every example is its own project depending on `grpc` by path, and each
# one builds gRPC from source again — the cache does not carry across
# them. Measured on linux: module test 25min, then ~31min per example.
# Three examples already sat at ~90min under the old 120 cap; adding
# `advanced` pushed the run past it and the job was cancelled mid-build,
# which reads like a failure and is not one.
#
# Raising the cap is the honest short-term answer, not the right one:
# what actually costs the hour and a half is rebuilding the same gRPC
# four times in series. Splitting the examples into their own matrix leg
# (or getting the dependency cache to hit across sibling projects) turns
# ~2h of wall clock into ~35min. Worth doing on its own, not inside a
# release PR.
# Allow a cold native build plus all generated-code consumers. The pinned
# client can reuse SDK objects across projects; the former local-cache
# workaround forced four cold builds and is no longer needed.
timeout-minutes: 210
strategy:
fail-fast: false
Expand All @@ -64,6 +54,9 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Mwrap identity and bilingual README contract
run: python3 tools/check_mwrap_release.py

- name: Download pinned mcpp
shell: bash
run: |
Expand All @@ -89,17 +82,13 @@ jobs:
run: |
"$MCPP" index update

# mcpp#344: object-path disambiguation keys on basename collisions across
# the whole build dir, while the package cache key covers only the
# dependency — one entry can hold two layouts. This graph has several
# colliding basenames (abseil/protobuf `parser.cc`, abseil/gRPC
# `status.cc`, `time.cc`), so the package cache is bypassed exactly as
# mcpp-index's own CI does. Drop this once the pin reaches 2026.8.3.4.
# The pinned client includes the object-layout cache fix (2026.8.3.4).
# Reuse SDK objects between actual consumers; every example still builds
# its own generated sources and executes its runtime checks.
- name: Build the library and run the module test
shell: bash
env:
MCPP_INDEX_MIRROR: GLOBAL
MCPP_BUILD_CACHE: local
run: |
"$MCPP" --version
"$MCPP" test
Expand All @@ -110,7 +99,6 @@ jobs:
working-directory: examples/helloworld
env:
MCPP_INDEX_MIRROR: GLOBAL
MCPP_BUILD_CACHE: local
run: |
"$MCPP" run

Expand All @@ -124,7 +112,6 @@ jobs:
working-directory: examples/greeter
env:
MCPP_INDEX_MIRROR: GLOBAL
MCPP_BUILD_CACHE: local
run: |
"$MCPP" run

Expand All @@ -138,7 +125,6 @@ jobs:
working-directory: examples/advanced
env:
MCPP_INDEX_MIRROR: GLOBAL
MCPP_BUILD_CACHE: local
run: |
"$MCPP" run
# The mock header is declared by the edge and produced by protoc;
Expand All @@ -148,20 +134,20 @@ jobs:
test -n "$out" || { echo "no mock header produced"; exit 1; }
echo "mock header: $out"
# The shared tree was generated, not just searched.
test -f target/.build-mcpp/out/common/types.pb.cc \
test -s "$(dirname "$out")/common/types.pb.cc" \
|| { echo "shared-proto was not generated"; exit 1; }
# The edge describes ITSELF. This is the rule's half of observability
# — mcpp already puts the full argv in build.ninja, so what the rule
# owns is "which knobs produced it", and that string is what every
# build prints. Asserting it keeps the two from drifting apart.
nj=$(find target -name build.ninja | head -1)
grep -q 'description = GENERATE protoc:orders (+grpc +mock,' "$nj" \
|| { echo "edge description does not describe its knobs:";
grep -o 'description = GENERATE protoc:.*' "$nj"; exit 1; }
nj=$(find target -name build.ninja -exec grep -lF \
'description = GENERATE protoc:orders (+grpc +mock,' {} + | head -1)
test -n "$nj" \
|| { echo "no build graph describes the requested generation knobs"; exit 1; }
grep -o 'description = GENERATE protoc:.*' "$nj"

package-versions-match:
name: all three packages share one version
name: runtime and host tools share upstream source
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -174,14 +160,17 @@ jobs:
- name: versions must match
shell: bash
run: |
lib=$(awk -F'"' '/^version/{print $2; exit}' mcpp.toml)
plug=$(awk -F'"' '/^version/{print $2; exit}' plugin/mcpp.toml)
rule=$(awk -F'"' '/^version/{print $2; exit}' rules/mcpp.toml)
echo "grpc=$lib grpc-plugin=$plug grpcgen=$rule"
rc=0
[ "$lib" = "$plug" ] || { echo "FAIL: grpc-plugin ($plug) != grpc ($lib)"; rc=1; }
[ "$lib" = "$rule" ] || { echo "FAIL: grpcgen ($rule) != grpc ($lib)"; rc=1; }
exit $rc
python3 - <<'PYVERS'
import tomllib
from pathlib import Path
runtime = tomllib.loads(Path("mcpp.toml").read_text())["package"]
plugin = tomllib.loads(Path("plugin/mcpp.toml").read_text())["package"]
rule = tomllib.loads(Path("rules/mcpp.toml").read_text())["package"]
upstream = runtime["metadata"]["mwrap"]["upstream-version"]
assert runtime["version"] == upstream == "1.83.0"
assert plugin["version"] == rule["version"] == upstream + ".1"
print("runtime", runtime["version"], "host tools", plugin["version"], "same pinned source")
PYVERS

# rules/mcpp.toml states that the package name and the module name are
# kept EQUAL, and that this is what makes the package work on every
Expand Down
49 changes: 49 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Release
on:
push:
tags: ["mwrap-*"]
permissions:
contents: read
jobs:
publish:
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: write
actions: read
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Check tag, upstream version and bilingual entry pages
run: python3 tools/check_mwrap_release.py --tag "$GITHUB_REF_NAME"
- name: Require successful source CI at this exact commit
env:
GH_TOKEN: ${{ github.token }}
shell: bash
run: |
set -euo pipefail
result=$(gh run list --repo "$GITHUB_REPOSITORY" --workflow ci.yml --commit "$GITHUB_SHA" --limit 1 --json status,conclusion --jq '.[0] | .status == "completed" and .conclusion == "success"')
test "$result" = true || { echo 'No successful source CI at the tag commit'; exit 1; }
- name: Build immutable source asset and publish
env:
GH_TOKEN: ${{ github.token }}
shell: bash
run: |
set -euo pipefail
version="${GITHUB_REF_NAME#mwrap-}"
repo="${GITHUB_REPOSITORY#*/}"
asset="${repo}-${version}.tar.gz"
git archive --format=tar.gz --prefix="${repo}-${version}/" "$GITHUB_SHA" > "$RUNNER_TEMP/$asset"
(cd "$RUNNER_TEMP" && sha256sum "$asset" > "$asset.sha256")
if gh release view "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
echo 'Release already exists; refusing to change immutable assets'; exit 1
fi
extra=()
if [[ "$version" == *-rc* ]]; then extra+=(--prerelease); fi
gh release create "$GITHUB_REF_NAME" "$RUNNER_TEMP/$asset" "$RUNNER_TEMP/$asset.sha256" \
--repo "$GITHUB_REPOSITORY" --verify-tag --title "$repo $version" \
--notes "Module wrapper for upstream $version. New mwrap package identities become installable after mcpp-index publication; see the bilingual README for the tested support scope." "${extra[@]}"
42 changes: 42 additions & 0 deletions .github/workflows/templates.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Actual project templates
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
permissions:
contents: read
concurrency:
group: templates-${{ github.ref }}
cancel-in-progress: true
env:
MCPP_VERSION: "2026.10.24.1"
jobs:
templates:
runs-on: ubuntu-latest
timeout-minutes: 120
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: ~/.mcpp/registry
key: template-registry-${{ github.repository }}-${{ env.MCPP_VERSION }}-${{ hashFiles('mcpp.toml') }}
restore-keys: |
template-registry-${{ github.repository }}-${{ env.MCPP_VERSION }}-
- name: Install current mcpp
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"
mkdir -p "$HOME/.mcpp/registry"
cp -a "$root/registry/." "$HOME/.mcpp/registry/"
echo "$root/bin" >> "$GITHUB_PATH"
- name: Install toolchains
run: |
mcpp toolchain install gcc 16.1.0
mcpp toolchain install llvm 23.1.3
- name: Actual scaffold, strict build and runtime behavior
run: |
python3 tools/test_template.py --toolchain llvm@23.1.3 --namespace grpc
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ target/
.mcpp/
mcpp.lock
compile_commands.json

.xlings/
5 changes: 5 additions & 0 deletions .xlings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"workspace": {
"xim:mcpp": "2026.10.24.1"
}
}
Loading
Loading