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
18 changes: 18 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 4

[*.{ts,tsx,js,jsx,json,yml,yaml,md,css,html}]
indent_size = 2

[*.rs]
indent_size = 4

[Makefile]
indent_style = tab
197 changes: 197 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1

jobs:
lint:
name: lint (fmt + clippy + tsc)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- uses: Swatinem/rust-cache@v2
Comment on lines +18 to +25

Copilot AI Apr 17, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This job installs dtolnay/rust-toolchain@stable, which ignores the repo’s rust-toolchain.toml pin. To avoid local-vs-CI drift (fmt/clippy behavior, MSRV), consider installing from the toolchain file (or explicitly pinning the same version) in CI.

Copilot uses AI. Check for mistakes.
- name: cargo fmt --check
run: cargo fmt --all -- --check
- name: cargo clippy
run: cargo clippy --workspace --all-targets -- -D warnings

- uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
- name: ui install
working-directory: ui
run: pnpm install --no-frozen-lockfile
- name: ui typecheck
working-directory: ui
run: pnpm typecheck || true # lockfile is generated at first install; soft until PR #11

rust-unit:
name: rust unit + coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: llvm-tools-preview
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- uses: Swatinem/rust-cache@v2
Comment on lines +48 to +55

Copilot AI Apr 17, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This job installs dtolnay/rust-toolchain@stable, which ignores the repo’s rust-toolchain.toml pin. Consider switching CI to use the toolchain file (or explicitly installing the pinned version) to keep CI and local dev consistent.

Copilot uses AI. Check for mistakes.
- name: install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov
- name: unit tests with coverage
run: cargo llvm-cov --workspace --lcov --output-path lcov-unit.info
- uses: actions/upload-artifact@v4
with:
name: coverage-unit
path: lcov-unit.info

build-ui:
name: build ui
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
- name: install
working-directory: ui
run: pnpm install --no-frozen-lockfile
- name: build
working-directory: ui
run: pnpm build
- uses: actions/upload-artifact@v4
with:
name: ui-dist
path: crates/aisix-admin/ui-dist

build-bin:
name: build aisix (instrumented)
needs: build-ui
runs-on: ubuntu-latest
env:
RUSTFLAGS: "-C instrument-coverage"
LLVM_PROFILE_FILE: "coverage/aisix-%p-%m.profraw"
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: ui-dist
path: crates/aisix-admin/ui-dist
- uses: dtolnay/rust-toolchain@stable
with:
components: llvm-tools-preview
- uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- uses: Swatinem/rust-cache@v2
Comment on lines +100 to +106

Copilot AI Apr 17, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This job installs dtolnay/rust-toolchain@stable, which ignores the repo’s rust-toolchain.toml pin. Consider using the toolchain file (or pinning the same version) to prevent CI/local divergence when the pinned toolchain changes.

Copilot uses AI. Check for mistakes.
- name: build
run: cargo build -p aisix-server --bin aisix
- uses: actions/upload-artifact@v4
with:
name: aisix-bin
path: target/debug/aisix

e2e:
name: e2e (vitest) + coverage
needs: [build-bin, build-ui]
runs-on: ubuntu-latest
# Scaffold-phase soft gate: the harness lands with PR #2+.
# Flip `continue-on-error` to false at PR #5 per plan §5.2 ratchet.
continue-on-error: true
services:
etcd:
image: quay.io/coreos/etcd:v3.5.15
env:
ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379"
ETCD_ADVERTISE_CLIENT_URLS: "http://0.0.0.0:2379"
ports: ["2379:2379"]
redis:
image: redis:7-alpine
ports: ["6379:6379"]
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: aisix-bin
path: target/debug
- run: chmod +x target/debug/aisix
- uses: actions/setup-node@v4
with:
node-version: 20
- uses: pnpm/action-setup@v4
with:
version: 9
- name: check harness exists
id: harness
run: |
if [ -f tests/e2e/package.json ]; then
echo "present=true" >> "$GITHUB_OUTPUT"
else
echo "present=false" >> "$GITHUB_OUTPUT"
echo "::notice::tests/e2e harness not present yet — skipping"
fi
- name: e2e install
if: steps.harness.outputs.present == 'true'
working-directory: tests/e2e
run: pnpm install --no-frozen-lockfile
- name: run e2e
if: steps.harness.outputs.present == 'true'
working-directory: tests/e2e
run: pnpm test
- uses: actions/upload-artifact@v4
if: always()
with:
name: coverage-e2e
path: tests/e2e/coverage/lcov.info
if-no-files-found: ignore

coverage-gate:
name: coverage >= 90%
needs: [rust-unit, e2e]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with: { name: coverage-unit, path: cov/unit }
- uses: actions/download-artifact@v4
continue-on-error: true
with: { name: coverage-e2e, path: cov/e2e }
- name: merge + threshold
run: |
npm i -g lcov-result-merger @lcov-viewer/cli
merged=cov/combined.info
files=(cov/unit/*.info)
[ -d cov/e2e ] && files+=(cov/e2e/*.info)
lcov-result-merger "${files[@]}" "$merged" || cp "${files[0]}" "$merged"
pct=$(awk -F: '/^LF:/ {tot+=$2} /^LH:/ {hit+=$2} END {if (tot>0) printf "%.2f", hit/tot*100; else print 0}' "$merged")
echo "Combined line coverage: ${pct}%"
threshold=${COVERAGE_THRESHOLD:-90}
awk -v p="$pct" -v t="$threshold" 'BEGIN { exit (p+0 < t+0) }' || {
echo "::error::Coverage ${pct}% below threshold ${threshold}%"
# soft during scaffold milestones; flip to `exit 1` at PR #5.
exit 0
}
- uses: actions/upload-artifact@v4
with:
name: coverage-combined
path: cov/combined.info
Loading
Loading