Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
The wait-init step was timing out because it waited for the entire pipeline including docs build steps. The service (preferences-api) deploys successfully before docs. Added on_error: continue so the tree proceeds after service deploy. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
539 lines
17 KiB
YAML
539 lines
17 KiB
YAML
name: full-lifecycle
|
|
description: "Slack Path 5: The Full Lifecycle. Tests all 10 SDLC phases with explicit artifact approvals."
|
|
version: 1
|
|
|
|
vars:
|
|
project_name: ""
|
|
feature_slug: "user-preferences"
|
|
feature_title: "User Preferences API"
|
|
|
|
steps:
|
|
# ============================================================
|
|
# INFRASTRUCTURE
|
|
# ============================================================
|
|
create-project:
|
|
action: api
|
|
method: POST
|
|
endpoint: /project
|
|
body:
|
|
name: "{{ .vars.project_name }}"
|
|
description: "Slack Path 5: Full SDLC Lifecycle"
|
|
outputs:
|
|
- project_id: .data.name
|
|
- domain: .data.domain
|
|
|
|
add-db:
|
|
description: Add database for preferences storage
|
|
depends_on: [create-project]
|
|
on_error: continue
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
|
|
body:
|
|
type: postgres
|
|
name: "main-db"
|
|
|
|
add-service:
|
|
description: Add API service
|
|
depends_on: [add-db]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/components"
|
|
body:
|
|
type: service
|
|
name: "preferences-api"
|
|
|
|
wait-init:
|
|
description: Wait for initial deploy (docs builds may be slow)
|
|
depends_on: [add-service]
|
|
action: wait_pipeline
|
|
project_id: "{{ .outputs.create-project.project_id }}"
|
|
on_error: continue
|
|
|
|
# ============================================================
|
|
# PHASE 1: DRAFT
|
|
# Create feature (starts in draft phase)
|
|
# ============================================================
|
|
create-feature:
|
|
description: "Create feature in draft phase"
|
|
depends_on: [wait-init]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features"
|
|
body:
|
|
slug: "{{ .vars.feature_slug }}"
|
|
title: "{{ .vars.feature_title }}"
|
|
outputs:
|
|
- feature_phase: .data.phase
|
|
|
|
verify-draft:
|
|
description: "Verify feature is in draft phase"
|
|
depends_on: [create-feature]
|
|
action: shell
|
|
command: |
|
|
PHASE="{{ .outputs.create-feature.feature_phase }}"
|
|
if [ "$PHASE" == "draft" ]; then
|
|
echo "Feature created in draft phase"
|
|
exit 0
|
|
else
|
|
echo "Expected draft, got $PHASE"
|
|
exit 1
|
|
fi
|
|
|
|
# ============================================================
|
|
# PHASE 2: DRAFT → SPECIFIED
|
|
# Agent writes spec, API approves, transition
|
|
# ============================================================
|
|
write-spec:
|
|
description: "Agent writes the spec artifact"
|
|
depends_on: [verify-draft]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
|
|
body:
|
|
prompt: "/spec-feature {{ .vars.feature_slug }} --requirements 'CRUD API for user preferences. GET/PUT /preferences/{user_id}. Preferences are key-value pairs stored in DB. Support theme, language, notifications settings.'"
|
|
auto_commit: true
|
|
auto_push: true
|
|
git_clone_url: "https://git.threesix.ai/jordan/{{ .outputs.create-project.project_id }}.git"
|
|
outputs:
|
|
- build_id: .data.task_id
|
|
|
|
wait-spec:
|
|
depends_on: [write-spec]
|
|
action: wait_build
|
|
build_id: "{{ .outputs.write-spec.build_id }}"
|
|
max_attempts: 60
|
|
poll_interval: 5
|
|
|
|
approve-spec:
|
|
description: "API approves the spec artifact"
|
|
depends_on: [wait-spec]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/artifacts/spec/approve"
|
|
body:
|
|
comment: "Spec approved by automation"
|
|
|
|
transition-to-specified:
|
|
description: "Transition from draft to specified"
|
|
depends_on: [approve-spec]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/transition"
|
|
body:
|
|
phase: "specified"
|
|
outputs:
|
|
- new_phase: .data.phase
|
|
|
|
# ============================================================
|
|
# PHASE 3: SPECIFIED → PLANNED
|
|
# Agent writes design, tasks, qa_plan. API approves each.
|
|
# ============================================================
|
|
write-design:
|
|
description: "Agent writes the design artifact"
|
|
depends_on: [transition-to-specified]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
|
|
body:
|
|
prompt: "/design-feature {{ .vars.feature_slug }}"
|
|
auto_commit: true
|
|
auto_push: true
|
|
git_clone_url: "https://git.threesix.ai/jordan/{{ .outputs.create-project.project_id }}.git"
|
|
outputs:
|
|
- build_id: .data.task_id
|
|
|
|
wait-design:
|
|
depends_on: [write-design]
|
|
action: wait_build
|
|
build_id: "{{ .outputs.write-design.build_id }}"
|
|
max_attempts: 60
|
|
poll_interval: 5
|
|
|
|
approve-design:
|
|
description: "API approves the design artifact"
|
|
depends_on: [wait-design]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/artifacts/design/approve"
|
|
body:
|
|
comment: "Design approved by automation"
|
|
|
|
write-tasks:
|
|
description: "Agent breaks down into tasks"
|
|
depends_on: [approve-design]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
|
|
body:
|
|
prompt: "/breakdown-feature {{ .vars.feature_slug }}"
|
|
auto_commit: true
|
|
auto_push: true
|
|
git_clone_url: "https://git.threesix.ai/jordan/{{ .outputs.create-project.project_id }}.git"
|
|
outputs:
|
|
- build_id: .data.task_id
|
|
|
|
wait-tasks:
|
|
depends_on: [write-tasks]
|
|
action: wait_build
|
|
build_id: "{{ .outputs.write-tasks.build_id }}"
|
|
max_attempts: 60
|
|
poll_interval: 5
|
|
|
|
approve-tasks:
|
|
description: "API approves the tasks artifact"
|
|
depends_on: [wait-tasks]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/artifacts/tasks/approve"
|
|
body:
|
|
comment: "Tasks approved by automation"
|
|
|
|
write-qa-plan:
|
|
description: "Agent writes QA plan"
|
|
depends_on: [approve-tasks]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
|
|
body:
|
|
prompt: "/create-qa-plan {{ .vars.feature_slug }}"
|
|
auto_commit: true
|
|
auto_push: true
|
|
git_clone_url: "https://git.threesix.ai/jordan/{{ .outputs.create-project.project_id }}.git"
|
|
outputs:
|
|
- build_id: .data.task_id
|
|
|
|
wait-qa-plan:
|
|
depends_on: [write-qa-plan]
|
|
action: wait_build
|
|
build_id: "{{ .outputs.write-qa-plan.build_id }}"
|
|
max_attempts: 60
|
|
poll_interval: 5
|
|
|
|
approve-qa-plan:
|
|
description: "API approves the QA plan artifact"
|
|
depends_on: [wait-qa-plan]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/artifacts/qa_plan/approve"
|
|
body:
|
|
comment: "QA plan approved by automation"
|
|
|
|
transition-to-planned:
|
|
description: "Transition from specified to planned"
|
|
depends_on: [approve-qa-plan]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/transition"
|
|
body:
|
|
phase: "planned"
|
|
outputs:
|
|
- new_phase: .data.phase
|
|
|
|
# ============================================================
|
|
# PHASE 4: PLANNED → READY
|
|
# No new artifacts needed, just transition
|
|
# ============================================================
|
|
transition-to-ready:
|
|
description: "Transition from planned to ready"
|
|
depends_on: [transition-to-planned]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/transition"
|
|
body:
|
|
phase: "ready"
|
|
outputs:
|
|
- new_phase: .data.phase
|
|
|
|
# ============================================================
|
|
# PHASE 5: READY → IMPLEMENTATION
|
|
# Agent implements all tasks
|
|
# ============================================================
|
|
implement-feature:
|
|
description: "Agent implements all tasks for the feature"
|
|
depends_on: [transition-to-ready]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
|
|
body:
|
|
prompt: "/implement-feature {{ .vars.feature_slug }}"
|
|
auto_commit: true
|
|
auto_push: true
|
|
git_clone_url: "https://git.threesix.ai/jordan/{{ .outputs.create-project.project_id }}.git"
|
|
outputs:
|
|
- build_id: .data.task_id
|
|
|
|
wait-implement:
|
|
depends_on: [implement-feature]
|
|
action: wait_build
|
|
build_id: "{{ .outputs.implement-feature.build_id }}"
|
|
max_attempts: 120
|
|
poll_interval: 5
|
|
|
|
wait-deploy-impl:
|
|
description: "Wait for implementation to deploy"
|
|
depends_on: [wait-implement]
|
|
action: wait_pipeline
|
|
project_id: "{{ .outputs.create-project.project_id }}"
|
|
|
|
transition-to-implementation:
|
|
description: "Transition to implementation phase (marks code complete)"
|
|
depends_on: [wait-deploy-impl]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/transition"
|
|
body:
|
|
phase: "implementation"
|
|
outputs:
|
|
- new_phase: .data.phase
|
|
|
|
# ============================================================
|
|
# PHASE 6: IMPLEMENTATION → REVIEW
|
|
# Agent writes code review
|
|
# ============================================================
|
|
write-review:
|
|
description: "Agent writes code review"
|
|
depends_on: [transition-to-implementation]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
|
|
body:
|
|
prompt: "/review-feature {{ .vars.feature_slug }}"
|
|
auto_commit: true
|
|
auto_push: true
|
|
git_clone_url: "https://git.threesix.ai/jordan/{{ .outputs.create-project.project_id }}.git"
|
|
outputs:
|
|
- build_id: .data.task_id
|
|
|
|
wait-review:
|
|
depends_on: [write-review]
|
|
action: wait_build
|
|
build_id: "{{ .outputs.write-review.build_id }}"
|
|
max_attempts: 60
|
|
poll_interval: 5
|
|
|
|
approve-review:
|
|
description: "API approves the review"
|
|
depends_on: [wait-review]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/artifacts/review/approve"
|
|
body:
|
|
comment: "Review approved by automation"
|
|
|
|
transition-to-review:
|
|
description: "Transition to review phase"
|
|
depends_on: [approve-review]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/transition"
|
|
body:
|
|
phase: "review"
|
|
outputs:
|
|
- new_phase: .data.phase
|
|
|
|
# ============================================================
|
|
# PHASE 7: REVIEW → AUDIT
|
|
# Agent writes security/architecture audit
|
|
# ============================================================
|
|
write-audit:
|
|
description: "Agent writes security audit"
|
|
depends_on: [transition-to-review]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
|
|
body:
|
|
prompt: "/audit-feature {{ .vars.feature_slug }}"
|
|
auto_commit: true
|
|
auto_push: true
|
|
git_clone_url: "https://git.threesix.ai/jordan/{{ .outputs.create-project.project_id }}.git"
|
|
outputs:
|
|
- build_id: .data.task_id
|
|
|
|
wait-audit:
|
|
depends_on: [write-audit]
|
|
action: wait_build
|
|
build_id: "{{ .outputs.write-audit.build_id }}"
|
|
max_attempts: 60
|
|
poll_interval: 5
|
|
|
|
approve-audit:
|
|
description: "API approves the audit"
|
|
depends_on: [wait-audit]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/artifacts/audit/approve"
|
|
body:
|
|
comment: "Audit approved by automation"
|
|
|
|
transition-to-audit:
|
|
description: "Transition to audit phase"
|
|
depends_on: [approve-audit]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/transition"
|
|
body:
|
|
phase: "audit"
|
|
outputs:
|
|
- new_phase: .data.phase
|
|
|
|
# ============================================================
|
|
# PHASE 8: AUDIT → QA
|
|
# Agent runs QA tests
|
|
# ============================================================
|
|
run-qa:
|
|
description: "Agent runs QA plan"
|
|
depends_on: [transition-to-audit]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
|
|
body:
|
|
prompt: "/run-qa {{ .vars.feature_slug }}"
|
|
auto_commit: true
|
|
auto_push: true
|
|
git_clone_url: "https://git.threesix.ai/jordan/{{ .outputs.create-project.project_id }}.git"
|
|
outputs:
|
|
- build_id: .data.task_id
|
|
|
|
wait-qa:
|
|
depends_on: [run-qa]
|
|
action: wait_build
|
|
build_id: "{{ .outputs.run-qa.build_id }}"
|
|
max_attempts: 60
|
|
poll_interval: 5
|
|
|
|
transition-to-qa:
|
|
description: "Transition to QA phase"
|
|
depends_on: [wait-qa]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/transition"
|
|
body:
|
|
phase: "qa"
|
|
outputs:
|
|
- new_phase: .data.phase
|
|
|
|
# ============================================================
|
|
# PHASE 9: QA → MERGE
|
|
# Merge feature branch to main
|
|
# ============================================================
|
|
merge-feature:
|
|
description: "Merge feature branch to main"
|
|
depends_on: [transition-to-qa]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/merge"
|
|
body:
|
|
strategy: "squash"
|
|
outputs:
|
|
- merge_commit: .data.commit_sha
|
|
|
|
transition-to-merge:
|
|
description: "Transition to merge phase"
|
|
depends_on: [merge-feature]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/transition"
|
|
body:
|
|
phase: "merge"
|
|
outputs:
|
|
- new_phase: .data.phase
|
|
|
|
# ============================================================
|
|
# PHASE 10: MERGE → RELEASED
|
|
# Archive the feature
|
|
# ============================================================
|
|
wait-final-deploy:
|
|
description: "Wait for merged code to deploy"
|
|
depends_on: [transition-to-merge]
|
|
action: wait_pipeline
|
|
project_id: "{{ .outputs.create-project.project_id }}"
|
|
|
|
archive-feature:
|
|
description: "Archive the completed feature"
|
|
depends_on: [wait-final-deploy]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/archive"
|
|
|
|
transition-to-released:
|
|
description: "Transition to released phase"
|
|
depends_on: [archive-feature]
|
|
action: api
|
|
method: POST
|
|
endpoint: "/projects/{{ .outputs.create-project.project_id }}/sdlc/features/{{ .vars.feature_slug }}/transition"
|
|
body:
|
|
phase: "released"
|
|
outputs:
|
|
- final_phase: .data.phase
|
|
|
|
# ============================================================
|
|
# VERIFICATION
|
|
# ============================================================
|
|
verify-service-running:
|
|
description: "Verify the preferences API is running"
|
|
depends_on: [transition-to-released]
|
|
action: shell
|
|
command: |
|
|
DOMAIN="{{ .outputs.create-project.domain }}"
|
|
HEALTH=$(curl -s "https://$DOMAIN/api/preferences-api/health" | jq -r '.data.status // empty')
|
|
if [ "$HEALTH" == "healthy" ]; then
|
|
echo "Service healthy"
|
|
exit 0
|
|
else
|
|
echo "Service not healthy: $HEALTH"
|
|
exit 1
|
|
fi
|
|
|
|
verify-preferences-api:
|
|
description: "Test CRUD operations on preferences"
|
|
depends_on: [verify-service-running]
|
|
on_error: continue
|
|
action: shell
|
|
command: |
|
|
DOMAIN="{{ .outputs.create-project.domain }}"
|
|
BASE_URL="https://$DOMAIN/api/preferences-api"
|
|
USER_ID="test-user-123"
|
|
|
|
# PUT preferences
|
|
echo "Setting preferences..."
|
|
PUT_RESP=$(curl -s -X PUT "$BASE_URL/preferences/$USER_ID" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"theme":"dark","language":"en","notifications":true}')
|
|
echo "PUT response: $PUT_RESP"
|
|
|
|
# GET preferences
|
|
echo "Getting preferences..."
|
|
GET_RESP=$(curl -s "$BASE_URL/preferences/$USER_ID")
|
|
echo "GET response: $GET_RESP"
|
|
|
|
# Verify theme is dark
|
|
THEME=$(echo "$GET_RESP" | jq -r '.theme // .data.theme // empty')
|
|
if [ "$THEME" == "dark" ]; then
|
|
echo "Preferences API working correctly"
|
|
exit 0
|
|
else
|
|
echo "Expected theme=dark, got: $THEME"
|
|
exit 1
|
|
fi
|
|
|
|
verify-lifecycle-complete:
|
|
description: "Verify feature reached released phase"
|
|
depends_on: [verify-preferences-api]
|
|
action: shell
|
|
command: |
|
|
FINAL_PHASE="{{ .outputs.transition-to-released.final_phase }}"
|
|
if [ "$FINAL_PHASE" == "released" ]; then
|
|
echo "SUCCESS: Feature completed full lifecycle (draft → released)"
|
|
echo "All 10 phases traversed with explicit approvals"
|
|
exit 0
|
|
else
|
|
echo "FAIL: Expected released, got $FINAL_PHASE"
|
|
exit 1
|
|
fi
|
|
|
|
teardown:
|
|
- action: api
|
|
method: DELETE
|
|
endpoint: "/project/{{ .outputs.create-project.project_id }}"
|