Skip to content

Commit b30e70c

Browse files
docs: retranslate the 简体中文 README and manual; pypi: pip install mcpp-bin (#686)
* docs: retranslate the 简体中文 README and manual from the English sources Every docs/zh chapter and README.zh-CN.md is translated afresh from its English original: English technical terms and the system as grammatical subject are kept, full-width punctuation is applied to Chinese prose, and every fenced code block is byte-identical to the English. The retranslation restores content the Chinese copies had lost (the kind-decides-pack note in 10, 'The grammar is open' in 42, a blockquote in 92, two bullets in 90, the hooks example in 09) and retitles 41 as 在设备上运行. README: the 2026.9.20.1 release note is removed from the front page, and the navigation table gains a last row for mcpp-language-server. * pypi: publish the release binary as mcpp-bin (pip install mcpp-bin) scripts/pypi/build_wheels.py builds one wheel per payload named in the release's mcpp-release.json, checking each payload's sha256 against it. A wheel carries bin/mcpp and the bundled xlings, and a launcher behind the `mcpp` console script that pins MCPP_HOME to ~/.mcpp and MCPP_VENDORED_XLINGS to the bundled xlings, as the AUR launcher does. pypi-publish.yml runs downstream of release, pip-installs the wheels on Linux x86_64/aarch64, macOS arm64 and Windows x86_64, and uploads through PyPI Trusted Publishing. No secret is stored. Automatic uploads are armed by the PYPI_AUTOPUBLISH repository variable; a pull request never publishes. Both READMEs list pip as installation option 4. --------- Co-authored-by: speak-agent <248744407+speak-agent@users.noreply.github.com>
1 parent d1f1c98 commit b30e70c

40 files changed

Lines changed: 9226 additions & 7587 deletions

.github/workflows/pypi-publish.yml

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
name: pypi-publish
2+
3+
# Publish the `mcpp-bin` wheels to PyPI (`pip install mcpp-bin`).
4+
#
5+
# Downstream of `release`, like aur-publish.yml and homebrew-publish.yml: the
6+
# wheels are built from the release's own mcpp-release.json and payloads, so
7+
# this runs only once the release workflow has completed.
8+
#
9+
# CREDENTIALS: none stored. Publishing uses PyPI Trusted Publishing (OIDC):
10+
# PyPI trusts this repository + workflow file + the `pypi` environment, and
11+
# the job exchanges its GitHub OIDC token for a short-lived upload token.
12+
# One-time setup is in scripts/pypi/README.md.
13+
#
14+
# ARMING: the automatic trigger builds, verifies and reports, and publishes
15+
# only when the repository variable PYPI_AUTOPUBLISH is `true`, for the reason
16+
# aur-publish.yml gives: an unattended push to a third-party service must be
17+
# armed by a human who has watched one publish succeed, not inherited from a
18+
# merge. `workflow_dispatch` carries its own explicit `publish` switch.
19+
20+
on:
21+
workflow_run:
22+
workflows: [release]
23+
types: [completed]
24+
# Changes to the packaging itself build and pip-install the wheels of the
25+
# latest release on every platform. A pull request never publishes.
26+
pull_request:
27+
paths:
28+
- scripts/pypi/**
29+
- tests/scripts/test_pypi_wheels.py
30+
- .github/workflows/pypi-publish.yml
31+
workflow_dispatch:
32+
inputs:
33+
publish:
34+
description: 'Upload to PyPI (false builds and verifies only)'
35+
type: boolean
36+
required: true
37+
default: false
38+
tag:
39+
description: 'Release tag, e.g. v2026.9.21.3 (default: the latest release)'
40+
type: string
41+
required: false
42+
43+
concurrency:
44+
group: pypi-mcpp-bin
45+
cancel-in-progress: false
46+
47+
permissions:
48+
contents: read
49+
50+
jobs:
51+
build:
52+
name: build wheels
53+
if: >-
54+
github.event_name != 'workflow_run' ||
55+
github.event.workflow_run.conclusion == 'success'
56+
runs-on: ubuntu-24.04
57+
timeout-minutes: 20
58+
outputs:
59+
version: ${{ steps.resolve.outputs.version }}
60+
publish: ${{ steps.resolve.outputs.publish }}
61+
env:
62+
GH_TOKEN: ${{ github.token }}
63+
steps:
64+
- uses: actions/checkout@v4
65+
with:
66+
ref: ${{ github.event.workflow_run.head_sha || github.ref }}
67+
68+
- uses: actions/setup-python@v5
69+
with:
70+
python-version: '3.12'
71+
72+
- name: Builder contract tests
73+
run: python3 tests/scripts/test_pypi_wheels.py
74+
75+
- name: Resolve the release and whether to publish
76+
id: resolve
77+
env:
78+
TRIGGER: ${{ github.event_name }}
79+
INPUT_TAG: ${{ inputs.tag }}
80+
MANUAL_PUBLISH: ${{ inputs.publish }}
81+
AUTOPUBLISH: ${{ vars.PYPI_AUTOPUBLISH }}
82+
run: |
83+
set -euo pipefail
84+
if [[ -n "${INPUT_TAG:-}" ]]; then
85+
tag="$INPUT_TAG"
86+
elif [[ "$TRIGGER" == "workflow_run" ]]; then
87+
# The released commit's mcpp.toml carries the released version.
88+
tag="v$(grep -m1 -E '^\s*version\s*=' mcpp.toml | sed -E 's/.*"([^"]+)".*/\1/')"
89+
else
90+
tag="$(gh release view -R "$GITHUB_REPOSITORY" --json tagName --jq .tagName)"
91+
fi
92+
version="${tag#v}"
93+
echo "tag=$tag" >> "$GITHUB_OUTPUT"
94+
echo "version=$version" >> "$GITHUB_OUTPUT"
95+
96+
# PyPI never accepts the same file twice, so an existing version is
97+
# a finished job rather than something to retry.
98+
code=$(curl -s -o /dev/null -w '%{http_code}' --retry 3 --retry-all-errors \
99+
"https://pypi.org/pypi/mcpp-bin/$version/json")
100+
if [[ "$code" == "200" ]]; then
101+
echo "::notice::mcpp-bin $version is already on PyPI; nothing to publish."
102+
publish=false
103+
elif [[ "$TRIGGER" == "workflow_run" ]]; then
104+
if [[ "${AUTOPUBLISH:-}" == "true" ]]; then
105+
publish=true
106+
else
107+
publish=false
108+
echo "::notice::PYPI_AUTOPUBLISH is not set — building and verifying $tag without publishing."
109+
fi
110+
elif [[ "$TRIGGER" == "workflow_dispatch" ]]; then
111+
publish="${MANUAL_PUBLISH:-false}"
112+
else
113+
publish=false
114+
fi
115+
echo "publish=$publish" >> "$GITHUB_OUTPUT"
116+
echo "mcpp-bin $version from $tag; publish=$publish" >> "$GITHUB_STEP_SUMMARY"
117+
118+
- name: Build wheels from the release manifest
119+
run: python3 scripts/pypi/build_wheels.py --tag "${{ steps.resolve.outputs.tag }}" --out dist
120+
121+
- name: Check metadata
122+
run: |
123+
python3 -m pip install --quiet twine
124+
python3 -m twine check --strict dist/*.whl
125+
126+
- uses: actions/upload-artifact@v4
127+
with:
128+
name: mcpp-bin-wheels
129+
path: dist/*.whl
130+
if-no-files-found: error
131+
132+
# pip, not this workflow, picks the wheel: each runner installs from the
133+
# directory of all four, so a wrong platform tag fails here rather than on a
134+
# user's machine. The run then checks the two properties the launcher exists
135+
# for: the per-user home is outside the Python environment, and the bundled
136+
# xlings is the one seeded into it.
137+
smoke:
138+
name: pip install (${{ matrix.os }})
139+
needs: build
140+
strategy:
141+
fail-fast: false
142+
matrix:
143+
os: [ubuntu-24.04, ubuntu-24.04-arm, macos-14, windows-latest]
144+
runs-on: ${{ matrix.os }}
145+
timeout-minutes: 20
146+
steps:
147+
- uses: actions/setup-python@v5
148+
with:
149+
python-version: '3.12'
150+
- uses: actions/download-artifact@v4
151+
with:
152+
name: mcpp-bin-wheels
153+
path: dist
154+
- name: Install and run
155+
shell: bash
156+
env:
157+
VERSION: ${{ needs.build.outputs.version }}
158+
run: |
159+
set -euo pipefail
160+
python -m venv venv
161+
if [[ -x venv/Scripts/python.exe ]]; then py=venv/Scripts/python.exe; bin=venv/Scripts; else py=venv/bin/python; bin=venv/bin; fi
162+
"$py" -m pip install --quiet --no-index --find-links dist mcpp-bin
163+
home="$RUNNER_TEMP/home"; mkdir -p "$home"
164+
export HOME="$home" USERPROFILE="$home"
165+
unset MCPP_HOME MCPP_VENDORED_XLINGS
166+
out="$("$bin/mcpp" --version)"
167+
echo "$out"
168+
[[ "$out" == *"$VERSION"* ]] || { echo "::error::expected $VERSION, got: $out"; exit 1; }
169+
"$bin/mcpp" self env | tee env.txt
170+
grep -F "MCPP_HOME" env.txt | grep -F ".mcpp" \
171+
|| { echo "::error::MCPP_HOME is not the per-user home"; exit 1; }
172+
if grep -F "MCPP_HOME" env.txt | grep -qF "site-packages"; then
173+
echo "::error::MCPP_HOME resolved into the Python environment"; exit 1
174+
fi
175+
# On Windows mcpp runs the vendored xlings in place (src/config.cppm,
176+
# make_xlings_env), so the seeded copy is checked on POSIX only.
177+
if [[ "$RUNNER_OS" != "Windows" ]]; then
178+
ls "$home/.mcpp/registry/bin/" | grep -q '^xlings' \
179+
|| { echo "::error::the bundled xlings was not seeded into the home"; exit 1; }
180+
fi
181+
182+
publish:
183+
name: publish to PyPI
184+
needs: [build, smoke]
185+
if: needs.build.outputs.publish == 'true'
186+
runs-on: ubuntu-24.04
187+
timeout-minutes: 15
188+
environment:
189+
name: pypi
190+
url: https://pypi.org/project/mcpp-bin/${{ needs.build.outputs.version }}/
191+
permissions:
192+
id-token: write
193+
steps:
194+
- uses: actions/download-artifact@v4
195+
with:
196+
name: mcpp-bin-wheels
197+
path: dist
198+
- uses: pypa/gh-action-pypi-publish@release/v1
199+
with:
200+
packages-dir: dist/

README.md

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,12 @@
1313
|:---:|
1414
| [Package index mcpp-index](https://mcpplibs.github.io/mcpp-index/) · [Module libraries mcpplibs](https://github.com/mcpplibs) · [Community Forum](https://forum.d2learn.org/category/20) · [Issues](https://github.com/mcpp-community/mcpp/issues) · [Releases](https://github.com/mcpp-community/mcpp/releases) |
1515
| [![ci-linux](https://github.com/mcpp-community/mcpp/actions/workflows/ci-linux.yml/badge.svg?branch=main)](https://github.com/mcpp-community/mcpp/actions/workflows/ci-linux.yml) [![ci-macos](https://github.com/mcpp-community/mcpp/actions/workflows/ci-macos.yml/badge.svg?branch=main)](https://github.com/mcpp-community/mcpp/actions/workflows/ci-macos.yml) [![ci-windows](https://github.com/mcpp-community/mcpp/actions/workflows/ci-windows.yml/badge.svg?branch=main)](https://github.com/mcpp-community/mcpp/actions/workflows/ci-windows.yml) |
16+
| Plugins · [mcpp-language-server (mcppls)](https://github.com/Sunrisepeak/mcpp-language-server) — a C++20/23 modules language server for VS Code, Zed, CLion, Neovim, AI agents (MCP) and CI |
1617

1718
<p align="center">
1819
<img src="https://github.com/user-attachments/assets/6c85896e-9a37-4f62-acfb-d37a4eae2363" alt="mcpp demo" width="720">
1920
</p>
2021

21-
> **Note (2026.9.20.1):** the `[c-abi]` verification probe now selects the
22-
> target it is verifying. On a freestanding target it selected none and
23-
> answered for the build host, which on a Linux host passed for the wrong
24-
> reason and on a Windows host failed for one. The `hostStripMacros`
25-
> compensation 2026.9.18.3 added is removed with it. This release also adds
26-
> `[kernel-abi] provides-interfaces` / `requires-interfaces`, answered at
27-
> dependency resolution, and `[c-abi-absent]`, which states what a C library
28-
> does not supply and in what shape. See CHANGELOG and docs/22.
29-
3022
## Highlights
3123

3224
- **Modular build system** — C++ modules first: `import std` handled automatically, file-level incremental builds, automatic dependency analysis, nothing to configure
@@ -174,7 +166,23 @@ remain manually maintained and may intentionally lag.
174166
</details>
175167

176168
<details>
177-
<summary><b>Option 4</b> — let an AI assistant install it for you</summary>
169+
<summary><b>Option 4</b> — pip (PyPI)</summary>
170+
171+
```bash
172+
pip install mcpp-bin
173+
```
174+
175+
Installs the `mcpp` command into the active Python environment; `pipx install
176+
mcpp-bin` gives it an environment of its own. The wheels carry the same
177+
prebuilt release binary for Linux x86_64 / aarch64, macOS 14+ on Apple silicon
178+
and Windows x86_64. Per-user data still lives in `~/.mcpp/`, outside the Python
179+
environment. On PyPI the name `mcpp` belongs to an unrelated project, hence
180+
`mcpp-bin` (see [`scripts/pypi/`](scripts/pypi/)).
181+
182+
</details>
183+
184+
<details>
185+
<summary><b>Option 5</b> — let an AI assistant install it for you</summary>
178186

179187
Copy the following prompt to your AI coding assistant (Claude Code / Cursor / Copilot, etc.):
180188

0 commit comments

Comments
 (0)