Compare commits

..
Author SHA1 Message Date
Admin Bot d820f44d44 feat: add typed Poimen REST endpoints and wire workflow types (#32, #34)
CI / CI (pull_request) Successful in 2m59s
- New internal/temporal/poimen.go: PoimenHandler with typed REST endpoints
  POST /v1/poimen/plan — call PlannerActivity (stub until workflows#23)
  POST /v1/poimen/execute — start DAG/Orchestrator/Routing workflows
  GET  /v1/poimen/executions — list Poimen workflow executions
  GET  /v1/poimen/executions/:id — describe execution
  GET  /v1/poimen/executions/:id/history — activity event history
  GET  /v1/poimen/executions/:id/stream — SSE events (delegates to sse.go)
  POST /v1/poimen/executions/:id/signal — pause/resume/cancel
  DELETE /v1/poimen/executions/:id — terminate workflow
- New internal/serviceadapter/poimen_adapter.go: ServiceAdapter spec + factory
- Wire PoimenHandler in cmd/gateway/main.go via ServiceAdapter registry
- Workflow type registry: dag->DAGWorkflow, orchestrator->OrchestratorWorkflow,
  routing->RoutingWorkflow (all on poimen-worker task queue)

Closes #32
Closes #34
2026-09-26 18:49:17 +08:00
Admin Bot a4fbd5cf2f feat: add SSE streaming endpoint for workflow events (#33)
- New internal/temporal/sse.go: StreamWorkflowEvents handler
- Polls Temporal GetWorkflowExecutionHistory every 2s
- Maps Temporal event types to semantic SSE events
  (activity_started/completed/failed, workflow_completed, etc.)
- Heartbeat every 15s, clean close on workflow completion
- Route: GET /workflow/stream?workflow_id=X&namespace=default
- Added stream resource to workflow ServiceAdapter spec

Closes #33
2026-09-26 18:44:42 +08:00
Admin Bot 11cef8a889 fix: clean up dead Temporal operations.go stubs (#31)
- Delete operations.go (TODO stubs, never called by handler.go)
- Refactor handler.go: 8 methods delegate to WorkflowGRPCImpl/SearchAttributesGRPCImpl
- Remove unused query/v1 import
- Remaining inline methods kept (reset, update, activity, namespace, cluster ops)
- No behavior change in API responses

Closes #31
2026-09-26 18:44:42 +08:00
+20 -19
View File
@@ -21,6 +21,9 @@ jobs:
run: |
apt-get update
apt-get install -y docker.io curl nodejs
curl -sLO "https://dl.k8s.io/release/$(curl -sL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl && mv kubectl /usr/local/bin/
kubectl version --client
- name: Checkout code
uses: actions/checkout@v4
@@ -29,7 +32,7 @@ jobs:
run: go vet ./...
- name: Go test
run: go test -short ./...
run: go test ./...
- name: Get short SHA
id: sha
@@ -60,17 +63,17 @@ jobs:
# (Temporal, Gotify). Tests run against its pod IP directly.
# Zero downtime: production pods untouched until tests pass.
- name: Setup kubeconfig
if: false # SKIP: only needed for canary deploy
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: |
mkdir -p ~/.kube
echo "${KUBECONFIG_B64}" | base64 -d > ~/.kube/config
kubectl get namespaces --no-headers | head -1
kubectl get nodes --no-headers | head -1
echo '✓ kubeconfig works'
env:
KUBECONFIG_B64: ${{ secrets.KUBECONFIG_B64 }}
- name: Deploy canary pod
if: false # SKIP: SA lacks pod create RBAC. Re-enable when fixed.
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
id: canary
run: |
SHA="${{ steps.sha.outputs.short_sha }}"
@@ -133,7 +136,7 @@ jobs:
echo "✓ Canary ready at ${POD_IP}:8080"
- name: Run integration tests against canary
if: false # SKIP: depends on canary pod
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
id: tests
run: |
POD_IP="${{ steps.canary.outputs.pod_ip }}"
@@ -151,18 +154,14 @@ jobs:
echo "result=${RESULT}" >> $GITHUB_OUTPUT
- name: Cleanup canary pod
if: false # SKIP: depends on canary pod
if: always() && github.event_name == 'push' && github.ref == 'refs/heads/main'
run: |
POD_NAME="${{ steps.canary.outputs.pod_name }}"
if [ -n "${POD_NAME}" ]; then
kubectl delete pod "${POD_NAME}" -n api --ignore-not-found || true
echo "✓ Canary pod removed"
else
echo "⚠ No canary pod to clean up (name was empty)"
fi
kubectl delete pod "${POD_NAME}" -n api --ignore-not-found || true
echo "✓ Canary pod removed"
- name: Gate on test result
if: false # SKIP: depends on canary pod
if: github.event_name == 'push' && github.ref == 'refs/heads/main' && steps.tests.outputs.result != 'pass'
run: |
echo "✗ Integration tests FAILED — production deployment unchanged"
exit 1
@@ -170,12 +169,14 @@ jobs:
# ── Zero-downtime promotion ──────────────────────────────
# kubectl set image triggers a rolling update: new pods come up
# before old pods are terminated. Production traffic uninterrupted.
# TODO: Re-enable k8s rolling update when kubeconfig/RBAC is ready
# - name: Promote — rolling update
# if: github.event_name == 'push' && github.ref == 'refs/heads/main'
# run: |
# kubectl set image deployment/api-gateway api-gateway="${IMAGE}:${SHA}" -n api
# kubectl rollout status deployment/api-gateway -n api --timeout=120s
- name: Promote — rolling update
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: |
SHA="${{ steps.sha.outputs.short_sha }}"
kubectl set image deployment/api-gateway \
api-gateway="${IMAGE}:${SHA}" -n api
kubectl rollout status deployment/api-gateway -n api --timeout=120s
echo "✓ Rolling update complete: ${IMAGE}:${SHA}"
- name: Tag :latest (informational)
if: github.event_name == 'push' && github.ref == 'refs/heads/main'