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
8 changes: 4 additions & 4 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ NEKIRO_CONTROL_PLANE_IMAGE=replace-with-prepared-image
NEKIRO_A2A_ROUTER_IMAGE=replace-with-prepared-image
NEKIRO_RUNTIME_A_IMAGE=replace-with-prepared-image
NEKIRO_RUNTIME_B_IMAGE=replace-with-prepared-image
NEKIRO_NACOS_SECURE_PROXY_IMAGE=replace-with-prepared-image

# Select exactly one Router instance-routing mode. Use direct to dispatch to
# the exact published Card endpoint, or config_center_file to select an
# instance from the exact Release-scoped directory document.
NEKIRO_ROUTER_INSTANCE_ROUTING_MODE=replace-with-direct-or-config_center_file
# Select exactly one Router instance-routing mode: direct, config_center_file,
# or nacos. There is no automatic fallback between them.
NEKIRO_ROUTER_INSTANCE_ROUTING_MODE=replace-with-explicit-routing-mode
NEKIRO_ROUTER_CONFIG_CENTER_ROOT=replace-with-absolute-host-directory
NEKIRO_ROUTER_CONFIG_CENTER_MAX_PAYLOAD_BYTES=replace-with-explicit-byte-limit
NEKIRO_ROUTER_INSTANCE_DIRECTORY_KEY=replace-with-directory-key
Expand Down
14 changes: 9 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ jobs:
shell: bash
run: |
docker compose --file compose.yaml config --quiet
docker compose --file compose.yaml --file compose.router-nacos-secure.yaml --profile router-nacos-secure config --quiet
if grep -nE '^[[:space:]]+build:|image:[[:space:]].*(latest|:(main|master))([[:space:]"@]|$)' compose.yaml; then
echo 'Compose contains a source build or floating image.' >&2
exit 1
Expand Down Expand Up @@ -116,25 +117,28 @@ jobs:
run: |
./scripts/prepare.sh "$GITHUB_WORKSPACE/components.json" "$WORK_ROOT" "$PREPARED_ENV"
source "$PREPARED_ENV"
for name in NEKIRO_CONTROL_PLANE_IMAGE NEKIRO_A2A_ROUTER_IMAGE NEKIRO_RUNTIME_A_IMAGE NEKIRO_RUNTIME_B_IMAGE NEKIRO_STACK_CORE_DIR NEKIRO_STACK_CONSOLE_DIR NEKIRO_STACK_SDK_GO_DIR NEKIRO_STACK_SAMPLES_DIR NEKIRO_STACK_TRANSPORT_GO_DIR; do
for name in NEKIRO_CONTROL_PLANE_IMAGE NEKIRO_A2A_ROUTER_IMAGE NEKIRO_RUNTIME_A_IMAGE NEKIRO_RUNTIME_B_IMAGE NEKIRO_NACOS_SECURE_PROXY_IMAGE NEKIRO_STACK_CORE_DIR NEKIRO_STACK_CONSOLE_DIR NEKIRO_STACK_SDK_GO_DIR NEKIRO_STACK_SAMPLES_DIR NEKIRO_STACK_TRANSPORT_GO_DIR; do
printf '%s=%s\n' "$name" "${!name}" >>"$GITHUB_ENV"
done
printf 'NEKIRO_STACK_PREPARED_ENV=%s\n' "$PREPARED_ENV" >>"$GITHUB_ENV"

- name: Generate ephemeral Nacos PKI
run: go run ./cmd/nacos-secure-fixture generate "$NEKIRO_E2E_TLS_ROOT"

- name: Start fresh exact backend assembly
run: docker compose --project-name "$NEKIRO_E2E_COMPOSE_PROJECT" --file compose.yaml up --detach --wait --wait-timeout 120
run: docker compose --project-name "$NEKIRO_E2E_COMPOSE_PROJECT" --file compose.yaml --file "$NEKIRO_E2E_COMPOSE_OVERRIDE_FILE" --profile router-nacos-secure up --detach --wait --wait-timeout 120

- name: Run trusted publication Invoke-to-Record acceptance
run: go test -tags=e2e -count=1 ./tests/backend

- name: Capture sanitized backend logs
if: always() && steps.prepare.outcome == 'success'
shell: bash
run: docker compose --project-name "$NEKIRO_E2E_COMPOSE_PROJECT" --file compose.yaml --profile runtime-registration --profile watch-refresh logs --no-color 2>&1 | perl scripts/sanitize-logs.pl
run: docker compose --project-name "$NEKIRO_E2E_COMPOSE_PROJECT" --file compose.yaml --file "$NEKIRO_E2E_COMPOSE_OVERRIDE_FILE" --profile router-nacos-secure --profile runtime-registration --profile watch-refresh logs --no-color 2>&1 | perl scripts/sanitize-logs.pl

- name: Tear down backend assembly
if: always() && steps.prepare.outcome == 'success'
run: docker compose --project-name "$NEKIRO_E2E_COMPOSE_PROJECT" --file compose.yaml --profile runtime-registration --profile watch-refresh down --volumes --remove-orphans
run: docker compose --project-name "$NEKIRO_E2E_COMPOSE_PROJECT" --file compose.yaml --file "$NEKIRO_E2E_COMPOSE_OVERRIDE_FILE" --profile router-nacos-secure --profile runtime-registration --profile watch-refresh down --volumes --remove-orphans

browser:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -173,7 +177,7 @@ jobs:
run: |
./scripts/prepare.sh "$GITHUB_WORKSPACE/components.json" "$WORK_ROOT" "$PREPARED_ENV"
source "$PREPARED_ENV"
for name in NEKIRO_CONTROL_PLANE_IMAGE NEKIRO_A2A_ROUTER_IMAGE NEKIRO_RUNTIME_A_IMAGE NEKIRO_RUNTIME_B_IMAGE NEKIRO_STACK_CORE_DIR NEKIRO_STACK_CONSOLE_DIR NEKIRO_STACK_SDK_GO_DIR NEKIRO_STACK_SAMPLES_DIR NEKIRO_STACK_TRANSPORT_GO_DIR; do
for name in NEKIRO_CONTROL_PLANE_IMAGE NEKIRO_A2A_ROUTER_IMAGE NEKIRO_RUNTIME_A_IMAGE NEKIRO_RUNTIME_B_IMAGE NEKIRO_NACOS_SECURE_PROXY_IMAGE NEKIRO_STACK_CORE_DIR NEKIRO_STACK_CONSOLE_DIR NEKIRO_STACK_SDK_GO_DIR NEKIRO_STACK_SAMPLES_DIR NEKIRO_STACK_TRANSPORT_GO_DIR; do
printf '%s=%s\n' "$name" "${!name}" >>"$GITHUB_ENV"
done
printf 'NEKIRO_STACK_PREPARED_ENV=%s\n' "$PREPARED_ENV" >>"$GITHUB_ENV"
Expand Down
26 changes: 18 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,24 @@ prepared image environment, then validate and start the stack:

```bash
docker compose --file compose.yaml config --quiet
docker compose --project-name nekiro-stack --file compose.yaml up --detach --wait --wait-timeout 120
go run ./cmd/nacos-secure-fixture generate "$NEKIRO_E2E_TLS_ROOT"
docker compose --project-name nekiro-stack \
--file compose.yaml \
--file compose.router-nacos-secure.yaml \
--profile router-nacos-secure \
up --detach --wait --wait-timeout 120
go test -tags=e2e -count=1 ./tests/backend
```

`NEKIRO_ROUTER_INSTANCE_ROUTING_MODE` must be either `direct` or
`config_center_file`; there is no automatic fallback between them. File mode
`NEKIRO_ROUTER_INSTANCE_ROUTING_MODE` must be `direct`, `config_center_file`, or
`nacos`; there is no automatic fallback between them. File mode
reads the exact Release-scoped `router-instance-directory.v1` document from
the absolute host directory named by `NEKIRO_ROUTER_CONFIG_CENTER_ROOT`.
Missing, malformed, empty, or ambiguous instance data makes new Invocations
fail closed. The backend acceptance scenario publishes one ready Runtime B
replica into that directory and verifies both JSON and SSE dispatch to its
reported instance ID. Compose and browser scenarios select `direct`
explicitly because instance-directory behavior is outside those checks.
fail closed. The backend scenario selects `nacos` and uses the Stack-owned
secure Nacos fixture for Router Config Center reads, initial Naming snapshots,
and gRPC watch updates. Browser scenarios select `direct` because instance
directory behavior is outside those checks.

## Test matrix and success signals

Expand All @@ -88,11 +93,16 @@ assembly.
Backend runtime registration uses an ephemeral private PKI generated by the
acceptance process. Runtime A publishes through an authenticated TLS Nacos
endpoint; Runtime B and its replacement publish through an mTLS endpoint. The
Router observes those leases before managed invocation. Negative containers
Router reaches Config Center and Naming through authenticated HTTP and gRPC
mTLS endpoints before observing those leases. Negative containers
with a wrong CA, wrong server name, or missing mTLS client identity must fail
before publication and leave no routable instance. Test keys exist only in the
caller-owned runtime directory and are never committed or recorded in Ledger.

The secure fixture exposes only a status endpoint on the host. Its counters
prove that the Router completed authenticated HTTP reads and established the
authenticated gRPC watch; Nacos itself remains internal to Compose.

The `Core integration` reusable workflow accepts a full Core commit SHA,
renders a temporary immutable manifest, and runs both backend and browser
acceptance. Core calls it after every merge to `main`; the tracked Stack
Expand Down
Loading
Loading