Skip to content

feat: 一条依赖 + 一行 build.mcpp —— codegen 工具链由本包交给用户 (#3) #10

feat: 一条依赖 + 一行 build.mcpp —— codegen 工具链由本包交给用户 (#3)

feat: 一条依赖 + 一行 build.mcpp —— codegen 工具链由本包交给用户 (#3) #10

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
env:
# Keep in step with the mcpp-index CI pin: this package's dependencies are
# index packages, and they are validated against that same mcpp.
# 2026.8.6.2 is the FLOOR, not a routine pin. Four things the codegen in
# templates/ and examples/ is built on do not exist before it:
# 2026.8.5.1 `tools = [...]` host tools; `mcpp:action=` build-graph nodes
# 2026.8.5.2 a `host-module = true` rule package may use `import std;` and
# `import mcpp;` — rules/ needs both, and before .5.2 it failed
# with `module 'std' not found` / `module 'mcpp' not found`
# 2026.8.6.2 `reexport = true`, which is what lets THIS package hand its
# user the whole codegen toolchain — one dependency, not four —
# 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"
jobs:
build:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
include:
- { name: "linux x86_64", os: ubuntu-latest, suffix: linux-x86_64, ext: tar.gz, mcpp: bin/mcpp }
- { name: "macos arm64", os: macos-latest, suffix: macosx-arm64, ext: tar.gz, mcpp: bin/mcpp }
# No windows leg: compat.openssl has no windows xpm entry yet, so
# dependency resolution fails there before anything is compiled
# ("E_NOT_FOUND: package 'compat:openssl@3.5.1' not found"). gRPC's
# secure build cannot drop TLS, so this package is linux + macOS
# until that package gains windows support. Re-add this line then —
# the windows flags in mcpp.toml are already in place.
steps:
- uses: actions/checkout@v4
- name: Download pinned mcpp
shell: bash
run: |
base="https://github.com/mcpp-community/mcpp/releases/download/v${MCPP_VERSION}"
archive="mcpp-${MCPP_VERSION}-${{ matrix.suffix }}.${{ matrix.ext }}"
curl -L -fsS -o "$archive" "$base/$archive"
if [ "${{ matrix.ext }}" = "zip" ]; then unzip -q "$archive"; else tar -xzf "$archive"; fi
root="$PWD/mcpp-${MCPP_VERSION}-${{ matrix.suffix }}"
if [ "${{ runner.os }}" = "Windows" ]; then
echo "MCPP=$(cygpath -m "$root/${{ matrix.mcpp }}")" >> "$GITHUB_ENV"
echo "MCPP_VENDORED_XLINGS=$(cygpath -m "$root/registry/bin/xlings")" >> "$GITHUB_ENV"
else
echo "MCPP=$root/${{ matrix.mcpp }}" >> "$GITHUB_ENV"
echo "MCPP_VENDORED_XLINGS=$root/registry/bin/xlings" >> "$GITHUB_ENV"
fi
# The dependencies are published index packages, and the snapshot the
# mcpp release vendored is older than whatever landed since.
- name: Refresh the published package index
shell: bash
env:
MCPP_INDEX_MIRROR: GLOBAL
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.
- 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
# The long form: codegen spelled out by hand in build.mcpp.
- name: helloworld example — a real RPC over loopback
shell: bash
working-directory: examples/helloworld
env:
MCPP_INDEX_MIRROR: GLOBAL
MCPP_BUILD_CACHE: local
run: |
"$MCPP" run
# The short form: the same program, with codegen from the `grpcgen` rule
# package and a three-line build.mcpp. This example IS templates/greeter
# instantiated, so building it is how the template gets tested — a broken
# template would otherwise only be discovered by a user running
# `mcpp new`.
- name: greeter example — the template, via the rule package
shell: bash
working-directory: examples/greeter
env:
MCPP_INDEX_MIRROR: GLOBAL
MCPP_BUILD_CACHE: local
run: |
"$MCPP" run
package-versions-match:
name: all three packages share one version
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# The plugin generates code that calls gRPC internals, so a plugin built
# from a different release than the runtime being linked is exactly the
# mismatch this whole design exists to make impossible. The rule package
# names both of the others by version in what it tells users to write.
# All three ship as separate index entries from ONE tag, so nothing but a
# check keeps them equal.
- 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
template-matches-example:
name: templates/greeter == examples/greeter
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# examples/greeter is the template instantiated; CI builds it, which is
# the only thing that tests the template at all. That only holds while
# the two do not drift, and build.mcpp is the file that matters — it is
# pure code with no substitutions, so it must be byte-identical.
- name: build.mcpp must be identical
shell: bash
run: |
if ! diff -u templates/greeter/build.mcpp.in examples/greeter/build.mcpp; then
echo "FAIL: the template and its example have drifted apart."
echo " cp templates/greeter/build.mcpp.in examples/greeter/build.mcpp"
exit 1
fi
echo "template and example agree"
manifest-matches-upstream:
name: source list == upstream CMakeLists
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Fetch the pinned gRPC tag
run: |
git clone -q --depth 1 -b v1.83.0 https://github.com/grpc/grpc.git /tmp/grpc
# Proves mcpp.toml's source arrays are upstream's own list, not a
# hand-curated one that has drifted.
- name: tools/gen_sources.py --check
run: python3 tools/gen_sources.py --grpc /tmp/grpc --check