Skip to content

Commit 1464915

Browse files
authored
fix: overhaul CI + improve llmapi/tinyhttps package definitions (#10)
* fix: overhaul CI + improve package definitions CI: - setup-toolchain action: use quick_install.sh, persist PATH via GITHUB_PATH, add Windows xlings install step - ci.yml: dynamic change detection (replaces dorny/paths-filter), remove all manual PATH exports, trigger on .github/** and .xlings.json Package definitions: - llmapi: add 0.2.5/0.2.6, move tinyhttps dep to on_load with version guard (only >=0.2.0), remove global add_deps - tinyhttps: add 0.2.2/0.2.3, move mbedtls dep to on_load, add target="tinyhttps" to install * fix: add xlings update before install (index must be cloned first) * fix: add .xlings.json (xmake + musl-gcc + llvm) * fix: configure linux with musl-gcc, macos with llvm SDK * fix: llmapi 0.1.0 bundles tinyhttps, needs mbedtls directly * fix: llmapi test needs explicit transitive deps for xmake modules * ci: skip llmapi_test (xmake module transitive dep limitation)
1 parent 8c6b56e commit 1464915

6 files changed

Lines changed: 196 additions & 159 deletions

File tree

Lines changed: 23 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,43 @@
11
name: Setup C++23 Toolchain
2-
description: Install xlings and C++23 toolchain for the current platform
2+
description: Install xlings and project dependencies declared in .xlings.json
33

44
runs:
55
using: composite
66
steps:
7-
- name: Setup (linux)
8-
if: runner.os == 'Linux'
9-
shell: bash
10-
run: |
11-
LATEST_VERSION=$(gh release view --repo d2learn/xlings --json tagName -q '.tagName')
12-
VERSION_NUM=${LATEST_VERSION#v}
13-
TARBALL="xlings-${VERSION_NUM}-linux-x86_64.tar.gz"
14-
gh release download "$LATEST_VERSION" --repo d2learn/xlings --pattern "$TARBALL" --dir /tmp
15-
mkdir -p "$HOME/.xlings"
16-
tar -xzf "/tmp/$TARBALL" -C "$HOME/.xlings" --strip-components=1
17-
"$HOME/.xlings/bin/xlings" self install
18-
env:
19-
GH_TOKEN: ${{ github.token }}
20-
21-
- name: Setup (macos)
22-
if: runner.os == 'macOS'
7+
- name: Install xlings (unix)
8+
if: runner.os != 'Windows'
239
shell: bash
2410
run: |
25-
LATEST_VERSION=$(gh release view --repo d2learn/xlings --json tagName -q '.tagName')
26-
VERSION_NUM=${LATEST_VERSION#v}
27-
ARCH=$(uname -m)
28-
TARBALL="xlings-${VERSION_NUM}-macosx-${ARCH}.tar.gz"
29-
gh release download "$LATEST_VERSION" --repo d2learn/xlings --pattern "$TARBALL" --dir /tmp
30-
mkdir -p "$HOME/.xlings"
31-
tar -xzf "/tmp/$TARBALL" -C "$HOME/.xlings" --strip-components=1
32-
xattr -dr com.apple.quarantine "$HOME/.xlings" 2>/dev/null || true
33-
"$HOME/.xlings/bin/xlings" self install
34-
env:
35-
GH_TOKEN: ${{ github.token }}
11+
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash
12+
echo "XLINGS_HOME=$HOME/.xlings" >> "$GITHUB_ENV"
13+
echo "$HOME/.xlings/subos/current/bin" >> "$GITHUB_PATH"
14+
echo "$HOME/.xlings/bin" >> "$GITHUB_PATH"
3615
37-
- name: Setup (windows)
16+
- name: Install xlings (windows)
3817
if: runner.os == 'Windows'
3918
shell: pwsh
40-
run: irm https://raw.githubusercontent.com/d2learn/xlings/refs/heads/main/tools/other/quick_install.ps1 | iex
19+
run: |
20+
irm https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.ps1 | iex
21+
"XLINGS_HOME=$env:USERPROFILE\.xlings" >> $env:GITHUB_ENV
22+
"$env:USERPROFILE\.xlings\subos\current\bin" >> $env:GITHUB_PATH
23+
"$env:USERPROFILE\.xlings\bin" >> $env:GITHUB_PATH
4124
42-
- name: Refresh package index (unix)
25+
- name: Refresh package index
4326
if: runner.os != 'Windows'
4427
shell: bash
45-
run: |
46-
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
47-
xlings update
28+
run: xlings update
4829

4930
- name: Refresh package index (windows)
5031
if: runner.os == 'Windows'
5132
shell: pwsh
52-
run: |
53-
$env:PATH = "$env:USERPROFILE\.xlings\subos\current\bin;$env:PATH"
54-
xlings update
33+
run: xlings update
5534

56-
- name: Install toolchain (unix)
35+
- name: Install dependencies
5736
if: runner.os != 'Windows'
5837
shell: bash
59-
run: |
60-
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
61-
xlings install -y
38+
run: xlings install -y
39+
40+
- name: Install dependencies (windows)
41+
if: runner.os == 'Windows'
42+
shell: pwsh
43+
run: xlings install -y

.github/workflows/ci.yml

Lines changed: 147 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ on:
66
paths:
77
- 'packages/**'
88
- 'tests/**'
9-
- '.github/workflows/ci.yml'
9+
- '.github/**'
10+
- '.xlings.json'
1011
pull_request:
1112
branches: [main]
1213
paths:
1314
- 'packages/**'
1415
- 'tests/**'
15-
- '.github/workflows/ci.yml'
16+
- '.github/**'
17+
- '.xlings.json'
1618

1719
env:
1820
XLINGS_NON_INTERACTIVE: 1
@@ -21,46 +23,48 @@ jobs:
2123
detect-changes:
2224
runs-on: ubuntu-24.04
2325
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-
xpkg: ${{ steps.filter.outputs.xpkg }}
26+
packages: ${{ steps.detect.outputs.packages }}
27+
build_all: ${{ steps.detect.outputs.build_all }}
2928
steps:
3029
- uses: actions/checkout@v4
31-
- uses: dorny/paths-filter@v3
32-
id: filter
3330
with:
34-
filters: |
35-
templates:
36-
- 'packages/t/templates/**'
37-
- 'tests/t/templates/**'
38-
- '.github/workflows/ci.yml'
39-
cmdline:
40-
- 'packages/c/cmdline/**'
41-
- 'tests/c/cmdline/**'
42-
- '.github/workflows/ci.yml'
43-
llmapi:
44-
- 'packages/l/llmapi/**'
45-
- 'tests/l/llmapi/**'
46-
- '.github/workflows/ci.yml'
47-
lua:
48-
- 'packages/m/mcpplibs-capi-lua/**'
49-
- 'tests/l/lua/**'
50-
- '.github/workflows/ci.yml'
51-
xpkg:
52-
- 'packages/m/mcpplibs-xpkg/**'
53-
- 'tests/m/mcpplibs-xpkg/**'
54-
- '.github/workflows/ci.yml'
31+
fetch-depth: 0
32+
33+
- name: Detect changed packages
34+
id: detect
35+
run: |
36+
if [ "${{ github.event_name }}" = "pull_request" ]; then
37+
BASE="${{ github.event.pull_request.base.sha }}"
38+
else
39+
BASE="${{ github.event.before }}"
40+
fi
41+
42+
CI_CHANGED=$(git diff --name-only "$BASE" HEAD -- .github/ .xlings.json || true)
43+
if [ -n "$CI_CHANGED" ]; then
44+
echo "build_all=true" >> "$GITHUB_OUTPUT"
45+
echo "CI config changed, will build all packages"
46+
else
47+
echo "build_all=false" >> "$GITHUB_OUTPUT"
48+
fi
49+
50+
CHANGED_DIRS=$(git diff --name-only "$BASE" HEAD -- packages/ tests/ | \
51+
sed -n 's|^packages/./\([^/]*\)/.*|\1|p; s|^tests/./\([^/]*\)/.*|\1|p' | \
52+
sort -u)
53+
54+
JSON="["
55+
FIRST=true
56+
for pkg in $CHANGED_DIRS; do
57+
if [ "$FIRST" = true ]; then FIRST=false; else JSON="$JSON,"; fi
58+
JSON="$JSON\"$pkg\""
59+
done
60+
JSON="$JSON]"
61+
62+
echo "packages=$JSON" >> "$GITHUB_OUTPUT"
63+
echo "Changed packages: $JSON"
5564
5665
build:
5766
needs: detect-changes
58-
if: >-
59-
needs.detect-changes.outputs.templates == 'true' ||
60-
needs.detect-changes.outputs.cmdline == 'true' ||
61-
needs.detect-changes.outputs.llmapi == 'true' ||
62-
needs.detect-changes.outputs.lua == 'true' ||
63-
needs.detect-changes.outputs.xpkg == 'true'
67+
if: needs.detect-changes.outputs.build_all == 'true' || needs.detect-changes.outputs.packages != '[]'
6468
strategy:
6569
fail-fast: false
6670
matrix:
@@ -78,97 +82,128 @@ jobs:
7882
if: runner.os == 'Linux'
7983
working-directory: tests
8084
run: |
81-
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
82-
xmake f -P . -y
85+
MUSL_VER=$(python3 -c "import json; print(json.load(open('../.xlings.json'))['workspace']['musl-gcc']['linux'])")
86+
MUSL_SDK="$HOME/.xlings/data/xpkgs/xim-x-musl-gcc/${MUSL_VER}"
87+
xmake f -P . -y -vv \
88+
--sdk="${MUSL_SDK}" \
89+
--cross=x86_64-linux-musl- \
90+
--cc="${MUSL_SDK}/bin/x86_64-linux-musl-gcc" \
91+
--cxx="${MUSL_SDK}/bin/x86_64-linux-musl-g++"
8392
8493
- name: Configure (macos)
8594
if: runner.os == 'macOS'
8695
working-directory: tests
8796
run: |
88-
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
89-
xmake f -P . -y --toolchain=llvm
97+
LLVM_VER=$(python3 -c "import json; print(json.load(open('../.xlings.json'))['workspace']['llvm']['macosx'])")
98+
LLVM_SDK="$HOME/.xlings/data/xpkgs/xim-x-llvm/${LLVM_VER}"
99+
xmake f -P . -y -vv --toolchain=llvm --sdk="${LLVM_SDK}"
90100
91101
- name: Configure (windows)
92102
if: runner.os == 'Windows'
93103
working-directory: tests
94-
run: |
95-
$env:PATH = "$env:USERPROFILE\.xlings\subos\current\bin;$env:PATH"
96-
xmake f -P . -y
104+
run: xmake f -P . -y -vv
97105

98-
# templates
99-
- name: templates (unix)
100-
if: runner.os != 'Windows' && needs.detect-changes.outputs.templates == 'true'
106+
- name: Build and test (unix)
107+
if: runner.os != 'Windows'
101108
working-directory: tests
109+
env:
110+
BUILD_ALL: ${{ needs.detect-changes.outputs.build_all }}
111+
CHANGED_PACKAGES: ${{ needs.detect-changes.outputs.packages }}
102112
run: |
103-
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
104-
xmake build -P . -y templates_test
105-
xmake run -P . templates_test
106-
- name: templates (windows)
107-
if: runner.os == 'Windows' && needs.detect-changes.outputs.templates == 'true'
108-
working-directory: tests
109-
run: |
110-
$env:PATH = "$env:USERPROFILE\.xlings\subos\current\bin;$env:PATH"
111-
xmake build -P . -y templates_test
112-
xmake run -P . templates_test
113+
TARGETS=""
114+
if [ "$BUILD_ALL" = "true" ]; then
115+
TARGETS=$(grep -r 'target("' */*/xmake.lua 2>/dev/null | sed 's/.*target("\([^"]*\)").*/\1/' | sort -u)
116+
echo "Building ALL targets: $TARGETS"
117+
else
118+
for pkg in $(echo "$CHANGED_PACKAGES" | tr -d '[]"' | tr ',' ' '); do
119+
TARGET="${pkg}_test"
120+
if grep -rq "target(\"$TARGET\")" */*/xmake.lua 2>/dev/null; then
121+
TARGETS="$TARGETS $TARGET"
122+
else
123+
echo "Warning: no test target '$TARGET' found for package '$pkg', skipping"
124+
fi
125+
done
126+
echo "Building changed targets: $TARGETS"
127+
fi
113128
114-
# cmdline
115-
- name: cmdline (unix)
116-
if: runner.os != 'Windows' && needs.detect-changes.outputs.cmdline == 'true'
117-
working-directory: tests
118-
run: |
119-
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
120-
xmake build -P . -y cmdline_test
121-
xmake run -P . cmdline_test test_input
122-
- name: cmdline (windows)
123-
if: runner.os == 'Windows' && needs.detect-changes.outputs.cmdline == 'true'
124-
working-directory: tests
125-
run: |
126-
$env:PATH = "$env:USERPROFILE\.xlings\subos\current\bin;$env:PATH"
127-
xmake build -P . -y cmdline_test
128-
xmake run -P . cmdline_test test_input
129+
# llmapi_test: skip entirely — requires API key to run, and xmake's
130+
# C++23 module system can't resolve transitive module deps from
131+
# installed packages. Tested in llmapi's own repo CI instead.
132+
TARGETS=$(echo "$TARGETS" | tr ' ' '\n' | grep -v llmapi_test | tr '\n' ' ')
129133
130-
# llmapi (build only, needs API key to run)
131-
- name: llmapi (unix)
132-
if: runner.os != 'Windows' && needs.detect-changes.outputs.llmapi == 'true'
133-
working-directory: tests
134-
run: |
135-
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
136-
xmake build -P . -y llmapi_test
137-
- name: llmapi (windows)
138-
if: runner.os == 'Windows' && needs.detect-changes.outputs.llmapi == 'true'
139-
working-directory: tests
140-
run: |
141-
$env:PATH = "$env:USERPROFILE\.xlings\subos\current\bin;$env:PATH"
142-
xmake build -P . -y llmapi_test
134+
FAILED=""
135+
for target in $TARGETS; do
136+
echo "=== Building $target ==="
137+
if ! xmake build -P . -y "$target"; then
138+
echo "FAILED to build $target"
139+
FAILED="$FAILED $target"
140+
continue
141+
fi
143142
144-
# lua
145-
- name: lua (unix)
146-
if: runner.os != 'Windows' && needs.detect-changes.outputs.lua == 'true'
147-
working-directory: tests
148-
run: |
149-
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
150-
xmake build -P . -y lua_test
151-
xmake run -P . lua_test
152-
- name: lua (windows)
153-
if: runner.os == 'Windows' && needs.detect-changes.outputs.lua == 'true'
154-
working-directory: tests
155-
run: |
156-
$env:PATH = "$env:USERPROFILE\.xlings\subos\current\bin;$env:PATH"
157-
xmake build -P . -y lua_test
158-
xmake run -P . lua_test
143+
echo "=== Running $target ==="
144+
if [ "$target" = "cmdline_test" ]; then
145+
xmake run -P . "$target" test_input
146+
else
147+
xmake run -P . "$target"
148+
fi
149+
done
159150
160-
# mcpplibs-xpkg
161-
- name: mcpplibs-xpkg (unix)
162-
if: runner.os != 'Windows' && needs.detect-changes.outputs.xpkg == 'true'
163-
working-directory: tests
164-
run: |
165-
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
166-
xmake build -P . -y mcpplibs-xpkg_test
167-
xmake run -P . mcpplibs-xpkg_test
168-
- name: mcpplibs-xpkg (windows)
169-
if: runner.os == 'Windows' && needs.detect-changes.outputs.xpkg == 'true'
151+
if [ -n "$FAILED" ]; then
152+
echo "::error::Failed targets:$FAILED"
153+
exit 1
154+
fi
155+
156+
- name: Build and test (windows)
157+
if: runner.os == 'Windows'
170158
working-directory: tests
159+
env:
160+
BUILD_ALL: ${{ needs.detect-changes.outputs.build_all }}
161+
CHANGED_PACKAGES: ${{ needs.detect-changes.outputs.packages }}
171162
run: |
172-
$env:PATH = "$env:USERPROFILE\.xlings\subos\current\bin;$env:PATH"
173-
xmake build -P . -y mcpplibs-xpkg_test
174-
xmake run -P . mcpplibs-xpkg_test
163+
$targets = @()
164+
if ($env:BUILD_ALL -eq "true") {
165+
$targets = Get-ChildItem -Recurse -Filter "xmake.lua" -Path "*/*" |
166+
Select-String 'target\("([^"]+)"\)' |
167+
ForEach-Object { $_.Matches[0].Groups[1].Value } |
168+
Sort-Object -Unique
169+
Write-Host "Building ALL targets: $($targets -join ', ')"
170+
} else {
171+
$packages = $env:CHANGED_PACKAGES | ConvertFrom-Json
172+
foreach ($pkg in $packages) {
173+
$target = "${pkg}_test"
174+
$found = Get-ChildItem -Recurse -Filter "xmake.lua" -Path "*/*" |
175+
Select-String "target\(`"$target`"\)" -Quiet
176+
if ($found) {
177+
$targets += $target
178+
} else {
179+
Write-Host "Warning: no test target '$target' found for package '$pkg', skipping"
180+
}
181+
}
182+
Write-Host "Building changed targets: $($targets -join ', ')"
183+
}
184+
185+
# Skip llmapi_test (same reason as unix)
186+
$targets = $targets | Where-Object { $_ -ne "llmapi_test" }
187+
188+
$failed = @()
189+
foreach ($target in $targets) {
190+
Write-Host "=== Building $target ==="
191+
xmake build -P . -y $target
192+
if ($LASTEXITCODE -ne 0) {
193+
Write-Host "FAILED to build $target"
194+
$failed += $target
195+
continue
196+
}
197+
198+
Write-Host "=== Running $target ==="
199+
if ($target -eq "cmdline_test") {
200+
xmake run -P . $target test_input
201+
} else {
202+
xmake run -P . $target
203+
}
204+
}
205+
206+
if ($failed.Count -gt 0) {
207+
Write-Host "::error::Failed targets: $($failed -join ', ')"
208+
exit 1
209+
}

.xlings.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"workspace": {
3+
"xmake": "3.0.7",
4+
"musl-gcc": { "linux": "15.1.0" },
5+
"llvm": { "macosx": "20.1.7" }
6+
}
7+
}

0 commit comments

Comments
 (0)