Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8d50059
feat(rust): differ poc (#542)
bzp2010 Aug 1, 2026
6573d00
test: rust differ (#543)
bzp2010 Aug 1, 2026
c8153f8
feat: rust resource type (#544)
bzp2010 Aug 1, 2026
e62ba61
feat: rust diff event type (#547)
bzp2010 Aug 1, 2026
949e88b
feat: rust backend type (#548)
bzp2010 Aug 1, 2026
bf48d78
feat: rust backend core (#549)
bzp2010 Aug 1, 2026
690bba8
feat: rust backend apisix (#550)
bzp2010 Aug 2, 2026
d3bf181
feat: rust cli (#551)
bzp2010 Aug 4, 2026
b110bfa
feat: rust backend api7 (#555)
bzp2010 Aug 5, 2026
4302449
feat: rust backend apisix standalone (#559)
bzp2010 Aug 6, 2026
a789222
feat: oas converter (#562)
bzp2010 Aug 16, 2026
775ba63
chore: clean benchmark crates (#563)
bzp2010 Aug 16, 2026
689faa5
fix comments
bzp2010 Aug 16, 2026
385ff90
clean code comments
bzp2010 Aug 16, 2026
b8c6163
fix comments
bzp2010 Aug 18, 2026
569d322
feat: rust lint (#564)
bzp2010 Aug 18, 2026
bd24d73
feat: rust ingress server (#565)
bzp2010 Aug 19, 2026
ae03053
fix: api7 format fp numbers for timeout correctly (#566)
bzp2010 Aug 20, 2026
baf5e24
test: rust add api7 timeout real float point number (#567)
bzp2010 Aug 22, 2026
500d63b
fix: rust clippy result err size lint (#568)
bzp2010 Aug 22, 2026
d38baad
fix: review 260822-1 (#569)
bzp2010 Aug 22, 2026
987ee15
fix: rust standalone race conditon between dump and sync (#570)
bzp2010 Aug 22, 2026
2b330cd
fix: rust standalone dump race condition (#572)
bzp2010 Aug 23, 2026
ef1603c
feat: rust internalize only sub event type (#573)
bzp2010 Aug 23, 2026
d60f5b2
feat: rust manually review 260823 (#574)
bzp2010 Aug 23, 2026
f9ccab2
fix comments
bzp2010 Aug 23, 2026
40b5d78
fix: rust revert api7 multiple certs support
bzp2010 Aug 23, 2026
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
125 changes: 125 additions & 0 deletions .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ on:
push:
branches:
- main
- rust-next
pull_request:
branches:
- main
- rust-next
types: [opened, synchronize, reopened, labeled]
env:
E2E: "1"
Expand All @@ -31,6 +33,7 @@ jobs:
apisix:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
version:
- 3.2.2
Expand Down Expand Up @@ -79,10 +82,22 @@ jobs:
# Run E2E tests
- name: Run E2E tests
run: npx nx run backend-apisix:test

# Run the Rust port's E2E tests against the same live apisix instance
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
workspaces: rust -> target
- name: Run Rust E2E tests
working-directory: ./rust
run: |
rustup update stable
rustup default stable
cargo test -p adc-backend-apisix -- --ignored --test-threads=1
apisix-standalone:
runs-on: ubuntu-latest
if: contains(github.event.pull_request.labels.*.name, 'test/apisix-standalone') || github.event_name == 'push'
strategy:
fail-fast: false
matrix:
version:
- 3.13.0
Expand Down Expand Up @@ -120,6 +135,28 @@ jobs:
# Run E2E tests
- name: Run E2E tests
run: npx nx run backend-apisix-standalone:test

# Run the Rust port's E2E tests against the same live cluster. Each
# test function restarts every instance itself before it starts
# (see adc-backend-apisix-standalone's tests/common/mod.rs), so
# running after the TS suite here is safe — nothing from the TS
# suite's own state survives into the Rust tests.
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
workspaces: rust -> target
- name: Run Rust E2E tests
working-directory: ./rust
run: |
rustup update stable
rustup default stable
cargo test -p adc-backend-apisix-standalone -- --ignored --test-threads=1
# Only useful when the step above fails: a bare 404 from an admin API
# request gives no clue why on its own — the container's own error
# log does.
- name: Dump APISIX standalone container logs
if: failure()
working-directory: ./libs/backend-apisix-standalone/e2e/assets
run: docker compose logs --no-color
api7:
runs-on: ubuntu-latest
if: contains(github.event.pull_request.labels.*.name, 'test/api7') || github.event_name == 'push'
Expand Down Expand Up @@ -174,3 +211,91 @@ jobs:
# Run API7 E2E tests
- name: Run E2E tests
run: npx nx run backend-api7:test
api7-rust:
runs-on: ubuntu-latest
if: contains(github.event.pull_request.labels.*.name, 'test/api7') || github.event_name == 'push'
permissions:
contents: read
packages: read
strategy:
fail-fast: false
matrix:
version: [3.5.5, 3.6.1, 3.7.8, 3.8.23, 3.9.14, 3.10.1, dev]
steps:
- name: Determine API7 image and license
run: |
if [ "${{ matrix.version }}" = "dev" ]; then
echo "BACKEND_API7_VERSION=999.999.999" >> $GITHUB_ENV
echo "API7_DASHBOARD_IMAGE=ghcr.io/api7/api7-ee-3-integrated" >> $GITHUB_ENV
echo "API7_IMAGE_TAG=dev" >> $GITHUB_ENV
{
echo "BACKEND_API7_LICENSE<<EOLICENSE"
echo "${{ secrets.BACKEND_API7_DEV_LICENSE }}"
echo "EOLICENSE"
} >> $GITHUB_ENV
else
echo "BACKEND_API7_VERSION=${{ matrix.version }}" >> $GITHUB_ENV
echo "API7_DASHBOARD_IMAGE=api7/api7-ee-3-integrated" >> $GITHUB_ENV
echo "API7_IMAGE_TAG=v${{ matrix.version }}" >> $GITHUB_ENV
{
echo "BACKEND_API7_LICENSE<<EOLICENSE"
echo "${{ secrets.BACKEND_API7_LICENSE }}"
echo "EOLICENSE"
} >> $GITHUB_ENV
fi

- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false

- name: Login to GHCR
if: matrix.version == 'dev'
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Runs on its own dashboard instance, independent of the `api7` job's
# (rather than reusing that job's live instance after the TS suite runs)
# — the Rust e2e suite's `common::client()` performs its own admin
# login / password rotation / license activation / token minting on
# first use (see adc-backend-api7's tests/common/mod.rs), which would
# collide with the TS suite doing the same dance against a shared
# instance.
- name: Setup API7 Instance via Docker Compose
working-directory: ./libs/backend-api7/e2e/assets
run: |
if [ "${{ matrix.version }}" = "dev" ]; then docker compose pull; fi
docker compose up -d

# Run the Rust port's E2E tests
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
workspaces: rust -> target
# Each test file below is its own process with no state shared
# between them, but they all talk to the one dashboard instance
# started above — so the admin login / password rotation / license
# activation / token minting dance runs here exactly once, and its
# result is shared with every other test file as `TOKEN` (see
# tests/e2e_init.rs), instead of each independently repeating it
# against a dashboard the first one to run already mutated.
- name: Bootstrap a shared API7 token
working-directory: ./rust
run: |
rustup update stable
rustup default stable
cargo test -p adc-backend-api7 --test e2e_init -- --ignored
- name: Run Rust E2E tests
working-directory: ./rust
run: |
rustup update stable
rustup default stable
cargo test -p adc-backend-api7 -- --ignored --test-threads=1
# Only useful when the step above fails: `BackendError::Api`'s
# message is empty for a 500 with no response body, which the
# dashboard's own logs can actually explain.
- name: Dump API7 dashboard logs
if: failure()
working-directory: ./libs/backend-api7/e2e/assets
run: docker compose logs --no-color
62 changes: 62 additions & 0 deletions .github/workflows/unit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ on:
push:
branches:
- main
- rust-next
pull_request:
branches:
- main
- rust-next
jobs:
test:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -35,3 +37,63 @@ jobs:
run: npx nx run backend-api7:test
- name: Run OpenAPI Converter unit tests
run: npx nx run converter-openapi:test
rust:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Setup Rust toolchain
run: |
rustup update stable
rustup default stable
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
workspaces: rust -> target

- name: Build
working-directory: ./rust
run: cargo build --workspace
- name: Clippy
working-directory: ./rust
run: cargo clippy --workspace --all-targets -- -D warnings
- name: Run unit tests
working-directory: ./rust
run: cargo test --workspace
rust-build:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
artifact: adc-linux-x64
- os: macos-latest
target: aarch64-apple-darwin
artifact: adc-macos-arm64
runs-on: ${{ matrix.os }}
permissions:
contents: read
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Setup Rust toolchain
run: |
rustup update stable
rustup default stable
rustup target add ${{ matrix.target }}
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
workspaces: rust -> target
- name: Build adc-cli
working-directory: ./rust
run: cargo build --release -p adc-cli --target ${{ matrix.target }}
- name: Stage binary
run: cp rust/target/${{ matrix.target }}/release/adc adc-${{ matrix.target }}
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ matrix.artifact }}
path: adc-${{ matrix.target }}
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,6 @@ vitest.config.*.timestamp*

.nx/polygraph
.nx/self-healing
.nx/migrate-runs
.nx/migrate-runs

rust/target/
5 changes: 5 additions & 0 deletions fixtures/differ/basic.adapts_to_default_core_values.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"local": { "consumers": [{ "username": "alice", "plugins": {} }] },
"remote": { "consumers": [{ "username": "alice", "description": "", "plugins": {} }] },
"defaultValue": { "core": { "consumer": { "description": "" } }, "plugins": {} }
}
5 changes: 5 additions & 0 deletions fixtures/differ/basic.adapts_to_default_plugin_values.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"local": { "consumers": [{ "username": "alice", "plugins": { "key-auth": { "key": "key" } } }] },
"remote": { "consumers": [{ "username": "alice", "plugins": { "key-auth": { "key": "key", "added": "added" } } }] },
"defaultValue": { "core": {}, "plugins": { "key-auth": { "added": "added" } } }
}
12 changes: 12 additions & 0 deletions fixtures/differ/basic.boolean_defaults_merged_correctly.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"local": { "services": [{ "name": "HTTP", "path_prefix": "/test", "strip_path_prefix": false }] },
"remote": {
"services": [{
"id": "f40b27d6b8b9a4fc3827264c1da16a04ecf4d094",
"name": "HTTP",
"path_prefix": "/test",
"strip_path_prefix": true
}]
},
"defaultValue": { "core": { "service": { "strip_path_prefix": true } }, "plugins": {} }
}
4 changes: 4 additions & 0 deletions fixtures/differ/basic.create_resource.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"local": { "consumers": [{ "username": "alice", "plugins": {} }] },
"remote": {}
}
4 changes: 4 additions & 0 deletions fixtures/differ/basic.delete_resource.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"local": {},
"remote": { "consumers": [{ "username": "alice", "plugins": {} }] }
}
4 changes: 4 additions & 0 deletions fixtures/differ/basic.empty_input_yields_empty_output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"local": {},
"remote": {}
}
8 changes: 8 additions & 0 deletions fixtures/differ/basic.generates_hashed_resource_id.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"local": {
"ssls": [
{ "snis": ["demo-sni1", "demo-sni2"], "certificates": [{ "certificate": "cert", "key": "key" }] }
]
},
"remote": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"local": {
"services": [{
"name": "Test Service",
"path_prefix": "/test",
"plugins": { "test": { "testKey": "testValue" } }
}]
},
"remote": {
"services": [{
"id": "5139f1c19641e214d3b9c57949d1578c2482b940",
"name": "Test Service",
"plugins": { "test": { "testKey": "testValue", "added": "added" } }
}]
},
"defaultValue": { "core": {}, "plugins": { "test": { "added": "added" } } }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"local": {
"services": [{
"name": "Test Service",
"upstream": { "nodes": [{ "host": "0.0.0.0", "port": 443, "weight": 1 }] }
}]
},
"remote": {
"services": [{
"id": "5139f1c19641e214d3b9c57949d1578c2482b940",
"name": "Test Service",
"upstream": { "nodes": [{ "host": "0.0.0.0", "port": 443, "weight": 1, "priority": 0 }] }
}]
},
"defaultValue": {
"core": { "service": { "upstream": { "nodes": [{ "priority": 0 }] } } },
"plugins": {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"local": {
"services": [
{ "name": "HTTP", "routes": [{ "name": "HTTP 1", "uris": ["/1"] }] },
{ "name": "Stream", "stream_routes": [{ "name": "Stream 1", "server_port": 5432 }] }
]
},
"remote": {
"services": [
{
"id": "f40b27d6b8b9a4fc3827264c1da16a04ecf4d094",
"name": "HTTP",
"routes": [{ "id": "f9e217f5cef4955ffce8d8da8b8e17918f85deb7", "name": "HTTP 1", "uris": ["/1"] }]
},
{
"id": "df063869e11d7a9aa132cd4a984f7b5eb870d656",
"name": "Stream",
"stream_routes": [{ "id": "05a5e25f718f3fd8d9d3b02e39bdf6e8ab274220", "name": "Stream 1", "server_port": 5432 }]
}
]
},
"defaultValue": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"local": { "services": [{ "name": "Test Service", "test1": {} }] },
"remote": {
"services": [{
"id": "5139f1c19641e214d3b9c57949d1578c2482b940",
"name": "Test Service",
"test": "test",
"test1": { "test2": "test2" }
}]
},
"defaultValue": {
"core": {
"service": { "test": "test", "test1": { "test2": "test2", "test3": { "test4": "test4" } } }
},
"plugins": {}
}
}
14 changes: 14 additions & 0 deletions fixtures/differ/basic.sorted_by_event_type.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"local": {
"consumers": [
{ "username": "createConsumer", "plugins": {} },
{ "username": "updatedConsumer", "plugins": { "key-auth": {} } }
]
},
"remote": {
"consumers": [
{ "username": "updatedConsumer", "plugins": {} },
{ "username": "deletedConsumer", "plugins": {} }
]
}
}
Loading
Loading