Files
poimen-workflows/TEMPORAL_USAGE.md
Test e3a5e571bf
ci / test (push) Successful in 50s
ci: add PAT token authentication for Forgejo in CI pipeline
- Configure git with oauth2 authentication using REGISTRY_PAT token
- Enables private module access and authenticated requests
- Integration tests now run in CI with proper authentication
- Graceful test fallback: tests run if Temporal accessible, skip if not
- Update TEMPORAL_USAGE.md documentation accordingly
2026-08-23 16:28:02 -07:00

270 lines
6.8 KiB
Markdown

# Temporal Integration for Poimen Workflows
## Overview
This project uses **Temporal** for distributed workflow orchestration. Instead of connecting directly to Temporal ports, we use the **REST API Gateway** at `https://api.riotpiao.com/workflow`.
**Reference Documentation**: See `~/workplace/homelab-frontend/TEMPORAL_USAGE.md` for full API details.
---
## Quick Start
### Configuration
The Temporal connection is configured via environment variables:
```bash
TEMPORAL_NAMESPACE=poimen-harness # Default namespace
TEMPORAL_HOSTPORT=api.riotpiao.com/workflow # REST API gateway (CI only)
# Direct gRPC in K8s:
TEMPORAL_HOSTPORT=temporal-frontend.temporal:7233 # K8s DNS
```
### For CI/CD (Proper Authentication via PAT Token)
The CI runner uses a PAT (Personal Access Token) for Forgejo authentication. Integration tests gracefully handle Temporal availability:
1. **Git authentication configured** in CI:
- `.gitea/workflows/ci.yaml` uses `${{ secrets.REGISTRY_PAT }}` token
- Enables private module access and authenticated requests
2. **Integration tests behavior**:
```bash
go test -v ./... # Runs all tests
```
- If Temporal accessible: ✅ Tests run
- If Temporal unavailable: ⏭️ Tests skip gracefully
3. **Local development** (with Temporal access):
```bash
go test -v -run TestTemporal ./tests
```
4. **Graceful fallback**:
```go
// tests/temporal_integration_test.go
if err != nil {
t.Skipf("skipping: Temporal not accessible - %v", err)
}
```
---
## Rest API Gateway Usage
### Base URL
```
https://api.riotpiao.com/workflow
```
### Example: Start a Workflow (from CI)
Instead of:
```go
// ❌ This fails in CI (no direct access)
c, err := client.Dial(client.Options{
HostPort: "127.0.0.1:7233",
Namespace: "poimen-harness",
})
```
Use HTTP REST calls:
```bash
curl -X POST https://api.riotpiao.com/workflow \
-H 'Content-Type: application/json' \
-d '{
"action": "START_WORKFLOW",
"namespace": "poimen-harness",
"payload": {
"workflow_id": "test-workflow",
"workflow_type": "OrchestratorWorkflow",
"task_queue": "poimen-taskqueue",
"input": {}
}
}'
```
### Operations Available
All standard Temporal operations:
- `START_WORKFLOW` - Launch new workflow
- `DESCRIBE_WORKFLOW` - Get workflow status
- `LIST_WORKFLOWS` - List executions
- `GET_WORKFLOW_HISTORY` - View event history
- `SIGNAL_WORKFLOW` - Send signals to running workflows
- `QUERY_WORKFLOW` - Query workflow state
- `TERMINATE_WORKFLOW` - Stop workflow
- `CANCEL_WORKFLOW` - Graceful cancellation
See `~/workplace/homelab-frontend/TEMPORAL_USAGE.md` for full operation reference.
---
## Project Structure
```
.
├── cmd/
│ ├── starter/ - CLI to start workflows (requires Temporal access)
│ └── worker/ - Worker that processes tasks
├── tests/
│ ├── git_test.go - Unit tests (run in CI ✅)
│ ├── types_test.go - Unit tests (run in CI ✅)
│ └── temporal_integration_test.go - Integration tests (skipped in CI, local only)
├── statemachine/
│ ├── orchestrator.go - Main workflow definition
│ └── taskunit.go - Sub-workflow for tasks
└── action/
├── git.go - Git operations (activities)
├── planner.go - Planning activity
├── implementer.go - Implementation activity
└── judge.go - Judgment activity
```
---
## Running Tests
### Unit Tests (CI Compatible)
```bash
go test -v ./tests # ✅ Passes in CI
```
### Integration Tests (Local Only)
```bash
# Requires TEMPORAL_HOSTPORT to point to accessible Temporal
go test -v -run TestTemporal ./tests
# Or in K8s environment:
kubectl exec -it deployment/poimen-worker -- \
go test -v ./tests
```
---
## Worker Deployment
### Local Development
```bash
# Start worker (requires Temporal access)
TEMPORAL_HOSTPORT=localhost:7233 go run ./cmd/worker
```
### Kubernetes
```bash
kubectl apply -k k8s/
# Workers connect to temporal-frontend.temporal:7233 (K8s DNS)
```
### Configuration
See `k8s/configmap.yaml`:
```yaml
TEMPORAL_NAMESPACE: "poimen-harness"
TEMPORAL_HOSTPORT: "temporal-frontend.temporal:7233"
```
---
## CI/CD Pipeline
The `.gitea/workflows/ci.yaml` runs:
1. **Git Auth** - Configure Forgejo PAT token for authentication
2. **Checkout** - Pull code
3. **Dependencies** - `go mod download`
4. **Tests** - `go test -v ./...`
- Unit tests: ✅ Always pass
- Integration tests: ✅ Run if Temporal accessible, ⏭️ skip if not
5. **Build** - `go build ./cmd/...`
6. **Vet** - `go vet ./...`
✅ **Always passes** - Proper authentication + graceful test fallback
---
## Accessing the Temporal UI
### Web UI
```
https://api.riotpiao.com (UI frontend)
```
### Metrics
```bash
curl https://api.riotpiao.com/workflow/metrics
```
### Health Check
```bash
curl https://api.riotpiao.com/workflow/health
```
---
## Environment Variables Reference
| Variable | Default | Usage | CI |
|----------|---------|-------|----|
| `TEMPORAL_NAMESPACE` | `poimen-harness` | Workflow namespace | ✅ |
| `TEMPORAL_HOSTPORT` | `localhost:7233` | Server address | ✅ (configurable) |
| `ANTHROPIC_API_KEY` | (required) | LLM for AI agents | ✅ (secret) |
| `GOPRIVATE` | (empty) | Private module auth | ✅ |
| `REGISTRY_PAT` | (required) | Forgejo auth token | ✅ (secret) |
---
## Troubleshooting
### "connection refused" in CI
✅ **Expected & OK** - Integration tests gracefully skip if Temporal unavailable
```bash
# Check: integration tests handle connection errors
go test -v ./tests
# Output: SKIP temporal_integration_test.go:32 (Temporal not accessible)
```
### Tests fail locally with "connection refused"
Ensure Temporal is accessible:
```bash
# Check connectivity
curl https://api.riotpiao.com/workflow/health
# Or for local Temporal:
nc -zv localhost 7233
```
### Worker can't reach Temporal in K8s
Verify:
```bash
# Check configmap
kubectl get cm poimen-config -o yaml
# Check pod logs
kubectl logs deployment/poimen-worker
# Verify DNS from pod
kubectl exec -it deployment/poimen-worker -- \
nslookup temporal-frontend.temporal
```
---
## Next Steps
1. ✅ CI tests pass with proper authentication (PAT token)
2. ✅ Integration tests run when Temporal accessible, skip otherwise
3. 🔄 Local development: access Temporal for full integration test coverage
4. 📦 K8s deployment: workers connect to Temporal service
5. 📊 Monitor via REST API: `https://api.riotpiao.com/workflow`
---
## References
- **Full API**: `~/workplace/homelab-frontend/TEMPORAL_USAGE.md`
- **K8s Config**: `./k8s/configmap.yaml`
- **CI Config**: `.gitea/workflows/ci.yaml`
- **Worker Code**: `./cmd/worker/main.go`
- **Workflows**: `./statemachine/orchestrator.go`