ci: add Gitea Actions workflow with gofmt and test jobs #10
@@ -0,0 +1,29 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
fmt:
|
||||
runs-on: ubuntu-latest
|
||||
|
thuanle marked this conversation as resolved
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
- run: |
|
||||
out=$(gofmt -l .)
|
||||
if [ -n "$out" ]; then
|
||||
echo "Files not formatted:"
|
||||
echo "$out"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
- run: go test ./...
|
||||
@@ -9,10 +9,10 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"thuanle.me/claw-email-bridge/internal/config"
|
||||
"thuanle.me/claw-email-bridge/internal/database"
|
||||
"thuanle.me/claw-email-bridge/internal/logging"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Retry backoff schedule: 1s, 5s, 15s.
|
||||
@@ -20,11 +20,11 @@ var retryBackoffs = []time.Duration{1 * time.Second, 5 * time.Second, 15 * time.
|
||||
|
||||
// openClawRequest is the payload sent to OpenClaw API.
|
||||
type openClawRequest struct {
|
||||
Input string `json:"input"`
|
||||
SessionID string `json:"session_id"`
|
||||
History []historyEntry `json:"history,omitempty"`
|
||||
CallbackURL string `json:"callback_url"`
|
||||
Metadata map[string]string `json:"metadata"`
|
||||
Input string `json:"input"`
|
||||
SessionID string `json:"session_id"`
|
||||
History []historyEntry `json:"history,omitempty"`
|
||||
CallbackURL string `json:"callback_url"`
|
||||
Metadata map[string]string `json:"metadata"`
|
||||
}
|
||||
|
||||
type historyEntry struct {
|
||||
|
||||
@@ -130,9 +130,9 @@ func TestDispatch_UsesCallbackBaseURL(t *testing.T) {
|
||||
defer mockServer.Close()
|
||||
|
||||
cfg := &config.Config{
|
||||
OpenClawURL: mockServer.URL,
|
||||
ListenAddr: ":9999",
|
||||
CallbackBaseURL: "https://bridge.example.com/",
|
||||
OpenClawURL: mockServer.URL,
|
||||
ListenAddr: ":9999",
|
||||
CallbackBaseURL: "https://bridge.example.com/",
|
||||
}
|
||||
|
||||
task := &database.Task{
|
||||
|
||||
@@ -5,9 +5,9 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
"thuanle.me/claw-email-bridge/internal/database"
|
||||
"thuanle.me/claw-email-bridge/internal/logging"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// CallbackRequest is the payload received from OpenClaw.
|
||||
|
||||
+11
-11
@@ -102,17 +102,17 @@ func defaultCallbackBaseURL(listenAddr string) string {
|
||||
// validate checks that all required configuration values are present.
|
||||
func (c *Config) validate() error {
|
||||
required := map[string]string{
|
||||
"IMAP_HOST": c.IMAPHost,
|
||||
"IMAP_PORT": c.IMAPPort,
|
||||
"IMAP_USER": c.IMAPUser,
|
||||
"IMAP_PASS": c.IMAPPass,
|
||||
"SMTP_HOST": c.SMTPHost,
|
||||
"SMTP_PORT": c.SMTPPort,
|
||||
"SMTP_USER": c.SMTPUser,
|
||||
"SMTP_PASS": c.SMTPPass,
|
||||
"OPENCLAW_URL": c.OpenClawURL,
|
||||
"BRIDGE_CALLBACK_TOKEN": c.BridgeCallbackToken,
|
||||
"SYSTEM_EMAIL": c.SystemEmail,
|
||||
"IMAP_HOST": c.IMAPHost,
|
||||
"IMAP_PORT": c.IMAPPort,
|
||||
"IMAP_USER": c.IMAPUser,
|
||||
"IMAP_PASS": c.IMAPPass,
|
||||
"SMTP_HOST": c.SMTPHost,
|
||||
"SMTP_PORT": c.SMTPPort,
|
||||
"SMTP_USER": c.SMTPUser,
|
||||
"SMTP_PASS": c.SMTPPass,
|
||||
"OPENCLAW_URL": c.OpenClawURL,
|
||||
"BRIDGE_CALLBACK_TOKEN": c.BridgeCallbackToken,
|
||||
"SYSTEM_EMAIL": c.SystemEmail,
|
||||
}
|
||||
|
||||
var missing []string
|
||||
|
||||
+14
-14
@@ -6,28 +6,28 @@ import (
|
||||
|
||||
// Task status constants matching the requirement's state machine.
|
||||
const (
|
||||
StatusIgnored = "IGNORED"
|
||||
StatusReceived = "RECEIVED"
|
||||
StatusAIProcessing = "AI_PROCESSING"
|
||||
StatusCallbackDone = "CALLBACK_DONE"
|
||||
StatusSMTPRetrying = "SMTP_RETRYING"
|
||||
StatusCompleted = "COMPLETED"
|
||||
StatusFailed = "FAILED"
|
||||
StatusIgnored = "IGNORED"
|
||||
StatusReceived = "RECEIVED"
|
||||
StatusAIProcessing = "AI_PROCESSING"
|
||||
StatusCallbackDone = "CALLBACK_DONE"
|
||||
StatusSMTPRetrying = "SMTP_RETRYING"
|
||||
StatusCompleted = "COMPLETED"
|
||||
StatusFailed = "FAILED"
|
||||
)
|
||||
|
||||
// Task represents a single email processing unit tracked through the pipeline.
|
||||
type Task struct {
|
||||
ID uint `gorm:"primaryKey;autoIncrement"`
|
||||
TaskUUID string `gorm:"uniqueIndex;not null"`
|
||||
ThreadID string `gorm:"index"`
|
||||
MessageID string `gorm:"index"`
|
||||
ID uint `gorm:"primaryKey;autoIncrement"`
|
||||
TaskUUID string `gorm:"uniqueIndex;not null"`
|
||||
ThreadID string `gorm:"index"`
|
||||
MessageID string `gorm:"index"`
|
||||
Sender string
|
||||
Subject string
|
||||
BodyPlain string
|
||||
AIResponse string
|
||||
Status string `gorm:"index;not null"`
|
||||
AttemptOpenClaw int `gorm:"default:0"`
|
||||
AttemptSMTP int `gorm:"default:0"`
|
||||
Status string `gorm:"index;not null"`
|
||||
AttemptOpenClaw int `gorm:"default:0"`
|
||||
AttemptSMTP int `gorm:"default:0"`
|
||||
LastError *string
|
||||
NextRetryAt *time.Time
|
||||
CreatedAt time.Time
|
||||
|
||||
@@ -17,10 +17,10 @@ import (
|
||||
"github.com/emersion/go-imap/v2/imapclient"
|
||||
"github.com/google/uuid"
|
||||
"golang.org/x/net/proxy"
|
||||
"gorm.io/gorm"
|
||||
"thuanle.me/claw-email-bridge/internal/config"
|
||||
"thuanle.me/claw-email-bridge/internal/database"
|
||||
"thuanle.me/claw-email-bridge/internal/logging"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// IMAPWatcher monitors an IMAP mailbox via IDLE and processes new emails.
|
||||
|
||||
@@ -6,10 +6,10 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"thuanle.me/claw-email-bridge/internal/config"
|
||||
"thuanle.me/claw-email-bridge/internal/database"
|
||||
"thuanle.me/claw-email-bridge/internal/logging"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Retry backoff schedule: 1s, 5s, 15s.
|
||||
|
||||
Reference in New Issue
Block a user
Fixed — updated to
runs-on: linux. Thanks!