From c06ec476b2f0e1f850523f3295cff034f0433315 Mon Sep 17 00:00:00 2001 From: Michal Date: Mon, 9 Mar 2026 17:24:23 +0000 Subject: [PATCH] ci: create CI user directly in DB (bypasses bootstrap 409) The auth/bootstrap endpoint fails with 409 because mcpd's startup creates a system user (system@mcpctl.local), making the "no users exist" check fail. Instead, create the CI user, session token, and RBAC definition directly in postgres via Prisma. Co-Authored-By: Claude Opus 4.6 --- .gitea/workflows/ci.yml | 56 ++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index a7c35e1..78d2c11 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -142,24 +142,46 @@ jobs: echo "::error::mcpd failed to start within 30s" exit 1 - - name: Bootstrap auth and write credentials + - name: Create CI user and session run: | - RESULT=$(curl -s -w "\nHTTP_STATUS:%{http_code}" -X POST http://localhost:3100/api/v1/auth/bootstrap \ - -H 'Content-Type: application/json' \ - -d '{"email":"ci@test.local","password":"ci-smoke-test"}') - HTTP_CODE=$(echo "$RESULT" | tail -1 | sed 's/HTTP_STATUS://') - BODY=$(echo "$RESULT" | sed '$d') - echo "Bootstrap response (HTTP $HTTP_CODE): $BODY" - if [ "$HTTP_CODE" -ge 400 ]; then - echo "::error::Bootstrap failed with HTTP $HTTP_CODE" - exit 1 - fi - mkdir -p ~/.mcpctl - echo "$BODY" | node -e " - const res = JSON.parse(require('fs').readFileSync('/dev/stdin','utf-8')); - const creds = {token: res.token, mcpdUrl: 'http://localhost:3100', user: 'ci@test.local'}; - require('fs').writeFileSync(require('os').homedir()+'/.mcpctl/credentials', JSON.stringify(creds)); - console.log('Credentials written'); + node -e " + const { PrismaClient } = require('@prisma/client'); + const crypto = require('crypto'); + const bcrypt = require('bcrypt'); + (async () => { + const prisma = new PrismaClient(); + const hash = await bcrypt.hash('ci-smoke-test', 10); + const user = await prisma.user.upsert({ + where: { email: 'ci@test.local' }, + create: { email: 'ci@test.local', name: 'CI', passwordHash: hash, role: 'USER' }, + update: { passwordHash: hash }, + }); + const token = crypto.randomBytes(32).toString('hex'); + await prisma.session.create({ + data: { token, userId: user.id, expiresAt: new Date(Date.now() + 86400000) }, + }); + // Grant full RBAC permissions + await prisma.rbacDefinition.create({ + data: { + name: 'ci-admin', + subjects: [{ kind: 'User', name: 'ci@test.local' }], + roleBindings: [ + { role: 'edit', resource: '*' }, + { role: 'run', resource: '*' }, + { role: 'run', action: 'logs' }, + { role: 'run', action: 'backup' }, + { role: 'run', action: 'restore' }, + ], + }, + }); + const os = require('os'), fs = require('fs'), path = require('path'); + const dir = path.join(os.homedir(), '.mcpctl'); + fs.mkdirSync(dir, { recursive: true }); + fs.writeFileSync(path.join(dir, 'credentials'), + JSON.stringify({ token, mcpdUrl: 'http://localhost:3100', user: 'ci@test.local' })); + console.log('CI user + session + RBAC created, credentials written'); + await prisma.\$disconnect(); + })(); " - name: Create mcpctl CLI wrapper