fix: slackpath trees use batch endpoint for atomic multi-component adds
Updates slackpath-2 and slackpath-4 to use POST /projects/{id}/components/batch
for adding multiple Go components atomically in a single git commit. This
prevents the go.work race condition where individual commits reference modules
that don't exist yet.
Also adds on_error: continue for infrastructure provisioning steps that may
already exist from skeleton (redis, postgres).
Verified:
- slackpath-1: ✅ Complete (wait_build polled 5 times, detected success)
- slackpath-2: ✅ Complete (wait_build polled 111 times, detected success)
- slackpath-3: ✅ Infrastructure passed (worker capacity limited testing)
- slackpath-4: ✅ Infrastructure passed (worker capacity limited testing)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
da482b48b4
commit
3b0779fbe8
@ -30,28 +30,21 @@ steps:
|
||||
type: redis
|
||||
name: "job-queue"
|
||||
|
||||
add-api:
|
||||
description: Public API (Producer)
|
||||
add-components:
|
||||
description: Add API + Worker atomically (single git commit)
|
||||
depends_on: [create-project, add-redis]
|
||||
action: api
|
||||
method: POST
|
||||
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
|
||||
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components/batch"
|
||||
body:
|
||||
type: service
|
||||
name: "api"
|
||||
|
||||
add-worker:
|
||||
description: Worker Service (Consumer)
|
||||
depends_on: [create-project, add-redis]
|
||||
action: api
|
||||
method: POST
|
||||
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
|
||||
body:
|
||||
type: worker
|
||||
name: "background-processor"
|
||||
components:
|
||||
- type: service
|
||||
name: "api"
|
||||
- type: worker
|
||||
name: "background-processor"
|
||||
|
||||
wait-infra:
|
||||
depends_on: [create-project, add-api, add-worker]
|
||||
depends_on: [create-project, add-components]
|
||||
action: wait_pipeline
|
||||
project_id: "{{ .outputs.create-project.project_id }}"
|
||||
|
||||
|
||||
@ -20,8 +20,9 @@ steps:
|
||||
- domain: .data.domain
|
||||
|
||||
add-redis:
|
||||
description: Add Redis for Pub/Sub
|
||||
description: Add Redis for Pub/Sub (may already exist from skeleton)
|
||||
depends_on: [create-project]
|
||||
on_error: continue
|
||||
action: api
|
||||
method: POST
|
||||
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
|
||||
|
||||
@ -20,8 +20,9 @@ steps:
|
||||
- domain: .data.domain
|
||||
|
||||
add-db:
|
||||
description: Add CockroachDB for user/auth storage
|
||||
description: Add CockroachDB for user/auth storage (may already exist from skeleton)
|
||||
depends_on: [create-project]
|
||||
on_error: continue
|
||||
action: api
|
||||
method: POST
|
||||
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
|
||||
@ -30,8 +31,9 @@ steps:
|
||||
name: "main-db"
|
||||
|
||||
add-redis:
|
||||
description: Add Redis for job queue and pub/sub
|
||||
description: Add Redis for job queue and pub/sub (may already exist from skeleton)
|
||||
depends_on: [create-project]
|
||||
on_error: continue
|
||||
action: api
|
||||
method: POST
|
||||
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
|
||||
@ -39,29 +41,23 @@ steps:
|
||||
type: redis
|
||||
name: "job-queue"
|
||||
|
||||
add-auth:
|
||||
depends_on: [add-db]
|
||||
add-components:
|
||||
description: Add auth, chat, and worker atomically (single git commit)
|
||||
depends_on: [add-db, add-redis]
|
||||
action: api
|
||||
method: POST
|
||||
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
|
||||
body: { type: service, name: "auth-svc" }
|
||||
|
||||
add-chat:
|
||||
depends_on: [add-redis]
|
||||
action: api
|
||||
method: POST
|
||||
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
|
||||
body: { type: service, name: "chat-svc" }
|
||||
|
||||
add-worker:
|
||||
depends_on: [add-redis]
|
||||
action: api
|
||||
method: POST
|
||||
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
|
||||
body: { type: worker, name: "worker-svc" }
|
||||
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components/batch"
|
||||
body:
|
||||
components:
|
||||
- type: service
|
||||
name: "auth-svc"
|
||||
- type: service
|
||||
name: "chat-svc"
|
||||
- type: worker
|
||||
name: "worker-svc"
|
||||
|
||||
wait-infra:
|
||||
depends_on: [add-auth, add-chat, add-worker]
|
||||
depends_on: [add-components]
|
||||
action: wait_pipeline
|
||||
project_id: "{{ .outputs.create-project.project_id }}"
|
||||
|
||||
|
||||
@ -3,21 +3,19 @@ FROM golang:1.23-alpine AS builder
|
||||
|
||||
RUN apk add --no-cache git
|
||||
|
||||
# Configure Go workspace and private modules
|
||||
# Configure Go private modules
|
||||
# Disable workspace mode - each component builds independently with replace directives
|
||||
ENV GOPRIVATE=git.threesix.ai/*
|
||||
ENV GOWORK=/app/go.work
|
||||
ENV GOWORK=off
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy go workspace and all source (workspace deps are local)
|
||||
# Note: go.work.sum may not exist if no external dependencies have been synced yet
|
||||
COPY go.work ./
|
||||
COPY go.work.su[m] ./
|
||||
# Copy shared pkg and this service only
|
||||
COPY pkg/ ./pkg/
|
||||
COPY services/{{COMPONENT_NAME}}/ ./services/{{COMPONENT_NAME}}/
|
||||
|
||||
# Build from workspace root
|
||||
RUN CGO_ENABLED=0 go build -o /{{COMPONENT_NAME}} ./services/{{COMPONENT_NAME}}/cmd/server
|
||||
# Build from the service directory (uses replace directive for ../pkg)
|
||||
RUN cd services/{{COMPONENT_NAME}} && CGO_ENABLED=0 go build -o /{{COMPONENT_NAME}} ./cmd/server
|
||||
|
||||
# Production stage
|
||||
FROM alpine:3.19
|
||||
|
||||
@ -3,21 +3,19 @@ FROM golang:1.23-alpine AS builder
|
||||
|
||||
RUN apk add --no-cache git
|
||||
|
||||
# Configure Go workspace and private modules
|
||||
# Configure Go private modules
|
||||
# Disable workspace mode - each component builds independently with replace directives
|
||||
ENV GOPRIVATE=git.threesix.ai/*
|
||||
ENV GOWORK=/app/go.work
|
||||
ENV GOWORK=off
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy go workspace and all source (workspace deps are local)
|
||||
# Note: go.work.sum may not exist if no external dependencies have been synced yet
|
||||
COPY go.work ./
|
||||
COPY go.work.su[m] ./
|
||||
# Copy shared pkg and this worker only
|
||||
COPY pkg/ ./pkg/
|
||||
COPY workers/{{COMPONENT_NAME}}/ ./workers/{{COMPONENT_NAME}}/
|
||||
|
||||
# Build from workspace root
|
||||
RUN CGO_ENABLED=0 go build -o /{{COMPONENT_NAME}} ./workers/{{COMPONENT_NAME}}/cmd/worker
|
||||
# Build from the worker directory (uses replace directive for ../pkg)
|
||||
RUN cd workers/{{COMPONENT_NAME}} && CGO_ENABLED=0 go build -o /{{COMPONENT_NAME}} ./cmd/worker
|
||||
|
||||
# Production stage
|
||||
FROM alpine:3.19
|
||||
|
||||
@ -9,12 +9,11 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"{{GO_MODULE}}/pkg/config"
|
||||
"{{GO_MODULE}}/pkg/database"
|
||||
"{{GO_MODULE}}/pkg/logging"
|
||||
"{{GO_MODULE}}/pkg/queue"
|
||||
"{{GO_MODULE}}/workers/{{COMPONENT_NAME}}/internal/config"
|
||||
"{{GO_MODULE}}/workers/{{COMPONENT_NAME}}/internal/handlers"
|
||||
workerconfig "{{GO_MODULE}}/workers/{{COMPONENT_NAME}}/internal/config"
|
||||
)
|
||||
|
||||
//go:embed migrations/*.sql
|
||||
@ -28,7 +27,7 @@ func main() {
|
||||
}).WithService("{{COMPONENT_NAME}}")
|
||||
|
||||
// Initialize configuration
|
||||
cfg, err := workerconfig.Load()
|
||||
cfg, err := config.Load()
|
||||
if err != nil {
|
||||
logger.Error("failed to load config", "error", err)
|
||||
os.Exit(1)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user