|
|
@@ -187,6 +187,106 @@ Development uses `dotenv-flow`:
|
|
|
|
|
|
See `.env.example` for available variables.
|
|
|
|
|
|
+## Smoke Testing
|
|
|
+
|
|
|
+The devcontainer always has MongoDB and other services running (see `.claude/rules/devcontainer.md`). The dev server **can and should** be started for smoke verification — never claim the runtime environment is unavailable.
|
|
|
+
|
|
|
+### Workflow
|
|
|
+
|
|
|
+**Step 1 — Override env vars without touching committed files**
|
|
|
+
|
|
|
+Create `apps/app/.env.development.local` (highest dotenv-flow priority; gitignored):
|
|
|
+
|
|
|
+```bash
|
|
|
+# Example: disable vault feature to test 404 behaviour
|
|
|
+cat > apps/app/.env.development.local << 'EOF'
|
|
|
+VAULT_ENABLED=false
|
|
|
+EOF
|
|
|
+```
|
|
|
+
|
|
|
+dotenv-flow load order (first definition wins):
|
|
|
+1. `.env.development.local` ← your override
|
|
|
+2. `.env.local`
|
|
|
+3. `.env.development` ← committed defaults
|
|
|
+4. `.env`
|
|
|
+
|
|
|
+> **Note:** nodemon watches `*.*` but does **not** reliably pick up dotfile changes (files starting with `.`). After editing `.env.development.local`, kill the ts-node process manually so nodemon restarts it with the new env:
|
|
|
+> ```bash
|
|
|
+> kill $(ss -tlnp | grep ':3000' | grep -o 'pid=[0-9]*' | cut -d= -f2)
|
|
|
+> ```
|
|
|
+
|
|
|
+**Step 2 — Start the dev server in background**
|
|
|
+
|
|
|
+```bash
|
|
|
+turbo run dev --filter @growi/app &
|
|
|
+```
|
|
|
+
|
|
|
+Wait for the ready message:
|
|
|
+```bash
|
|
|
+until curl -s http://localhost:3000/ > /dev/null 2>&1; do sleep 1; done
|
|
|
+echo "Server ready"
|
|
|
+```
|
|
|
+
|
|
|
+Or watch the log for `Express server is listening on port 3000`.
|
|
|
+
|
|
|
+**Step 3 — Curl the endpoints**
|
|
|
+
|
|
|
+```bash
|
|
|
+# Feature disabled → 404 (no Retry-After)
|
|
|
+curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/_vault/repo.git/info/refs?service=git-upload-pack
|
|
|
+
|
|
|
+# Push attempt → always 403
|
|
|
+curl -s -o /dev/null -w "%{http_code}" -X POST http://localhost:3000/_vault/repo.git/git-receive-pack
|
|
|
+
|
|
|
+# Check response body
|
|
|
+curl -s http://localhost:3000/_vault/repo.git/info/refs?service=git-upload-pack
|
|
|
+
|
|
|
+# Check specific headers
|
|
|
+curl -sI http://localhost:3000/_vault/repo.git/info/refs?service=git-upload-pack | grep -i retry-after
|
|
|
+```
|
|
|
+
|
|
|
+**Step 4 — Switch env and retest**
|
|
|
+
|
|
|
+Edit `.env.development.local`, then kill and wait for nodemon to restart:
|
|
|
+
|
|
|
+```bash
|
|
|
+echo "VAULT_ENABLED=true" > apps/app/.env.development.local
|
|
|
+kill $(ss -tlnp | grep ':3000' | grep -o 'pid=[0-9]*' | cut -d= -f2)
|
|
|
+until curl -s http://localhost:3000/ > /dev/null 2>&1; do sleep 1; done
|
|
|
+```
|
|
|
+
|
|
|
+**Step 5 — Manipulate MongoDB state if needed**
|
|
|
+
|
|
|
+```bash
|
|
|
+node -e "
|
|
|
+const { MongoClient } = require('/workspace/growi-vault/node_modules/.pnpm/mongodb@6.8.0_@aws-sdk+credential-providers@3.600.0_@aws-sdk+client-sso-oidc@3.600.0__socks@2.8.3/node_modules/mongodb');
|
|
|
+async function main() {
|
|
|
+ const client = new MongoClient('mongodb://mongo:27017/growi?replicaSet=rs0');
|
|
|
+ await client.connect();
|
|
|
+ // e.g. reset bootstrap state
|
|
|
+ await client.db('growi').collection('vault_sync_state').updateOne(
|
|
|
+ { _id: 'singleton' },
|
|
|
+ { \$set: { bootstrapState: 'pending' } },
|
|
|
+ { upsert: true }
|
|
|
+ );
|
|
|
+ await client.close();
|
|
|
+}
|
|
|
+main().catch(console.error);
|
|
|
+"
|
|
|
+```
|
|
|
+
|
|
|
+**Step 6 — Stop the server**
|
|
|
+
|
|
|
+```bash
|
|
|
+kill $(pgrep -f "nodemon|src/server/app.ts") 2>/dev/null
|
|
|
+```
|
|
|
+
|
|
|
+### What counts as a passing smoke test
|
|
|
+
|
|
|
+- The Express server starts without throwing on import (`Express server is listening on port 3000` in logs)
|
|
|
+- Feature-flag–gated endpoints return the correct status code for each flag state (404 when disabled, 503 with the right message when bootstrap incomplete, 403 for read-only enforcement)
|
|
|
+- No unhandled exception in server startup logs
|
|
|
+
|
|
|
## Troubleshooting
|
|
|
|
|
|
### Migration Issues
|