feat: add tenant_schedule database table for manifest-driven scheduli… #3184
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: E2E Tests | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: [develop, main] | |
| paths: | |
| - 'frontend/**' | |
| - 'services/**' | |
| - '.github/workflows/e2e.yml' | |
| pull_request: | |
| branches: [develop, main] | |
| paths: | |
| - 'frontend/**' | |
| - 'services/**' | |
| - '.github/workflows/e2e.yml' | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # =========================================================================== | |
| # Build: compile backend binary and frontend assets once, share via artifacts | |
| # =========================================================================== | |
| build: | |
| name: Build | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Set up Go | |
| uses: actions/setup-go@v6 | |
| with: | |
| go-version: '1.26.1' | |
| cache: true | |
| - name: Set up buf | |
| uses: bufbuild/buf-action@v1 | |
| with: | |
| setup_only: true | |
| github_token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '22' | |
| cache: 'npm' | |
| cache-dependency-path: frontend/package-lock.json | |
| - name: Generate protobuf files | |
| run: buf generate | |
| - name: Build proto FileDescriptorSet | |
| run: buf build api/proto -o cmd/meridian/descriptor.binpb | |
| - name: Build meridian binary | |
| run: CGO_ENABLED=0 go build -o ./dist/meridian ./cmd/meridian/ | |
| - name: Build seed-dev binary | |
| run: CGO_ENABLED=0 go build -o ./dist/seed-dev ./cmd/seed-dev/ | |
| - name: Install frontend dependencies | |
| working-directory: frontend | |
| run: npm ci | |
| - name: Generate frontend protobuf files | |
| working-directory: frontend | |
| run: npm run generate | |
| - name: Build frontend | |
| working-directory: frontend | |
| env: | |
| VITE_E2E_MODE: 'true' | |
| VITE_API_BASE_URL: 'http://localhost:5173' | |
| run: npx vite build | |
| - name: Upload backend binaries | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: meridian-binary | |
| path: | | |
| dist/meridian | |
| dist/seed-dev | |
| retention-days: 1 | |
| - name: Upload frontend build | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: frontend-dist | |
| path: frontend/dist/ | |
| retention-days: 1 | |
| # =========================================================================== | |
| # E2E Shards: run Playwright tests in parallel across 4 runners | |
| # =========================================================================== | |
| e2e: | |
| name: 'E2E Shard ${{ matrix.shardIndex }}/4' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 25 | |
| needs: build | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shardIndex: [1, 2, 3, 4] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Download backend binary | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: meridian-binary | |
| path: dist/ | |
| - name: Make binaries executable | |
| run: chmod +x dist/meridian dist/seed-dev | |
| - name: Download frontend build | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: frontend-dist | |
| path: frontend/dist/ | |
| - name: Start CockroachDB | |
| run: | | |
| docker run -d \ | |
| --name cockroachdb \ | |
| -p 26257:26257 \ | |
| cockroachdb/cockroach:latest-v24.1 \ | |
| start-single-node --insecure | |
| # Wait for CockroachDB to be ready (up to 60s) | |
| for i in $(seq 1 30); do | |
| if docker exec cockroachdb cockroach sql --insecure -e 'SELECT 1' >/dev/null 2>&1; then | |
| echo "CockroachDB is ready" | |
| break | |
| fi | |
| if [ "$i" -eq 30 ]; then | |
| echo "ERROR: CockroachDB did not become ready after 60s" | |
| exit 1 | |
| fi | |
| sleep 2 | |
| done | |
| - name: Run database migrations | |
| run: | | |
| ./dist/meridian \ | |
| --migrate \ | |
| --database-url "postgres://root@localhost:26257/defaultdb?sslmode=disable" | |
| - name: Stage tenant migration files for provisioner | |
| run: | | |
| # The schema provisioner reads per-service migrations from | |
| # MIGRATIONS_BASE_PATH/<service>/*.sql. In the Docker image this is | |
| # /migrations/<service>, but the E2E runner runs the binary directly | |
| # from dist/. Stage a flat layout under /tmp/provisioner-migrations | |
| # so the provisioner can apply each service's migrations to the | |
| # org_<tenant> schema when InitiateTenant fires. | |
| mkdir -p /tmp/provisioner-migrations | |
| for SVC in party current-account position-keeping financial-accounting payment-order market-information reference-data internal-account reconciliation identity control-plane; do | |
| if [ -d "services/${SVC}/migrations" ]; then | |
| cp -r "services/${SVC}/migrations" "/tmp/provisioner-migrations/${SVC}" | |
| fi | |
| done | |
| - name: Start meridian backend | |
| run: | | |
| DATABASE_URL="postgres://root@localhost:26257/defaultdb?sslmode=disable" \ | |
| LOCAL_DEV_MODE=true \ | |
| AUTH_ENABLED=false \ | |
| SAGA_ASSET_DIR="$(pwd)" \ | |
| SCHEMA_PROVISIONING_ENABLED=true \ | |
| MIGRATIONS_BASE_PATH=/tmp/provisioner-migrations \ | |
| ./dist/meridian >/tmp/meridian.log 2>&1 & | |
| - name: Seed dev tenant and apply manifest | |
| run: | | |
| ./dist/seed-dev \ | |
| --gateway-url=http://localhost:8090 \ | |
| --grpc-addr=localhost:50051 \ | |
| --manifest=examples/manifests/energy.json \ | |
| --tenant-id=dev_tenant \ | |
| --tenant-slug=dev-tenant | |
| - name: Create additional test tenants | |
| run: | | |
| GATEWAY_URL="http://localhost:8090" | |
| create_tenant() { | |
| local TENANT_ID=$1 | |
| local PAYLOAD=$2 | |
| HTTP_CODE=$(curl -sS -o /tmp/tenant_resp.txt -w "%{http_code}" \ | |
| -X POST "${GATEWAY_URL}/v1/tenants" \ | |
| -H "Content-Type: application/json" \ | |
| -H "X-Tenant-Slug: dev-tenant" \ | |
| -d "$PAYLOAD") | |
| echo "${TENANT_ID}: HTTP ${HTTP_CODE}" | |
| if [ "$HTTP_CODE" != "200" ] && [ "$HTTP_CODE" != "201" ] && [ "$HTTP_CODE" != "409" ]; then | |
| echo "ERROR: Unexpected response for ${TENANT_ID}:" | |
| cat /tmp/tenant_resp.txt | |
| exit 1 | |
| fi | |
| } | |
| create_tenant "acme_corp" '{"tenantId":"acme_corp","displayName":"ACME Corporation","settlementAsset":"GBP","slug":"acme-corp"}' | |
| create_tenant "energy_co" '{"tenantId":"energy_co","displayName":"Energy Co Ltd","settlementAsset":"KWH","slug":"energy-co"}' | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '22' | |
| cache: 'npm' | |
| cache-dependency-path: frontend/package-lock.json | |
| - name: Install frontend dependencies | |
| working-directory: frontend | |
| run: npm ci | |
| - name: Install Playwright browsers | |
| working-directory: frontend | |
| run: npx playwright install --with-deps chromium | |
| - name: Run Playwright tests (shard ${{ matrix.shardIndex }}/4) | |
| working-directory: frontend | |
| env: | |
| CI: 'true' | |
| run: npx playwright test --shard=${{ matrix.shardIndex }}/4 --reporter=blob | |
| - name: Upload blob report | |
| uses: actions/upload-artifact@v7 | |
| if: always() | |
| with: | |
| name: blob-report-${{ matrix.shardIndex }} | |
| path: frontend/blob-report/ | |
| retention-days: 1 | |
| - name: Upload Playwright traces | |
| uses: actions/upload-artifact@v7 | |
| if: failure() | |
| with: | |
| name: playwright-traces-${{ matrix.shardIndex }} | |
| path: frontend/test-results/ | |
| retention-days: 30 | |
| # =========================================================================== | |
| # Merge: combine shard reports into a single HTML report | |
| # =========================================================================== | |
| merge-reports: | |
| name: Merge E2E Reports | |
| runs-on: ubuntu-latest | |
| needs: e2e | |
| if: ${{ always() && needs.e2e.result != 'skipped' }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '22' | |
| cache: 'npm' | |
| cache-dependency-path: frontend/package-lock.json | |
| - name: Install frontend dependencies | |
| working-directory: frontend | |
| run: npm ci | |
| - name: Download blob reports | |
| uses: actions/download-artifact@v8 | |
| with: | |
| pattern: blob-report-* | |
| path: frontend/all-blob-reports | |
| merge-multiple: true | |
| - name: Merge reports | |
| working-directory: frontend | |
| run: npx playwright merge-reports --reporter=html all-blob-reports | |
| - name: Upload merged report | |
| uses: actions/upload-artifact@v7 | |
| if: always() | |
| with: | |
| name: playwright-report | |
| path: frontend/playwright-report/ | |
| retention-days: 30 |