Skip to content

feat: autoDeploy toggle on Service — skip auto-deploy when disabled#238

Open
wonderwomancode wants to merge 1 commit into
mainfrom
feat/issue-65-auto-deploy-toggle
Open

feat: autoDeploy toggle on Service — skip auto-deploy when disabled#238
wonderwomancode wants to merge 1 commit into
mainfrom
feat/issue-65-auto-deploy-toggle

Conversation

@wonderwomancode

Copy link
Copy Markdown
Contributor

Summary

Part of alternatefutures/web-app.alternatefutures.ai#65

  • Adds autoDeploy Boolean @default(true) to the Service Prisma model with a migration
  • Exposes autoDeploy on the Service GraphQL type and in UpdateServiceInput
  • updateService resolver validates and persists the new field
  • buildCallbackEndpoint: gates autoDeployAfterBuild() behind service.autoDeploy !== false — when disabled, the build completes normally (image pushed, lastBuildSha + lastBuildStatus updated) but no Akash/Phala deployment is triggered

Default is true so all existing services keep the current behaviour with no action required.

Test plan

  • pnpm build passes (no TypeScript errors)
  • pnpm test — all 847 tests pass
  • Migration: ALTER TABLE "Service" ADD COLUMN "autoDeploy" BOOLEAN NOT NULL DEFAULT true
  • Set autoDeploy=false on a service, push a commit — confirm build runs but deploy is skipped (log line: "skipping auto-deploy: autoDeploy is disabled for service")
  • Set autoDeploy=true — confirm push triggers deploy as before

🤖 Generated with Claude Code

#65

- prisma/schema.prisma: add autoDeploy Boolean @default(true) to Service
- prisma/migrations/…: ADD COLUMN autoDeploy with default true
- typeDefs.ts: expose autoDeploy on Service type and in UpdateServiceInput
- resolvers/index.ts: accept autoDeploy in updateService mutation
- buildCallbackEndpoint.ts: gate autoDeployAfterBuild on service.autoDeploy

When autoDeploy is false, a push still builds the image and records
lastBuildSha/lastBuildStatus, but does not trigger an Akash/Phala
deployment. The user deploys manually via the UI. Default is true so all
existing services are unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@claude

claude Bot commented Apr 28, 2026

Copy link
Copy Markdown

Claude encountered an error —— View job


I'll analyze this and get back to you.

@wonderwomancode

Copy link
Copy Markdown
Contributor Author

Quinn QA Review

Verdict: REQUEST CHANGES

Note: GitHub doesn't allow a reviewer to formally request-changes on their own PR via the review API. Posting as a comment with the same weight — this must be addressed before Senku/Lain review.


Test coverage findings

This is the primary blocker.

The PR adds a new conditional branch in buildCallbackEndpoint.ts — the most critical path in the codebase (build → auto-deploy pipeline) — with zero automated test coverage. There is no buildCallbackEndpoint.test.ts file at all, before or after this PR.

The 847 existing tests all pass, but they test 0 lines of buildCallbackEndpoint.ts. The new autoDeploy === false guard is the entire point of this PR, and it is completely untested.

Required test cases:

  1. autoDeploy = false on the service → autoDeployAfterBuild is not called after a SUCCEEDED callback
  2. autoDeploy = true (explicit) → autoDeployAfterBuild is called (regression guard for the default path)
  3. autoDeploy = true (DB default) → same as above, ensures the db default doesn't get lost in the include

The updateService resolver change also has no tests:

  • autoDeploy: false → persists correctly
  • autoDeploy: true → persists correctly
  • autoDeploy: null → throws GraphQLError('autoDeploy must be a boolean.')
  • autoDeploy not present in input → no-op, no DB write for this field

The mocking infrastructure already exists in mutation.test.ts and buildSpawner.test.ts — these are straightforward to add.


Regression risks

Low overall, but only because the logic reads correctly under analysis. With no tests, there's no automated regression guard if someone later refactors the buildJob Prisma include query and accidentally adds a select clause that drops autoDeploy from the service join — the feature would silently stop working (always deploys, autoDeploy=false ignored).

Migration is safe: NOT NULL DEFAULT true backfills existing rows correctly, behavioral parity for all existing services is preserved.


Code quality findings

Input type mismatch — non-blocking but worth fixing before merge:

UpdateServiceInput.autoDeploy is declared as Boolean (nullable) in the GraphQL schema (typeDefs.ts:495), which tells clients that passing null is valid. But the runtime validator in resolvers/index.ts:1849 rejects null with throw new GraphQLError('autoDeploy must be a boolean.').

A client that introspects the schema and passes autoDeploy: null gets an opaque error. Fix by either:

  • Making the input type autoDeploy: Boolean! (non-null) to match the runtime behavior, or
  • Treating null in the validator as a no-op (skip the field)

The former is simpler given the DB is NOT NULL DEFAULT true and there's no "reset to default" use case.

Logic is sound otherwise:

  • job.service.autoDeploy === false is strict equality on a non-nullable boolean — correct, conservative, won't accidentally skip deploys
  • The service include in the buildJob query uses no select restriction, so autoDeploy is present on job.service automatically via Prisma's default scalar inclusion
  • Commit status still posts success when a build succeeds with autoDeploy=false — correct, the build did succeed

Blockers

  1. Add buildCallbackEndpoint.test.ts covering at minimum: autoDeploy=false skips deploy, autoDeploy=true triggers deploy. Mock autoDeployAfterBuild (or the underlying Prisma + akash/phala mutation calls) to avoid integration dependencies.
  2. Add updateService + autoDeploy tests to mutation.test.ts covering the three input cases above.

Suggested follow-ups (non-blocking)

  • Fix UpdateServiceInput.autoDeploy: BooleanBoolean! to match runtime behavior
  • The existing buildCallbackEndpoint.ts is fully uncovered (847 tests, 0 touching this file). Good to address incrementally — the CAS idempotency logic and token verification are particularly worth covering.
  • Consider logging the autoDeploy=false skip in the GitHub commit status description (e.g., "Built — auto-deploy disabled") so users can see at a glance why no deployment appeared after a successful build

Not escalating to Senku or Lain until tests are added.

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