Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
6463eb9
feat: rewrite app logic for group-based context management (v2)
rtb-12 Mar 11, 2026
4a429f8
feat: add group API data source, hooks, and groupId config
rtb-12 Mar 11, 2026
7383ebf
feat: Phase 4 onboarding — group-based workspace creation and invitat…
rtb-12 Mar 11, 2026
b9cf71a
feat: Phase 7 admin UI for group member management, visibility, allow…
rtb-12 Mar 11, 2026
bee9b7f
feat: replace DM state machine with group-based restricted contexts
rtb-12 Mar 11, 2026
2e9e39a
fix: web + desktop options (#120)
frdomovic Mar 12, 2026
2740ee4
feat: complete workspace entry and channel join flow
rtb-12 Mar 13, 2026
2cd7311
feat: streamline workspace entry and group channel controls
rtb-12 Mar 13, 2026
3541c7c
feat: improve workspace admin controls and session switching
rtb-12 Mar 15, 2026
93d1b16
feat: improve group context discovery and DM creation
rtb-12 Mar 16, 2026
03c3cfd
feat: surface group and member aliases in chat UI
rtb-12 Mar 16, 2026
e85796d
feat: load workspace member aliases on entry
rtb-12 Mar 17, 2026
e93dc1f
feat: enhance group alias management and invitation handling
rtb-12 Mar 17, 2026
9e4673e
feat: update to match rc29 - edge - logic - fe - tests
frdomovic Apr 22, 2026
5f350c9
fix: comments + linting + authored vector usage
frdomovic Apr 23, 2026
370a5f0
feat: e2e changes
frdomovic Apr 23, 2026
df5412b
fix: cleanup
frdomovic Apr 23, 2026
96aad13
feat: update e2e tests
frdomovic Apr 24, 2026
0c8e206
fix: tests
frdomovic Apr 24, 2026
0cfd8e3
fix: tests v2
frdomovic Apr 24, 2026
dbd96df
fix: cleanup
frdomovic Apr 24, 2026
95092ea
fix: all e2e playwright tests
frdomovic Apr 24, 2026
dde3032
fix: CI
frdomovic Apr 24, 2026
ae38bdc
fix: ci
frdomovic Apr 24, 2026
3eef345
fix: ci
frdomovic Apr 24, 2026
de06669
fix: typecheck & lint
frdomovic Apr 25, 2026
d485652
feat: simplify e2e merobox tests
frdomovic Apr 25, 2026
f30df12
fix: remove js versions tbd
frdomovic Apr 25, 2026
7a5d426
fix: remove js trigger
frdomovic Apr 25, 2026
3d7b388
fix: comments
frdomovic Apr 25, 2026
a01e328
fix: logic + fe
frdomovic Apr 25, 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
6 changes: 0 additions & 6 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@ updates:
interval: "weekly"
open-pull-requests-limit: 5

- package-ecosystem: "npm"
directory: "/logic-js"
schedule:
interval: "weekly"
open-pull-requests-limit: 5

- package-ecosystem: "github-actions"
directory: "/"
schedule:
Expand Down
98 changes: 98 additions & 0 deletions .github/workflows/frontend-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
name: Frontend CI

on:
push:
branches: [main, master]
paths:
- 'app/**'
pull_request:
branches: [main, master]
paths:
- 'app/**'

defaults:
run:
working-directory: app

jobs:
typecheck-lint:
name: Typecheck & Lint
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
cache: pnpm
cache-dependency-path: app/pnpm-lock.yaml

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Typecheck
run: pnpm exec tsc --noEmit

- name: Lint
run: pnpm lint

unit:
name: Unit Tests
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
cache: pnpm
cache-dependency-path: app/pnpm-lock.yaml

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Run unit tests
run: pnpm test

e2e:
name: Playwright E2E
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
cache: pnpm
cache-dependency-path: app/pnpm-lock.yaml

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Install Playwright browsers
run: pnpm exec playwright install chromium --with-deps

- name: Run Playwright tests (mocked project — no live node required)
run: pnpm exec playwright test --project=mocked
env:
CI: true

- name: Upload Playwright report
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: app/e2e-report/
retention-days: 7
201 changes: 201 additions & 0 deletions .github/workflows/integration-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
# Full-stack integration CI: builds curb.wasm, starts real merod nodes via
# merobox, installs the app onto the nodes, seeds test data, then runs the
# Playwright "integration" project against the live stack.

name: Integration Tests (Full Stack)

on:
push:
branches: [main, master]
paths:
- "logic/**"
- "app/**"
- "workflows/**"
- "scripts/**"
pull_request:
branches: [main, master]
paths:
- "logic/**"
- "app/**"
- "workflows/**"
- "scripts/**"

jobs:
integration:
name: Full-Stack Integration Tests
runs-on: ubuntu-latest
timeout-minutes: 30

steps:
- uses: actions/checkout@v4

# ── Build curb WASM ───────────────────────────────────────────────────────

- name: Checkout calimero/core (Cargo path deps)
run: git clone --depth 1 https://github.com/calimero-network/core.git "${GITHUB_WORKSPACE}/../core"

- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: "1.89.0"
targets: wasm32-unknown-unknown

- name: Build curb WASM
run: |
cd logic
cargo build --target wasm32-unknown-unknown --profile app-release
mkdir -p res
cp target/wasm32-unknown-unknown/app-release/curb.wasm res/

# ── Install merobox ───────────────────────────────────────────────────────

- name: Install merobox
run: pip install merobox==0.4.6 && merobox --version

# ── Start nodes + install curb app + create context + seed messages ───────
# integration-setup.yml sets stop_all_nodes: false so nodes stay running.

- name: Run integration-setup workflow (merobox)
working-directory: workflows
run: |
merobox stop --all 2>/dev/null || true
merobox nuke --force 2>/dev/null || true
merobox bootstrap run integration-setup.yml

# ── Bootstrap JWT auth + discover IDs + write app/.env.integration ────────

- name: Bootstrap auth and write env file
run: |
set -euo pipefail
NODE_1_URL="http://localhost:2428"
NODE_2_URL="http://localhost:2429"
ADMIN_USER="${E2E_ADMIN_USER:-admin}"
ADMIN_PASS="${E2E_ADMIN_PASS:-calimero1234}"

echo "Waiting for both nodes to be healthy…"
for i in $(seq 1 30); do
if curl -sf "${NODE_1_URL}/admin-api/health" >/dev/null 2>&1 && \
curl -sf "${NODE_2_URL}/admin-api/health" >/dev/null 2>&1; then
echo "Both nodes healthy (attempt ${i})"
break
fi
if [ "$i" -eq 30 ]; then
echo "Nodes not healthy after 60 s — dumping logs"
exit 1
Comment thread
cursor[bot] marked this conversation as resolved.
fi
sleep 2
done

AUTH_PAYLOAD="{
\"auth_method\": \"user_password\",
\"public_key\": \"${ADMIN_USER}\",
\"client_name\": \"integration-ci\",
\"timestamp\": 0,
\"permissions\": [],
\"provider_data\": {\"username\": \"${ADMIN_USER}\", \"password\": \"${ADMIN_PASS}\"}
}"

AUTH_1=$(curl -sf -X POST "${NODE_1_URL}/auth/token" \
-H "Content-Type: application/json" -d "${AUTH_PAYLOAD}")
ACCESS_TOKEN_1=$(echo "$AUTH_1" | jq -r '.data.access_token // empty')
REFRESH_TOKEN_1=$(echo "$AUTH_1" | jq -r '.data.refresh_token // empty')
[ -n "$ACCESS_TOKEN_1" ] || { echo "Auth failed for node 1: $AUTH_1"; exit 1; }

AUTH_2=$(curl -sf -X POST "${NODE_2_URL}/auth/token" \
-H "Content-Type: application/json" -d "${AUTH_PAYLOAD}")
ACCESS_TOKEN_2=$(echo "$AUTH_2" | jq -r '.data.access_token // empty')
REFRESH_TOKEN_2=$(echo "$AUTH_2" | jq -r '.data.refresh_token // empty')
[ -n "$ACCESS_TOKEN_2" ] || { echo "Auth failed for node 2: $AUTH_2"; exit 1; }

GROUPS=$(curl -sf "${NODE_1_URL}/admin-api/groups" \
-H "Authorization: Bearer ${ACCESS_TOKEN_1}" 2>/dev/null) || GROUPS="{}"
GROUP_ID=$(echo "$GROUPS" | jq -r '
(.data // .) |
if type == "array" then .[0].groupId
elif type == "object" then (.groups[0].groupId // .items[0].groupId)
else empty end' 2>/dev/null || echo "")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

CI group discovery queries wrong endpoint and field

High Severity

The CI bootstrap script queries /admin-api/groups and extracts groupId from the response, but the actual node API list endpoint is /admin-api/namespaces and returns entries with a namespaceId field. The frontend's listGroups() in groupApiDataSource.ts confirms this by calling /admin-api/namespaces as the primary endpoint, and rpc-admin.spec.ts tests explicitly state "The node exposes namespaces under /namespaces (not /groups)." The integration-setup.yml workflow also uses create_namespace and outputs namespaceId. As a result, GROUP_ID is always empty, E2E_GROUP_ID is blank in .env.integration, integrationEnvAvailable() returns false, and every integration test silently skips — despite the expensive WASM build, node startup, and Playwright browser installation.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3d7b388. Configure here.


CTXS=$(curl -sf "${NODE_1_URL}/admin-api/contexts" \
-H "Authorization: Bearer ${ACCESS_TOKEN_1}" 2>/dev/null) || CTXS="{}"
CONTEXT_ID=$(echo "$CTXS" | jq -r '
(.data // .) |
if type == "array" then .[0].id // .[0].contextId
elif type == "object" then (.contexts[0].id // .contexts[0].contextId // .items[0].id)
else empty end' 2>/dev/null || echo "")

MEMBER_KEY=""
if [ -n "$CONTEXT_ID" ]; then
IDENTS=$(curl -sf \
"${NODE_1_URL}/admin-api/contexts/${CONTEXT_ID}/identities-owned" \
-H "Authorization: Bearer ${ACCESS_TOKEN_1}" 2>/dev/null) || IDENTS="{}"
MEMBER_KEY=$(echo "$IDENTS" | jq -r '
(.data // .) |
if type == "array" then .[0]
elif type == "object" then (.identities[0] // .items[0])
else empty end' 2>/dev/null || echo "")
fi

echo "GROUP_ID: ${GROUP_ID:-<not found>}"
echo "CONTEXT_ID: ${CONTEXT_ID:-<not found>}"

cat > app/.env.integration << ENVEOF
E2E_NODE_URL=${NODE_1_URL}
E2E_NODE_URL_2=${NODE_2_URL}
E2E_ACCESS_TOKEN=${ACCESS_TOKEN_1}
E2E_REFRESH_TOKEN=${REFRESH_TOKEN_1}
E2E_ACCESS_TOKEN_2=${ACCESS_TOKEN_2}
E2E_REFRESH_TOKEN_2=${REFRESH_TOKEN_2}
E2E_GROUP_ID=${GROUP_ID:-}
E2E_CONTEXT_ID=${CONTEXT_ID:-}
E2E_MEMBER_KEY=${MEMBER_KEY:-}
ENVEOF
echo "app/.env.integration written"

# ── Frontend setup ────────────────────────────────────────────────────────

- uses: pnpm/action-setup@v4
with:
version: 9

- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
cache-dependency-path: app/pnpm-lock.yaml

- name: Install frontend dependencies
working-directory: app
run: pnpm install --frozen-lockfile

- name: Install Playwright browsers
working-directory: app
run: pnpm exec playwright install chromium --with-deps

# ── Run integration Playwright tests ──────────────────────────────────────

- name: Run integration tests
working-directory: app
run: pnpm exec playwright test --project=integration
env:
CI: "true"
# Tells global-setup.ts to skip browser auth — integration tests
# inject tokens directly via injectRealTokens() per test.
INTEGRATION_MODE: "true"

# ── Cleanup ───────────────────────────────────────────────────────────────

- name: Stop nodes
if: always()
run: |
merobox stop --all 2>/dev/null || true
merobox nuke --force 2>/dev/null || true

# ── Artifacts ─────────────────────────────────────────────────────────────

- name: Upload Playwright report
if: always()
uses: actions/upload-artifact@v4
with:
name: integration-playwright-report
path: app/e2e-report/
retention-days: 7
Loading
Loading