Fix UUID cast in task creation, add kind test manifests

- Fix parent_task_id NULLIF cast to UUID type in INSERT query
- Fix itoa helper to use strconv.Itoa
- Handle AddReaction errors gracefully in webhook handler
- Add hack/kind/ manifests for local testing with kind cluster
This commit is contained in:
2026-06-10 22:22:57 +10:00
parent 49d514c050
commit c13b2ae999
8 changed files with 252 additions and 3 deletions
+61
View File
@@ -0,0 +1,61 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: forgebot-api
namespace: forgebot
spec:
replicas: 1
selector:
matchLabels:
app: forgebot-api
template:
metadata:
labels:
app: forgebot-api
spec:
containers:
- name: api
image: forgebot-api:dev
imagePullPolicy: Never
ports:
- containerPort: 8000
env:
- name: LISTEN_ADDR
value: ":8000"
- name: DBHOST
value: postgres.forgebot.svc.cluster.local
- name: DBPORT
value: "5432"
- name: DBUSER
value: forgebot
- name: DBPASS
value: forgebot
- name: DBNAME
value: forgebot
- name: DBSSL
value: disable
- name: WEBHOOK_SECRET
value: ""
- name: GITEA_URL
value: "https://git.unkin.net"
- name: GITEA_TOKEN
value: ""
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: forgebot-api
namespace: forgebot
spec:
selector:
app: forgebot-api
ports:
- port: 8000
targetPort: 8000
+5
View File
@@ -0,0 +1,5 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: forgebot
@@ -0,0 +1,35 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: forgebot-operator
namespace: forgebot
spec:
replicas: 1
selector:
matchLabels:
app: forgebot-operator
template:
metadata:
labels:
app: forgebot-operator
spec:
serviceAccountName: forgebot-operator
containers:
- name: operator
image: forgebot-operator:dev
imagePullPolicy: Never
args:
- --metrics-bind-address=:8080
- --health-probe-bind-address=:8081
ports:
- containerPort: 8080
name: metrics
- containerPort: 8081
name: health
readinessProbe:
httpGet:
path: /readyz
port: 8081
initialDelaySeconds: 5
periodSeconds: 5
+38
View File
@@ -0,0 +1,38 @@
---
apiVersion: v1
kind: Pod
metadata:
name: postgres
namespace: forgebot
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:17-alpine
env:
- name: POSTGRES_USER
value: forgebot
- name: POSTGRES_PASSWORD
value: forgebot
- name: POSTGRES_DB
value: forgebot
ports:
- containerPort: 5432
readinessProbe:
exec:
command: ["pg_isready", "-U", "forgebot"]
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: postgres
namespace: forgebot
spec:
selector:
app: postgres
ports:
- port: 5432
targetPort: 5432
+40
View File
@@ -0,0 +1,40 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: forgebot-operator
namespace: forgebot
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: forgebot-operator
rules:
- apiGroups: ["forgebot.unkin.net"]
resources: ["*"]
verbs: ["*"]
- apiGroups: ["forgebot.unkin.net"]
resources: ["*/status"]
verbs: ["get", "update", "patch"]
- apiGroups: ["batch"]
resources: ["jobs"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["pods", "configmaps", "secrets", "events", "serviceaccounts"]
verbs: ["get", "list", "watch"]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: forgebot-operator
subjects:
- kind: ServiceAccount
name: forgebot-operator
namespace: forgebot
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: forgebot-operator
+67
View File
@@ -0,0 +1,67 @@
---
apiVersion: v1
kind: Secret
metadata:
name: litellm-api-key
namespace: forgebot
stringData:
api-key: "sk-test-dummy-key"
---
apiVersion: v1
kind: Secret
metadata:
name: forgebot-api-token
namespace: forgebot
stringData:
token: "test-token"
---
apiVersion: forgebot.unkin.net/v1alpha1
kind: AgentPool
metadata:
name: test-pool
namespace: forgebot
spec:
model: claude-sonnet-4-20250514
endpoint: https://litellm.k8s.syd1.au.unkin.net
maxConcurrent: 2
image: busybox:latest
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
credentialSecretRef:
name: litellm-api-key
serviceAccountName: default
---
apiVersion: forgebot.unkin.net/v1alpha1
kind: ProviderQueue
metadata:
name: gitea-queue
namespace: forgebot
spec:
provider: gitea
endpoint: http://forgebot-api.forgebot.svc.cluster.local:8000/api/v1
pollInterval: "10s"
credentialSecretRef:
name: forgebot-api-token
---
apiVersion: forgebot.unkin.net/v1alpha1
kind: RepositoryBinding
metadata:
name: test-repo
namespace: forgebot
spec:
repository: unkin/test-repo
providerQueueRef: gitea-queue
agentPoolRef: test-pool
allowedUsers:
- unkinben
allowedCommands:
- plan
- review
- implement
- test
- fix
+3 -1
View File
@@ -84,7 +84,9 @@ func (h *WebhookHandler) HandleGitea(w http.ResponseWriter, r *http.Request) {
"author", event.Author,
)
h.provider.AddReaction(parts[0], parts[1], event.CommentID, "eyes")
if err := h.provider.AddReaction(parts[0], parts[1], event.CommentID, "eyes"); err != nil {
slog.Warn("failed to add reaction", "error", err)
}
}
w.WriteHeader(http.StatusAccepted)
+3 -2
View File
@@ -2,6 +2,7 @@ package database
import (
"context"
"strconv"
"time"
"github.com/jackc/pgx/v5"
@@ -35,7 +36,7 @@ func (db *DB) CreateTask(ctx context.Context, req models.CreateTaskRequest) (*mo
issue_number, pr_number, comment_id, body, author,
extra_tools, pool_ref
) VALUES (
NULLIF($1, ''), $2, $3, $4, $5,
NULLIF($1, '')::uuid, $2, $3, $4, $5,
$6, $7, $8, $9, $10,
$11, $12
) RETURNING id, created_at`,
@@ -173,5 +174,5 @@ func scanTasks(rows pgx.Rows) ([]models.Task, error) {
}
func itoa(i int) string {
return string(rune('0'+i)) + ""
return strconv.Itoa(i)
}