Skip to content

Commit f36aced

Browse files
Sunrisepeakclaude
andcommitted
add multi-platform CI with reusable toolchain setup
- Extract xlings + toolchain install into composite action - Single build job per OS, toolchain installed once and shared - Per-package change detection skips unaffected builds - Build from tests/ directory for correct add_repositories path - Remove llmapi C API (capi) - not implemented in upstream yet - Fix macOS 403: use GITHUB_TOKEN via .netrc for authenticated downloads - Fix macOS C++23 modules: specify --toolchain=llvm in configure Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1048fde commit f36aced

File tree

7 files changed

+251
-36
lines changed

7 files changed

+251
-36
lines changed

.agents/skills/mcpplibs-index-add.md

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ This skill adds a new library from `https://github.com/mcpplibs/<name>` to the m
1414
- xmake package docs: https://xmake.io/mirror/manual/package_dependencies.html
1515
- mcpplibs org: https://github.com/mcpplibs
1616
- index repo: https://github.com/mcpplibs/mcpplibs-index
17+
- xlings CI reference (cross-platform C++23 toolchain): https://github.com/d2learn/xlings/tree/main/.github/workflows
1718

1819
## Step 1: Gather Library Info
1920

@@ -110,7 +111,11 @@ Add an `includes()` line to `tests/xmake.lua`:
110111
includes("<first-letter>/<package-name>")
111112
```
112113

113-
## Step 6: Verify Build
114+
## Step 6: Update CI
115+
116+
Add a new job to `.github/workflows/ci.yml` for the package. Each package has its own job with path-based triggering. Add path filter in `detect-changes` job and a new job block (see existing jobs as template). Also add the package paths to the top-level `on.push.paths` and `on.pull_request.paths`.
117+
118+
## Step 7: Verify Build
114119

115120
```bash
116121
# Clean any cached package
@@ -129,20 +134,69 @@ xmake run <package-name>_test
129134

130135
All three commands must succeed before proceeding.
131136

132-
## Step 7: Create Branch, Commit & Push
137+
## Step 8: Create Branch, Commit & Push
133138

134139
```bash
135140
git checkout -b add-<repo-name>-library
136141
git add packages/<first-letter>/<package-name>/xmake.lua \
137142
tests/<first-letter>/<package-name>/xmake.lua \
138143
tests/<first-letter>/<package-name>/main.cpp \
139-
tests/xmake.lua
144+
tests/xmake.lua \
145+
.github/workflows/ci.yml
140146
git commit -m "add <package-name> library"
141147
git push -u upstream add-<repo-name>-library
142148
```
143149

144150
Use `upstream` (SSH remote) for push, not `origin` (HTTPS, no auth).
145151

152+
## C++23 Toolchain Reference
153+
154+
All mcpplibs packages require C++23 with modules support. Below are the toolchain configurations for each platform, referenced from [xlings CI](https://github.com/d2learn/xlings/tree/main/.github/workflows).
155+
156+
All toolchains are installed via [xlings](https://github.com/d2learn/xlings). xlings bundles xmake, no separate install needed.
157+
158+
### Install xlings
159+
160+
```bash
161+
# Linux / macOS
162+
curl -fsSL https://raw.githubusercontent.com/d2learn/xlings/main/tools/other/quick_install.sh | bash
163+
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
164+
165+
# Windows (PowerShell)
166+
irm https://raw.githubusercontent.com/d2learn/xlings/refs/heads/main/tools/other/quick_install.ps1 | iex
167+
$env:PATH = "$env:USERPROFILE\.xlings\subos\current\bin;$env:PATH"
168+
```
169+
170+
### Linux — GCC 15 (Ubuntu 24.04)
171+
172+
```bash
173+
xlings install gcc@15 -y
174+
xmake f -y
175+
```
176+
177+
### macOS — LLVM 20 (macOS 15)
178+
179+
```bash
180+
xlings install llvm@20 -y
181+
xmake f -y
182+
```
183+
184+
### Windows — MSVC (windows-latest)
185+
186+
```bash
187+
xmake f -y # auto-selects MSVC
188+
```
189+
190+
No special configuration needed. MSVC from Visual Studio supports C++23.
191+
192+
### Toolchain Version Summary
193+
194+
| Platform | Compiler | Version | Install |
195+
|----------|----------|---------|---------|
196+
| Linux | GCC | 15.1.0 | `xlings install gcc@15 -y` |
197+
| macOS | LLVM/Clang | 20 | `xlings install llvm@20 -y` |
198+
| Windows | MSVC | latest | auto-detected |
199+
146200
## Checklist
147201

148202
- [ ] Package directory name == `package("xxx")` name
@@ -151,6 +205,7 @@ Use `upstream` (SSH remote) for push, not `origin` (HTTPS, no auth).
151205
- [ ] Extra headers copied in `on_install` if needed by cppm
152206
- [ ] Test does NOT have `add_repositories()` (top-level handles it)
153207
- [ ] Test registered in `tests/xmake.lua` via `includes()`
208+
- [ ] CI matrix updated with new test entry
154209
- [ ] `xmake build` succeeds
155210
- [ ] `xmake run` produces expected output
156211
- [ ] Committed and pushed to upstream
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Setup C++23 Toolchain
2+
description: Install xlings and C++23 toolchain for the current platform
3+
4+
inputs:
5+
github-token:
6+
description: GitHub token for authenticated downloads (avoids rate limits)
7+
required: false
8+
default: ''
9+
10+
runs:
11+
using: composite
12+
steps:
13+
- name: Setup GitHub auth (unix)
14+
if: runner.os != 'Windows' && inputs.github-token != ''
15+
shell: bash
16+
run: |
17+
echo "machine github.com login x-access-token password ${{ inputs.github-token }}" >> ~/.netrc
18+
echo "machine objects.githubusercontent.com login x-access-token password ${{ inputs.github-token }}" >> ~/.netrc
19+
chmod 600 ~/.netrc
20+
- name: Setup (unix)
21+
if: runner.os != 'Windows'
22+
shell: bash
23+
run: curl -fsSL https://raw.githubusercontent.com/d2learn/xlings/main/tools/other/quick_install.sh | bash
24+
- name: Setup (windows)
25+
if: runner.os == 'Windows'
26+
shell: pwsh
27+
run: irm https://raw.githubusercontent.com/d2learn/xlings/refs/heads/main/tools/other/quick_install.ps1 | iex
28+
- name: Install toolchain (linux)
29+
if: runner.os == 'Linux'
30+
shell: bash
31+
run: |
32+
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
33+
xlings install gcc@15 -y
34+
- name: Install toolchain (macos)
35+
if: runner.os == 'macOS'
36+
shell: bash
37+
run: |
38+
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
39+
xlings install llvm@20 -y

.github/workflows/ci.yml

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- 'packages/**'
8+
- 'tests/**'
9+
- '.github/workflows/ci.yml'
10+
pull_request:
11+
branches: [main]
12+
paths:
13+
- 'packages/**'
14+
- 'tests/**'
15+
- '.github/workflows/ci.yml'
16+
17+
env:
18+
XLINGS_NON_INTERACTIVE: 1
19+
20+
jobs:
21+
detect-changes:
22+
runs-on: ubuntu-24.04
23+
outputs:
24+
templates: ${{ steps.filter.outputs.templates }}
25+
cmdline: ${{ steps.filter.outputs.cmdline }}
26+
llmapi: ${{ steps.filter.outputs.llmapi }}
27+
lua: ${{ steps.filter.outputs.lua }}
28+
steps:
29+
- uses: actions/checkout@v4
30+
- uses: dorny/paths-filter@v3
31+
id: filter
32+
with:
33+
filters: |
34+
templates:
35+
- 'packages/t/templates/**'
36+
- 'tests/t/templates/**'
37+
- '.github/workflows/ci.yml'
38+
cmdline:
39+
- 'packages/c/cmdline/**'
40+
- 'tests/c/cmdline/**'
41+
- '.github/workflows/ci.yml'
42+
llmapi:
43+
- 'packages/l/llmapi/**'
44+
- 'tests/l/llmapi/**'
45+
- '.github/workflows/ci.yml'
46+
lua:
47+
- 'packages/m/mcpplibs-capi-lua/**'
48+
- 'tests/l/lua/**'
49+
- '.github/workflows/ci.yml'
50+
51+
build:
52+
needs: detect-changes
53+
if: >-
54+
needs.detect-changes.outputs.templates == 'true' ||
55+
needs.detect-changes.outputs.cmdline == 'true' ||
56+
needs.detect-changes.outputs.llmapi == 'true' ||
57+
needs.detect-changes.outputs.lua == 'true'
58+
strategy:
59+
fail-fast: false
60+
matrix:
61+
include:
62+
- { os: ubuntu-24.04, shell: bash }
63+
- { os: macos-15, shell: bash }
64+
- { os: windows-latest, shell: pwsh }
65+
runs-on: ${{ matrix.os }}
66+
name: build (${{ matrix.os }})
67+
steps:
68+
- uses: actions/checkout@v4
69+
- uses: ./.github/actions/setup-toolchain
70+
with:
71+
github-token: ${{ secrets.GITHUB_TOKEN }}
72+
73+
- name: Configure (linux)
74+
if: runner.os == 'Linux'
75+
working-directory: tests
76+
run: |
77+
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
78+
xmake f -P . -y
79+
80+
- name: Configure (macos)
81+
if: runner.os == 'macOS'
82+
working-directory: tests
83+
run: |
84+
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
85+
xmake f -P . -y --toolchain=llvm
86+
87+
- name: Configure (windows)
88+
if: runner.os == 'Windows'
89+
working-directory: tests
90+
run: |
91+
$env:PATH = "$env:USERPROFILE\.xlings\subos\current\bin;$env:PATH"
92+
xmake f -P . -y
93+
94+
# templates
95+
- name: templates (unix)
96+
if: runner.os != 'Windows' && needs.detect-changes.outputs.templates == 'true'
97+
working-directory: tests
98+
run: |
99+
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
100+
xmake build -P . -y templates_test
101+
xmake run -P . templates_test
102+
- name: templates (windows)
103+
if: runner.os == 'Windows' && needs.detect-changes.outputs.templates == 'true'
104+
working-directory: tests
105+
run: |
106+
$env:PATH = "$env:USERPROFILE\.xlings\subos\current\bin;$env:PATH"
107+
xmake build -P . -y templates_test
108+
xmake run -P . templates_test
109+
110+
# cmdline
111+
- name: cmdline (unix)
112+
if: runner.os != 'Windows' && needs.detect-changes.outputs.cmdline == 'true'
113+
working-directory: tests
114+
run: |
115+
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
116+
xmake build -P . -y cmdline_test
117+
xmake run -P . cmdline_test test_input
118+
- name: cmdline (windows)
119+
if: runner.os == 'Windows' && needs.detect-changes.outputs.cmdline == 'true'
120+
working-directory: tests
121+
run: |
122+
$env:PATH = "$env:USERPROFILE\.xlings\subos\current\bin;$env:PATH"
123+
xmake build -P . -y cmdline_test
124+
xmake run -P . cmdline_test test_input
125+
126+
# llmapi (build only, needs API key to run)
127+
- name: llmapi (unix)
128+
if: runner.os != 'Windows' && needs.detect-changes.outputs.llmapi == 'true'
129+
working-directory: tests
130+
run: |
131+
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
132+
xmake build -P . -y llmapi_test
133+
- name: llmapi (windows)
134+
if: runner.os == 'Windows' && needs.detect-changes.outputs.llmapi == 'true'
135+
working-directory: tests
136+
run: |
137+
$env:PATH = "$env:USERPROFILE\.xlings\subos\current\bin;$env:PATH"
138+
xmake build -P . -y llmapi_test
139+
140+
# lua
141+
- name: lua (unix)
142+
if: runner.os != 'Windows' && needs.detect-changes.outputs.lua == 'true'
143+
working-directory: tests
144+
run: |
145+
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
146+
xmake build -P . -y lua_test
147+
xmake run -P . lua_test
148+
- name: lua (windows)
149+
if: runner.os == 'Windows' && needs.detect-changes.outputs.lua == 'true'
150+
working-directory: tests
151+
run: |
152+
$env:PATH = "$env:USERPROFILE\.xlings\subos\current\bin;$env:PATH"
153+
xmake build -P . -y lua_test
154+
xmake run -P . lua_test

packages/l/llmapi/xmake.lua

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,10 @@ package("llmapi")
1414

1515
add_versions("0.0.1", "174f86d3afdf48a57ad1cc9688718d1f1100a78a7e56686c823c573c3ccf99f4")
1616

17-
add_configs("capi", {description = "Link with llmapi_c (C API) by default", default = false, type = "boolean"})
18-
1917
add_includedirs("include")
2018
add_deps("libcurl 8.11.0")
2119

2220
on_load(function (package)
23-
if package:config("capi") then
24-
package:add("links", "llmapi_c")
25-
end
2621
package:add("links", "llmapi")
2722
end)
2823

tests/l/llmapi/capi/main.c

Lines changed: 0 additions & 21 deletions
This file was deleted.

tests/l/llmapi/capi/xmake.lua

Lines changed: 0 additions & 6 deletions
This file was deleted.

tests/xmake.lua

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
add_repositories("mcpplibs-index ../")
22

33
includes("l/llmapi")
4-
includes("l/llmapi/capi")
54
includes("l/lua")
65
includes("c/cmdline")
76
includes("t/templates")

0 commit comments

Comments
 (0)