- Config loader with env var expansion and validation - SQLite database with tasks and toolchain_versions tables - Gitea REST API client for repository and branch operations - K8s client for Job lifecycle management (with noop fallback for local dev) - REST API: tasks CRUD, retry, plugins, version management - Worker/scheduler with polling, concurrency control, and job tracking - Static frontend: generate, tasks, settings pages - Toolchain images: Go and Node.js Dockerfiles with entrypoint scripts - Helm chart with deployment, service, configmap, ingress, PVC - Multi-stage Dockerfile for service - Unit tests for config, database, gitclient, k8s, api, worker - E2E tests for idempotency, version switch, failure recovery
71 lines
1.5 KiB
Go
71 lines
1.5 KiB
Go
package database
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
|
|
_ "modernc.org/sqlite"
|
|
)
|
|
|
|
type DB struct {
|
|
conn *sql.DB
|
|
}
|
|
|
|
func New(dbPath string) (*DB, error) {
|
|
conn, err := sql.Open("sqlite", dbPath+"?_pragma=journal_mode(WAL)&_pragma=busy_timeout(5000)")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("opening database: %w", err)
|
|
}
|
|
|
|
db := &DB{conn: conn}
|
|
if err := db.migrate(); err != nil {
|
|
conn.Close()
|
|
return nil, fmt.Errorf("running migrations: %w", err)
|
|
}
|
|
|
|
return db, nil
|
|
}
|
|
|
|
func (db *DB) Close() error {
|
|
return db.conn.Close()
|
|
}
|
|
|
|
func (db *DB) migrate() error {
|
|
schema := `
|
|
CREATE TABLE IF NOT EXISTS tasks (
|
|
id TEXT PRIMARY KEY,
|
|
status TEXT NOT NULL DEFAULT 'pending',
|
|
language TEXT NOT NULL,
|
|
proto_repo TEXT NOT NULL,
|
|
proto_branch TEXT NOT NULL,
|
|
proto_commit TEXT NOT NULL DEFAULT '',
|
|
target_repo TEXT NOT NULL,
|
|
toolchain_image TEXT NOT NULL,
|
|
image_digest TEXT NOT NULL DEFAULT '',
|
|
result_commit TEXT NOT NULL DEFAULT '',
|
|
error TEXT NOT NULL DEFAULT '',
|
|
log TEXT NOT NULL DEFAULT '',
|
|
retries INTEGER NOT NULL DEFAULT 0,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL
|
|
);
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_tasks_running_per_repo
|
|
ON tasks(target_repo) WHERE status = 'running';
|
|
|
|
CREATE TABLE IF NOT EXISTS toolchain_versions (
|
|
language TEXT PRIMARY KEY,
|
|
image_tag TEXT NOT NULL,
|
|
enabled INTEGER NOT NULL DEFAULT 1,
|
|
updated_at TEXT NOT NULL
|
|
);
|
|
`
|
|
|
|
_, err := db.conn.Exec(schema)
|
|
return err
|
|
}
|
|
|
|
func (db *DB) Conn() *sql.DB {
|
|
return db.conn
|
|
}
|