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
|
type: redis
|
||||||
name: "job-queue"
|
name: "job-queue"
|
||||||
|
|
||||||
add-api:
|
add-components:
|
||||||
description: Public API (Producer)
|
description: Add API + Worker atomically (single git commit)
|
||||||
depends_on: [create-project, add-redis]
|
depends_on: [create-project, add-redis]
|
||||||
action: api
|
action: api
|
||||||
method: POST
|
method: POST
|
||||||
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components/batch"
|
||||||
body:
|
body:
|
||||||
type: service
|
components:
|
||||||
name: "api"
|
- type: service
|
||||||
|
name: "api"
|
||||||
add-worker:
|
- type: worker
|
||||||
description: Worker Service (Consumer)
|
name: "background-processor"
|
||||||
depends_on: [create-project, add-redis]
|
|
||||||
action: api
|
|
||||||
method: POST
|
|
||||||
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
|
|
||||||
body:
|
|
||||||
type: worker
|
|
||||||
name: "background-processor"
|
|
||||||
|
|
||||||
wait-infra:
|
wait-infra:
|
||||||
depends_on: [create-project, add-api, add-worker]
|
depends_on: [create-project, add-components]
|
||||||
action: wait_pipeline
|
action: wait_pipeline
|
||||||
project_id: "{{ .outputs.create-project.project_id }}"
|
project_id: "{{ .outputs.create-project.project_id }}"
|
||||||
|
|
||||||
|
|||||||
@ -20,8 +20,9 @@ steps:
|
|||||||
- domain: .data.domain
|
- domain: .data.domain
|
||||||
|
|
||||||
add-redis:
|
add-redis:
|
||||||
description: Add Redis for Pub/Sub
|
description: Add Redis for Pub/Sub (may already exist from skeleton)
|
||||||
depends_on: [create-project]
|
depends_on: [create-project]
|
||||||
|
on_error: continue
|
||||||
action: api
|
action: api
|
||||||
method: POST
|
method: POST
|
||||||
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
|
||||||
|
|||||||
@ -20,8 +20,9 @@ steps:
|
|||||||
- domain: .data.domain
|
- domain: .data.domain
|
||||||
|
|
||||||
add-db:
|
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]
|
depends_on: [create-project]
|
||||||
|
on_error: continue
|
||||||
action: api
|
action: api
|
||||||
method: POST
|
method: POST
|
||||||
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
|
||||||
@ -30,8 +31,9 @@ steps:
|
|||||||
name: "main-db"
|
name: "main-db"
|
||||||
|
|
||||||
add-redis:
|
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]
|
depends_on: [create-project]
|
||||||
|
on_error: continue
|
||||||
action: api
|
action: api
|
||||||
method: POST
|
method: POST
|
||||||
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
|
||||||
@ -39,29 +41,23 @@ steps:
|
|||||||
type: redis
|
type: redis
|
||||||
name: "job-queue"
|
name: "job-queue"
|
||||||
|
|
||||||
add-auth:
|
add-components:
|
||||||
depends_on: [add-db]
|
description: Add auth, chat, and worker atomically (single git commit)
|
||||||
|
depends_on: [add-db, add-redis]
|
||||||
action: api
|
action: api
|
||||||
method: POST
|
method: POST
|
||||||
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components/batch"
|
||||||
body: { type: service, name: "auth-svc" }
|
body:
|
||||||
|
components:
|
||||||
add-chat:
|
- type: service
|
||||||
depends_on: [add-redis]
|
name: "auth-svc"
|
||||||
action: api
|
- type: service
|
||||||
method: POST
|
name: "chat-svc"
|
||||||
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
|
- type: worker
|
||||||
body: { type: service, name: "chat-svc" }
|
name: "worker-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" }
|
|
||||||
|
|
||||||
wait-infra:
|
wait-infra:
|
||||||
depends_on: [add-auth, add-chat, add-worker]
|
depends_on: [add-components]
|
||||||
action: wait_pipeline
|
action: wait_pipeline
|
||||||
project_id: "{{ .outputs.create-project.project_id }}"
|
project_id: "{{ .outputs.create-project.project_id }}"
|
||||||
|
|
||||||
|
|||||||
@ -3,21 +3,19 @@ FROM golang:1.23-alpine AS builder
|
|||||||
|
|
||||||
RUN apk add --no-cache git
|
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 GOPRIVATE=git.threesix.ai/*
|
||||||
ENV GOWORK=/app/go.work
|
ENV GOWORK=off
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Copy go workspace and all source (workspace deps are local)
|
# Copy shared pkg and this service only
|
||||||
# Note: go.work.sum may not exist if no external dependencies have been synced yet
|
|
||||||
COPY go.work ./
|
|
||||||
COPY go.work.su[m] ./
|
|
||||||
COPY pkg/ ./pkg/
|
COPY pkg/ ./pkg/
|
||||||
COPY services/{{COMPONENT_NAME}}/ ./services/{{COMPONENT_NAME}}/
|
COPY services/{{COMPONENT_NAME}}/ ./services/{{COMPONENT_NAME}}/
|
||||||
|
|
||||||
# Build from workspace root
|
# Build from the service directory (uses replace directive for ../pkg)
|
||||||
RUN CGO_ENABLED=0 go build -o /{{COMPONENT_NAME}} ./services/{{COMPONENT_NAME}}/cmd/server
|
RUN cd services/{{COMPONENT_NAME}} && CGO_ENABLED=0 go build -o /{{COMPONENT_NAME}} ./cmd/server
|
||||||
|
|
||||||
# Production stage
|
# Production stage
|
||||||
FROM alpine:3.19
|
FROM alpine:3.19
|
||||||
|
|||||||
@ -3,21 +3,19 @@ FROM golang:1.23-alpine AS builder
|
|||||||
|
|
||||||
RUN apk add --no-cache git
|
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 GOPRIVATE=git.threesix.ai/*
|
||||||
ENV GOWORK=/app/go.work
|
ENV GOWORK=off
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Copy go workspace and all source (workspace deps are local)
|
# Copy shared pkg and this worker only
|
||||||
# Note: go.work.sum may not exist if no external dependencies have been synced yet
|
|
||||||
COPY go.work ./
|
|
||||||
COPY go.work.su[m] ./
|
|
||||||
COPY pkg/ ./pkg/
|
COPY pkg/ ./pkg/
|
||||||
COPY workers/{{COMPONENT_NAME}}/ ./workers/{{COMPONENT_NAME}}/
|
COPY workers/{{COMPONENT_NAME}}/ ./workers/{{COMPONENT_NAME}}/
|
||||||
|
|
||||||
# Build from workspace root
|
# Build from the worker directory (uses replace directive for ../pkg)
|
||||||
RUN CGO_ENABLED=0 go build -o /{{COMPONENT_NAME}} ./workers/{{COMPONENT_NAME}}/cmd/worker
|
RUN cd workers/{{COMPONENT_NAME}} && CGO_ENABLED=0 go build -o /{{COMPONENT_NAME}} ./cmd/worker
|
||||||
|
|
||||||
# Production stage
|
# Production stage
|
||||||
FROM alpine:3.19
|
FROM alpine:3.19
|
||||||
|
|||||||
@ -9,12 +9,11 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"{{GO_MODULE}}/pkg/config"
|
|
||||||
"{{GO_MODULE}}/pkg/database"
|
"{{GO_MODULE}}/pkg/database"
|
||||||
"{{GO_MODULE}}/pkg/logging"
|
"{{GO_MODULE}}/pkg/logging"
|
||||||
"{{GO_MODULE}}/pkg/queue"
|
"{{GO_MODULE}}/pkg/queue"
|
||||||
|
"{{GO_MODULE}}/workers/{{COMPONENT_NAME}}/internal/config"
|
||||||
"{{GO_MODULE}}/workers/{{COMPONENT_NAME}}/internal/handlers"
|
"{{GO_MODULE}}/workers/{{COMPONENT_NAME}}/internal/handlers"
|
||||||
workerconfig "{{GO_MODULE}}/workers/{{COMPONENT_NAME}}/internal/config"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed migrations/*.sql
|
//go:embed migrations/*.sql
|
||||||
@ -28,7 +27,7 @@ func main() {
|
|||||||
}).WithService("{{COMPONENT_NAME}}")
|
}).WithService("{{COMPONENT_NAME}}")
|
||||||
|
|
||||||
// Initialize configuration
|
// Initialize configuration
|
||||||
cfg, err := workerconfig.Load()
|
cfg, err := config.Load()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("failed to load config", "error", err)
|
logger.Error("failed to load config", "error", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user