diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 204ca7a..bfa52b8 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -28,7 +28,7 @@ concurrency: jobs: bench: - runs-on: ubuntu-latest + runs-on: sylphx-linux-standard steps: - uses: actions/checkout@v7 - uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # stable diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dcbb116..cf6e16d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,8 @@ concurrency: jobs: plain-language: name: plain language - runs-on: ubuntu-latest + runs-on: sylphx-linux-standard + timeout-minutes: 5 steps: - uses: actions/checkout@v7 with: @@ -25,23 +26,75 @@ jobs: - uses: SylphxAI/.github/.github/actions/plain-language@f9176dad2e49c6b99d75f1506fafac84632fe870 test: - name: test (${{ matrix.os }}) - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: sylphx-linux-standard + timeout-minutes: 20 steps: - uses: actions/checkout@v7 - uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # stable - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2 - run: cargo test --workspace --locked + # macOS runs on our macOS pool, in the merge queue (its queue wait would slow + # every pull request). Windows, which we do not host: the tests are + # cross-compiled to MSVC on Linux and run under wine. + macos: + if: github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' + name: test macos + runs-on: [self-hosted, sylphx, macos, standard] + timeout-minutes: 30 + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # stable + - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2 + - run: cargo test --workspace --locked + + windows: + name: test windows (wine) + runs-on: sylphx-linux-standard + timeout-minutes: 30 + steps: + - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # stable + with: + targets: x86_64-pc-windows-msvc + components: llvm-tools + - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2 + with: + key: windows + - uses: actions/cache@v4 + with: + path: ~/.cache/cargo-xwin + key: cargo-xwin-0.23.1-x86_64 + - name: cargo-xwin, clang and wine + run: | + set -euo pipefail + fetch() { curl -fsSL -o "$RUNNER_TEMP/$2" "$1"; echo "$3 $RUNNER_TEMP/$2" | sha256sum -c -; } + fetch https://github.com/rust-cross/cargo-xwin/releases/download/v0.23.1/cargo-xwin-v0.23.1.x86_64-unknown-linux-musl.tar.gz xwin.tgz \ + c492c6dfb7e5ac0eee586b796e0fc950ba13077e7f0bbb046f445d71790d5360 + # Ubuntu 24.04's wine 9.0 aborts in our runner VMs; this 64-bit build runs. + fetch https://github.com/Kron4ek/Wine-Builds/releases/download/11.18/wine-11.18-amd64-wow64.tar.xz wine.txz \ + f899879b8c37e0b20adca19d147cf77436f3f1a37bf16d08d27fa7137a52b9ba + mkdir -p "$RUNNER_TEMP/bin" && tar -xzf "$RUNNER_TEMP/xwin.tgz" -C "$RUNNER_TEMP/bin" cargo-xwin + tar -xJf "$RUNNER_TEMP/wine.txz" -C "$RUNNER_TEMP" + printf '%s\n' "$RUNNER_TEMP/bin" "$RUNNER_TEMP/wine-11.18-amd64-wow64/bin" >> "$GITHUB_PATH" + sudo apt-get update -qq + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends clang >/dev/null + - run: cargo xwin test --workspace --locked --target x86_64-pc-windows-msvc + env: + XWIN_ACCEPT_LICENSE: '1' + XWIN_ARCH: x86_64 + WINEPREFIX: ${{ runner.temp }}/wine + WINEDEBUG: -all + checks: name: manifests, smoke, docs - runs-on: ubuntu-latest + runs-on: sylphx-linux-standard + timeout-minutes: 30 steps: - uses: actions/checkout@v7 + - uses: actions/setup-node@v7 + with: + node-version: '24' - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 with: bun-version: '1.4.0' @@ -101,3 +154,17 @@ jobs: $B tinymodel "turn a model into a dict" -C crates/lockdocs-core/tests/fixture | grep -q to_dict - name: Docs build run: bun run docs:build + + # The one required check. + ci: + if: always() + needs: [plain-language, test, macos, windows, checks] + runs-on: sylphx-linux-standard + timeout-minutes: 5 + steps: + - name: Every job passed + env: + RESULTS: ${{ join(needs.*.result, ' ') }} + run: | + echo "$RESULTS" + for r in $RESULTS; do case "$r" in success|skipped) ;; *) exit 1 ;; esac; done diff --git a/.github/workflows/demo.yml b/.github/workflows/demo.yml index b7edd06..31f432e 100644 --- a/.github/workflows/demo.yml +++ b/.github/workflows/demo.yml @@ -13,7 +13,8 @@ permissions: jobs: record: - runs-on: ubuntu-latest + runs-on: sylphx-linux-standard + timeout-minutes: 30 steps: - uses: actions/checkout@v7 - uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # stable @@ -33,6 +34,11 @@ jobs: echo "$PWD/target/release" >> "$GITHUB_PATH" # Warm the per-version caches so the recording shows query time, not indexing. for p in next14 next15 pydantic1 pydantic2; do target/release/lockdocs index -C bench/projects/$p >/dev/null; done + # Our runner image is thin: vhs needs fc-cache and headless Chromium's libraries. + - run: >- + sudo apt-get update -qq && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends + fontconfig libnss3 libatk1.0-0t64 libatk-bridge2.0-0t64 libcups2t64 libdrm2 libxkbcommon0 libxcomposite1 + libxdamage1 libxfixes3 libxrandr2 libgbm1 libpango-1.0-0 libcairo2 libasound2t64 >/dev/null - uses: charmbracelet/vhs-action@f6d7db07a432fcd3b06772628d36a57f96d95dcf # v2 with: path: docs/demo.tape diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 4b0fced..f110747 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -21,9 +21,13 @@ concurrency: jobs: build: - runs-on: ubuntu-latest + runs-on: sylphx-linux-standard + timeout-minutes: 20 steps: - uses: actions/checkout@v7 + - uses: actions/setup-node@v7 + with: + node-version: '24' - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 with: bun-version: '1.4.0' @@ -35,7 +39,8 @@ jobs: path: docs/.vitepress/dist deploy: needs: build - runs-on: ubuntu-latest + runs-on: sylphx-linux-standard + timeout-minutes: 10 environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0c6aa43..3ed214f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,6 +10,11 @@ on: push: branches: [main] workflow_dispatch: + inputs: + build-only: + description: Build and check the binaries only; publish nothing. + type: boolean + default: false permissions: contents: read @@ -26,6 +31,7 @@ jobs: id-token: write packages: write with: + build-only: ${{ inputs.build-only == true }} name: lockdocs npm-package: '@sylphx/lockdocs' mcp-name: io.github.SylphxAI/lockdocs diff --git a/PROJECT.md b/PROJECT.md index bd29682..8065887 100644 --- a/PROJECT.md +++ b/PROJECT.md @@ -25,7 +25,7 @@ MIT licensed. Bump with `bun scripts/set-version.ts X.Y.Z && cargo update -w`, add a `## X.Y.Z` section to CHANGELOG.md, then merge. `release.yml` publishes when -the npm version is new: 5 native targets on GitHub-hosted runners, the natives +the npm version is new: 5 native targets cross-compiled on our Linux runners, the natives and `@sylphx/lockdocs`, an `npx` smoke on a real project, the GitHub release, and the MCP Registry entry. diff --git a/docs/capabilities.md b/docs/capabilities.md index d671d51..7116c04 100644 --- a/docs/capabilities.md +++ b/docs/capabilities.md @@ -17,5 +17,5 @@ is in [vision.md](vision.md). | LD-MCP | MCP server with the `resolve`, `docs` and `api` tools over stdio | supported | crates/lockdocs/src/mcp.rs, crates/lockdocs/src/tools.rs | LD-SEARCH | | LD-CLI | Command line with the same queries, plus `index`, `fetch` and `setup` | supported | crates/lockdocs/src/main.rs, crates/lockdocs/src/setup.rs | LD-SEARCH | | LD-NPM | npm launcher and native binaries for five platforms | supported | packages/lockdocs, packages/npm | LD-CLI | -| LD-BENCH | Version-sensitive benchmark against Context7, run on GitHub-hosted runners | supported | bench/run.py, bench/questions.json, .github/workflows/bench.yml | LD-CLI | +| LD-BENCH | Version-sensitive benchmark against Context7, run on our own Linux CI runners | supported | bench/run.py, bench/questions.json, .github/workflows/bench.yml | LD-CLI | | LD-SEMANTIC-RERANK | Rerank the top results with a stronger local model for questions worded differently from the docs | planned | | LD-SEARCH | diff --git a/docs/vision.md b/docs/vision.md index c02626b..3c780dc 100644 --- a/docs/vision.md +++ b/docs/vision.md @@ -38,7 +38,7 @@ newest one. That is the one job. - On the version-sensitive benchmark (`bench/`), lockdocs is correct at least as often as the best hosted alternative on every column: older majors, newer majors, single-version libraries and the held-out questions. Results are - measured on GitHub-hosted runners and published as they come out. + measured on our own Linux CI runners and published as they come out. - A question costs tens of milliseconds and about a thousand tokens. - Every answer cites `package@version path:line`, so an agent or a person can check it.