Skip to content

Comments

[DO NOT MERGE]: eng 2476 make workspacek8snamespace non nullable part 2#4993

Draft
chronark wants to merge 6 commits intomainfrom
eng-2476-make-workspacek8snamespace-non-nullable-part-2
Draft

[DO NOT MERGE]: eng 2476 make workspacek8snamespace non nullable part 2#4993
chronark wants to merge 6 commits intomainfrom
eng-2476-make-workspacek8snamespace-non-nullable-part-2

Conversation

@chronark
Copy link
Collaborator

@chronark chronark commented Feb 11, 2026

  • feat: always write a k8s_namespace when createing a workspace
  • fix: lock file
  • chore: make workspace.k8s_namespace not null

we need to run seeding and migrations for this PR

@linear
Copy link

linear bot commented Feb 11, 2026

@vercel
Copy link

vercel bot commented Feb 11, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
dashboard Ready Ready Preview, Comment Feb 11, 2026 0:37am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
engineering Ignored Ignored Preview Feb 11, 2026 0:37am

Request Review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 11, 2026

📝 Walkthrough

Walkthrough

This pull request makes the k8s_namespace column in the workspaces table non-nullable by updating the schema, regenerating database models and query parameter structs to use plain string instead of sql.NullString, updating all callsites to handle the plain string type, and adding a migration script to backfill existing workspace records with k8s_namespace values.

Changes

Cohort / File(s) Summary
Database Schema
pkg/db/schema.sql, web/internal/db/src/schema/workspaces.ts
Changed k8s_namespace column from nullable to NOT NULL, enforcing non-null values.
Seed Data
dev/04-seed-workspace.sql
Added k8s_namespace column and value 'ws-local-root' to root workspace insert statement.
Generated Database Models
pkg/db/models_generated.go
Updated Workspace struct K8sNamespace field type from sql.NullString to string.
Generated Query Parameter Structs
pkg/db/workspace_insert.sql_generated.go, pkg/db/workspace_set_k8s_namespace.sql_generated.go
Updated InsertWorkspaceParams and SetWorkspaceK8sNamespaceParams K8sNamespace field types from sql.NullString to string.
Generated Query Row Structs
pkg/db/deployment_topology_by_id_and_region.sql_generated.go, pkg/db/deployment_topology_list_by_versions.sql_generated.go, pkg/db/deployment_topology_list_desired.sql_generated.go
Updated K8sNamespace field types in query result row structs from sql.NullString to string; removed unused database/sql imports.
Service Layer - Deployment & Cluster
svc/ctrl/services/cluster/rpc_get_desired_deployment_state.go, svc/ctrl/services/cluster/rpc_watch_deployments.go
Updated K8SNamespace assignments to access K8sNamespace directly instead of calling .String method.
Service Layer - Deploy Handler
svc/ctrl/worker/deploy/deploy_handler.go
Updated validation and assignment logic for K8sNamespace from sql.NullString-based checks (Valid flag) to plain string comparisons (empty check).
Service Layer - Policy
svc/ctrl/worker/deploy/cilium_policy.go
Updated three namespace references from K8sNamespace.String to K8sNamespace in CiliumNetworkPolicy metadata and label matching.
Seed & Test Utilities
svc/api/internal/testutil/seed/seed.go, svc/ctrl/integration/seed/seed.go
Updated K8sNamespace assignments in workspace creation from sql.NullString{Valid: true, String: value} to plain string value.
Test Files
svc/api/routes/v2_identities_list_identities/200_test.go, svc/api/routes/v2_identities_list_identities/cross_workspace_test.go, svc/api/routes/v2_keys_add_permissions/404_test.go, svc/api/routes/v2_keys_remove_permissions/403_test.go, svc/api/routes/v2_keys_remove_permissions/404_test.go, svc/api/routes/v2_keys_set_roles/404_test.go, pkg/db/retry_test.go
Added K8sNamespace field with uid.DNS1035() value to InsertWorkspaceParams in workspace creation calls within test setups.
Migration Script
web/tools/migrate/backfill_k8s_namespace.ts
New TypeScript migration script that connects to database, iterates over workspaces with null k8sNamespace in batches of 1000, generates DNS-compliant namespaces, and updates records.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • Issue addressing making workspace K8sNamespace non-nullable throughout the system by updating schema, generated database models, service layer logic, and adding backfill migration for existing workspace records.
🚥 Pre-merge checks | ❌ 3
❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Description check ⚠️ Warning Description provides bullet points about changes but lacks required template sections like issue reference, type classification, test instructions, and checklist items. Follow the provided template: add issue number, select change type, describe testing approach, and complete all required checklist items.
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive Title is related to the main change but uses draft marker [DO NOT MERGE] and is overly vague with abbreviated terminology. Remove [DO NOT MERGE] marker and clarify: use 'Make workspace k8s_namespace field non-nullable' or similar, avoiding abbreviations.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch eng-2476-make-workspacek8snamespace-non-nullable-part-2

Comment @coderabbitai help to get the list of available commands and usage tips.

@chronark chronark changed the base branch from main to eng-2476-make-workspacek8snamespace-non-nullable February 11, 2026 12:30
Base automatically changed from eng-2476-make-workspacek8snamespace-non-nullable to main February 11, 2026 12:33
@chronark chronark changed the title eng 2476 make workspacek8snamespace non nullable part 2 [DO NOT MERGET]: eng 2476 make workspacek8snamespace non nullable part 2 Feb 11, 2026
@chronark chronark changed the title [DO NOT MERGET]: eng 2476 make workspacek8snamespace non nullable part 2 [DO NOT MERGE]: eng 2476 make workspacek8snamespace non nullable part 2 Feb 11, 2026
@chronark
Copy link
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 11, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
pkg/db/workspace_insert.sql_generated.go (1)

8-11: ⚠️ Potential issue | 🔴 Critical

Unused import database/sql causes build failure.

Pipeline reports this import is unused after removing sql.NullString. Since this is sqlc-generated code, regenerate with sqlc generate to fix.

svc/ctrl/worker/deploy/deploy_handler.go (1)

98-103: ⚠️ Potential issue | 🟡 Minor

Empty-string won’t persist

SetWorkspaceK8sNamespace only updates NULL; if k8s_namespace is "", update no-ops and ws uses a value not stored. Align predicate or handle '' in the update.

🤖 Fix all issues with AI agents
In `@web/tools/migrate/backfill_k8s_namespace.ts`:
- Around line 27-33: Wrap the top-level main() invocation in a try-catch and
handle errors: call main() inside an async IIFE or Promise chain and catch any
thrown errors, log them (using console.error or existing logger) and exit with
non-zero status; ensure the catch reports the error from DB operations such as
the db.update on schema.workspaces (and any dns1035 collisions) so failures in
the loop updating k8sNamespace are surfaced and cause process exit instead of
being unhandled.
🧹 Nitpick comments (1)
web/tools/migrate/backfill_k8s_namespace.ts (1)

44-44: Use fault for script errors

main() runs without fault-based handling; failures can surface as unhandled rejections. Wrap per repo fault pattern.

As per coding guidelines: Use fault library for error handling.

Comment on lines +27 to +33
for (const workspace of workspaces) {
const namespace = dns1035();

await db
.update(schema.workspaces)
.set({ k8sNamespace: namespace })
.where(eq(schema.workspaces.id, workspace.id));
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n web/tools/migrate/backfill_k8s_namespace.ts

Repository: unkeyed/unkey

Length of output: 1587


🏁 Script executed:

# Find dns1035 function definition
rg "export.*dns1035|function dns1035" -A 5 --type ts

Repository: unkeyed/unkey

Length of output: 462


🏁 Script executed:

# Search for schema.workspaces definition
fd "schema" --type ts | head -20

Repository: unkeyed/unkey

Length of output: 226


🏁 Script executed:

# Look for workspaces schema and k8sNamespace field
rg "k8sNamespace" --type ts -B 2 -A 2

Repository: unkeyed/unkey

Length of output: 3843


🏁 Script executed:

# Check for fault library usage in migration files
rg "from.*fault|import.*fault" web/tools/migrate --type-add "ts:*.ts" -A 2

Repository: unkeyed/unkey

Length of output: 39


🏁 Script executed:

# Look for error handling patterns in other migrations
fd backfill web/tools/migrate --type f

Repository: unkeyed/unkey

Length of output: 100


🏁 Script executed:

# Check for retry logic patterns in the codebase
rg "retry|catch.*Error" web/tools/migrate --type-add "ts:*.ts" -A 2 -B 1

Repository: unkeyed/unkey

Length of output: 39


🏁 Script executed:

# Check for fault library usage patterns in the broader codebase
rg "from.*fault|import.*fault" web/ --max-count 5 -l

Repository: unkeyed/unkey

Length of output: 2901


🏁 Script executed:

# Look at error handling in database operations
rg "\.catch\(|try \{" web/tools/migrate -A 3 -B 1

Repository: unkeyed/unkey

Length of output: 1494


🏁 Script executed:

# Check dns1035 collision probability - look at how many values it can generate
cat web/internal/id/src/generate.ts | head -30

Repository: unkeyed/unkey

Length of output: 732


Add error handling for main() invocation

The main() function call on line 44 lacks error handling. Add a try-catch block or implement proper error handling per TypeScript guidelines, as shown in other migration scripts (ch_copy.ts, ch_logs.ts).

While theoretically a unique constraint collision on k8sNamespace could occur with dns1035(), the probability is negligible (57-character alphabet, 12+ character names = millions of combinations). The primary concern is unhandled database operation errors.

🤖 Prompt for AI Agents
In `@web/tools/migrate/backfill_k8s_namespace.ts` around lines 27 - 33, Wrap the
top-level main() invocation in a try-catch and handle errors: call main() inside
an async IIFE or Promise chain and catch any thrown errors, log them (using
console.error or existing logger) and exit with non-zero status; ensure the
catch reports the error from DB operations such as the db.update on
schema.workspaces (and any dns1035 collisions) so failures in the loop updating
k8sNamespace are surfaced and cause process exit instead of being unhandled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants