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
12 changes: 6 additions & 6 deletions .github/workflows/fresh-install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -218,14 +218,14 @@ jobs:
include-hidden-files: true

released-course:
name: Published d2x install route (main only)
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' && inputs.candidate_run == ''
name: d2x download and pinned install
if: ${{ !inputs.diagnose && inputs.candidate_run == '' }}
runs-on: ubuntu-24.04
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
- name: Follow the README using the public course download
run: python3 scripts/ci/readme.py --published
- name: Verify the documented existing-d2x download route
run: python3 scripts/ci/readme.py --d2x-download ${{ github.event_name != 'pull_request' && github.ref == 'refs/heads/main' && '--published' || '' }}
- uses: actions/upload-artifact@v4
if: always()
with:
Expand Down Expand Up @@ -265,7 +265,7 @@ jobs:
include-hidden-files: true

latest-stable:
if: github.ref == 'refs/heads/main' && inputs.candidate_run == ''
if: ${{ !inputs.diagnose && inputs.candidate_run == '' }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
Expand All @@ -280,7 +280,7 @@ jobs:
if: runner.os == 'Windows'
shell: powershell
run: ./scripts/install-xlings.ps1
- name: Check stable release, public latest and course pin
- name: Check public latest and independently restore course pins
shell: bash
env:
GH_TOKEN: ${{ github.token }}
Expand Down
7 changes: 2 additions & 5 deletions .github/workflows/online-ebook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ jobs:
run:
working-directory: book

env:
MDBOOK_VERSION: 0.4.43

steps:
- uses: actions/checkout@v4

Expand All @@ -57,8 +54,8 @@ jobs:
- name: Install the shared xlings baseline
run: bash ../scripts/install-xlings.sh

- name: Install mdBook
run: xlings install mdbook@${MDBOOK_VERSION} -y
- name: Install the course dependencies from .xlings.json
run: xlings install -y

- name: Setup Pages
if: github.event_name != 'pull_request'
Expand Down
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,24 @@ Wait for the environment to be ready, then run `d2x checker` in the terminal.

### Practice locally

**1. Install the tools**
**1. Get the course**

Install [xlings](docs/environment.md#install-xlings), reopen your terminal, then run:
Install [xlings](docs/environment.md#install-xlings) and Git, then reopen your terminal.

```bash
xlings update
xlings install --use d2x@latest mcpp@latest -y
git clone https://github.com/mcpp-community/d2mcpp.git
cd d2mcpp
```

**2. Get the course**
**2. Install the course versions**

```bash
d2x install d2mcpp
cd d2mcpp
xlings update
xlings install -y
```

Run these commands from the course directory. `xlings install` installs the versions declared in `.xlings.json`; after updating the course with Git, run the same two commands again.

**3. Verify and practice**

```bash
Expand Down
16 changes: 9 additions & 7 deletions README.zh.hant.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,24 @@

### 建立本地練習環境

**第一步:安裝工具**
**第一步:取得課程**

安裝 [xlings](docs/environment.zh.md#install-xlings),重新開啟終端後執行:
安裝 [xlings](docs/environment.zh.md#install-xlings) 和 Git,然後重新開啟終端。

```bash
xlings update
xlings install --use d2x@latest mcpp@latest -y
git clone https://github.com/mcpp-community/d2mcpp.git
cd d2mcpp
```

**第二步:取得課程**
**第二步:安裝課程版本**

```bash
d2x install d2mcpp
cd d2mcpp
xlings update
xlings install -y
```

在課程目錄執行上述命令。`xlings install` 安裝 `.xlings.json` 宣告的版本;透過 Git 更新課程後,再次執行這兩條命令。

**第三步:驗證並開始練習**

```bash
Expand Down
16 changes: 9 additions & 7 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,24 @@

### 搭建本地练习环境

**第一步:安装工具**
**第一步:获取课程**

安装 [xlings](docs/environment.zh.md#install-xlings),重新打开终端后执行:
安装 [xlings](docs/environment.zh.md#install-xlings) 和 Git,然后重新打开终端。

```bash
xlings update
xlings install --use d2x@latest mcpp@latest -y
git clone https://github.com/mcpp-community/d2mcpp.git
cd d2mcpp
```

**第二步:获取课程**
**第二步:安装课程版本**

```bash
d2x install d2mcpp
cd d2mcpp
xlings update
xlings install -y
```

在课程目录执行上述命令。`xlings install` 安装 `.xlings.json` 声明的版本;通过 Git 更新课程后,再次执行这两条命令。

**第三步:验证并开始练习**

```bash
Expand Down
24 changes: 5 additions & 19 deletions book/en/src/base/chapter_1.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,32 +40,18 @@ $env:Path = "$env:USERPROFILE\.xlings\subos\current\bin;$env:Path"
The PATH command makes the installed tools available in this terminal. For future sessions, reopen your terminal after installation. Preparation can be repeated and preserves your exercise files and progress.

<details>
<summary>Alternative: download with d2x install</summary>
<summary>Alternative: download with an existing d2x</summary>

Install [xlings](https://github.com/openxlings/xlings) first:
If d2x is already installed, use the commands below. After downloading, run `xlings install -y` from the course directory to install the `.xlings.json` dependencies. There is no need to preinstall mcpp or select latest.

```bash
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/v2026.10.18.1/tools/other/quick_install.sh | bash -s v2026.10.18.1
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
```

Or on Windows PowerShell:

```powershell
irm https://raw.githubusercontent.com/mcpp-community/d2mcpp/main/scripts/install-xlings.ps1 | iex
$env:Path = "$env:USERPROFILE\.xlings\subos\current\bin;$env:Path"
```

Then, on either system:

```text
xlings update
xlings install --use d2x@latest mcpp@latest -y
d2x install d2mcpp
cd d2mcpp
xlings update
xlings install -y
```

Continue with the preparation script for your system in step 2; both download routes use the same verification below.
Then continue with the preparation script in step 2. Apply project pins again after updating the course.

</details>

Expand Down
7 changes: 7 additions & 0 deletions book/en/src/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@

## 2026/10

**Install dependencies from the course manifest**

Get the course before running `xlings install -y` to install the versions pinned in `.xlings.json`. Align update instructions and verify both Git and d2x downloads in CI. Check upstream latest independently of course dependency upgrades.

- `Book`: [zh](https://mcpp-community.github.io/d2mcpp/base/chapter_1.html) / [en](https://mcpp-community.github.io/d2mcpp/en/base/chapter_1.html) - 2026/10/21
- `Code`: [first-use CI](https://github.com/mcpp-community/d2mcpp/blob/main/.github/workflows/fresh-install.yml) - 2026/10/21

**d2x upgrade and cold-start diagnostics**

Upgrade d2x to 2026.10.21.1 and verify the selected executable; bound first Provider startup separately, show preparation and retain raw logs.
Expand Down
24 changes: 5 additions & 19 deletions book/src/base/chapter_1.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,32 +40,18 @@ $env:Path = "$env:USERPROFILE\.xlings\subos\current\bin;$env:Path"
PATH 命令让当前终端立即找到工具;安装后重新打开终端即可供后续会话使用。准备脚本可重复执行,不会改动练习文件或学习进度。

<details>
<summary>可选:通过 d2x install 下载课程</summary>
<summary>可选:通过已有 d2x 下载课程</summary>

先安装 [xlings](https://github.com/openxlings/xlings):
如果已经安装 d2x,可以使用以下方式。下载后在课程目录执行 `xlings install -y`,按 `.xlings.json` 安装依赖,无需提前安装 mcpp 或选择 latest。

```bash
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/v2026.10.18.1/tools/other/quick_install.sh | bash -s v2026.10.18.1
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
```

Windows PowerShell 使用:

```powershell
irm https://raw.githubusercontent.com/mcpp-community/d2mcpp/main/scripts/install-xlings.ps1 | iex
$env:Path = "$env:USERPROFILE\.xlings\subos\current\bin;$env:Path"
```

然后在任一系统执行:

```text
xlings update
xlings install --use d2x@latest mcpp@latest -y
d2x install d2mcpp
cd d2mcpp
xlings update
xlings install -y
```

继续执行第二步中对应系统的准备脚本;两种下载方式共用下面的验证步骤。
之后继续第二步的准备脚本。更新课程后同样按项目配置安装依赖。

</details>

Expand Down
7 changes: 7 additions & 0 deletions book/src/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@

## 2026/10

**按课程配置安装依赖**

默认先获取课程,再由 `xlings install -y` 安装 `.xlings.json` 固定的版本;统一更新说明,并在 CI 验证 Git 与 d2x 下载路径。上游 latest 检查独立于课程版本升级。

- `Book`: [zh](https://mcpp-community.github.io/d2mcpp/base/chapter_1.html) / [en](https://mcpp-community.github.io/d2mcpp/en/base/chapter_1.html) - 2026/10/21
- `Code`: [first-use CI](https://github.com/mcpp-community/d2mcpp/blob/main/.github/workflows/fresh-install.yml) - 2026/10/21

**d2x 最新版联动与冷启动诊断**

升级 d2x 至 2026.10.21.1,核对实际执行版本;首次 Provider 构建单独限时,显示准备进度并保留原始日志。
Expand Down
20 changes: 18 additions & 2 deletions docs/environment.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Continue with the README. If a command is not found, reopen your terminal or app

## Git installation and updates

After installing xlings, you can also clone the course. Replace the URL with your fork if needed:
After installing xlings, clone the course as shown in the README. Replace the URL with your fork if needed:

```bash
git clone https://github.com/mcpp-community/d2mcpp.git
Expand Down Expand Up @@ -104,6 +104,22 @@ limit. Preparation messages do not extend the startup deadline. On failure, keep
`.d2x/provider.stdout.log`, `.d2x/provider.stderr.log` and the command output.
Startup/transport errors exit nonzero; an unfinished exercise verdict is expected.

For an existing tool installation, use `xlings install --use d2x@latest mcpp@latest -y` after `xlings update`. `@latest` selects the newest stable index entry; `--use` activates it even when already installed. Bare install commands can retain the previously selected version.
From an existing course directory, install or restore the versions declared in `.xlings.json` with the commands below. `xlings update` refreshes the package index; `xlings install -y` installs the project dependencies. Use the course pins rather than `@latest`. Dependency upgrades belong in `.xlings.json` and must pass CI before publication.

```bash
xlings update
xlings install -y
```

User cancellation returns 130 and a `cancelled` event without a Provider-failure warning or a failed exercise verdict.

## Download with an existing d2x

If d2x is already available, you can use this download route. The installer applies the downloaded course dependencies; running `xlings install -y` from the course directory explicitly reapplies its pins. There is no need to preinstall mcpp or select latest.

```bash
d2x install d2mcpp
cd d2mcpp
xlings update
xlings install -y
```
18 changes: 17 additions & 1 deletion docs/environment.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,22 @@ checker 在第一题之前显示准备信息。首次 Provider 启动的总期
准备提示不会延长期限。失败时保留 `.d2x/provider.stdout.log`、`.d2x/provider.stderr.log` 与命令输出。
启动和传输错误会非零退出;未完成练习的 fail 判定属于预期行为。

已有工具环境先执行 `xlings update`,再执行 `xlings install --use d2x@latest mcpp@latest -y`。`@latest` 选择最新稳定条目;`--use` 即使新版已安装也会激活它。仅执行不带版本或激活选项的 install 可能继续保留旧版。
在已有课程目录中,执行以下命令安装或恢复 `.xlings.json` 声明的版本。`xlings update` 刷新包索引;`xlings install -y` 按项目配置安装依赖。不要用 `@latest` 替代课程版本。升级依赖应先修改 `.xlings.json`,通过 CI 后发布。

```bash
xlings update
xlings install -y
```

用户取消返回 130 和 `cancelled` 事件,不报告 Provider 故障,也不生成练习失败判定。

## 通过已有 d2x 下载课程

如果已经安装 d2x,可以使用以下下载方式。安装器会应用下载课程中的依赖配置;进入课程目录后再次运行 `xlings install -y` 可明确核对安装。无需提前安装 mcpp 或切换到 latest。

```bash
d2x install d2mcpp
cd d2mcpp
xlings update
xlings install -y
```
24 changes: 21 additions & 3 deletions scripts/ci/latest.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#!/usr/bin/env python3
"""Compare the stable d2x release, course pin and real public latest install."""
"""Verify public latest independently, then verify the reviewed project pins."""
import json
import os
from pathlib import Path
import subprocess
import tempfile
import urllib.request

from versions import verify

root = Path(__file__).resolve().parents[2]
logs = root / '.d2x/ci-logs'
logs.mkdir(parents=True, exist_ok=True)
Expand All @@ -25,8 +27,24 @@
assert old == '2026.08.02.2', 'Old-version activation fixture failed'
subprocess.run(['xlings', 'install', '--use', 'd2x@latest', '-y'], cwd=neutral, check=True)
actual = subprocess.check_output(['d2x', '--version'], cwd=neutral, text=True).strip()
report = {'previous': old, 'latest': latest, 'course_pin': pin, 'public_install': actual, 'release': release['html_url']}
# Deliberately keep a project behind latest to exercise version isolation,
# even when the real course pin currently equals the latest release.
project = Path(neutral) / 'older-course'
project.mkdir()
fixture = json.dumps({'workspace': {'d2x': old}}) + '\n'
(project / '.xlings.json').write_text(fixture)
subprocess.run(['xlings', 'install', '-y'], cwd=project, check=True)
selected = subprocess.check_output(['d2x', '--version'], cwd=project, text=True).strip()
assert selected == old, f'Project pin ignored: {selected}; expected {old}'
assert (project / '.xlings.json').read_text() == fixture, 'Install rewrote the fixture pin'
outside = subprocess.check_output(['d2x', '--version'], cwd=neutral, text=True).strip()
assert outside == actual, 'Project install changed the global selection'
report = {'previous': old, 'latest': latest, 'course_pin': pin, 'public_install': actual, 'release': release['html_url'], 'older_project_selection': selected, 'global_after_project_install': outside}
(logs / 'latest.json').write_text(json.dumps(report, indent=2))
print(json.dumps(report, indent=2), flush=True)
assert actual == latest, 'Public index/install is behind the stable release'
assert pin == latest, 'Bump the course pin and run the full first-use matrix for the new stable release'
# A new upstream release must not force an unreviewed course dependency bump.
manifest = (root / '.xlings.json').read_bytes()
subprocess.run(['xlings', 'install', '-y'], cwd=root, check=True)
verify(label='pinned-after-latest')
assert (root / '.xlings.json').read_bytes() == manifest, 'Install changed the reviewed manifest'
Loading
Loading