synckit

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 10, 2026 License: MIT Imports: 14 Imported by: 0

README

synckit

Shared deploy/update spine for sync servers — Discord bot (/verify, /updateserver), a declarative deploy-agent, Discord OAuth, generic Postgres plumbing, and a stable HTTP contract. Consumed by EggLedger and EggIncognito sync servers.

Consume it (Go)

import (
	"log"
	"os"

	synckit "github.com/DavidArthurCole/synckit"
	"github.com/DavidArthurCole/synckit/contract"
)

func main() {
	err := synckit.Run(synckit.AppProfile{
		Name: "EggLedger",
		RepoURL: "https://github.com/DavidArthurCole/EggLedgerSyncServer",
		Discord: synckit.DiscordConfig{
			Token: os.Getenv("DISCORD_BOT_TOKEN"),
			AppID: os.Getenv("DISCORD_CLIENT_ID"),
			GuildID: os.Getenv("DISCORD_GUILD_ID"),
		},
		Build: contract.VerifyInfo{SHA256: BuildSHA256, Version: BuildVersion, Date: BuildDate},
		DeployAgent: synckit.AgentRef{
			URL: os.Getenv("DEPLOY_AGENT_URL"),
			Secret: os.Getenv("DEPLOY_AGENT_SECRET"),
		},
	})
	if err != nil {
		log.Fatal(err)
	}
}

Build-info vars (BuildSHA256/BuildVersion/BuildDate) are injected by the consumer via -ldflags "-X main.BuildVersion=...".

AppProfile fields: Name, RepoURL, Discord, Build, DeployAgent, DB (nil = run DB-free), Commands (app-specific slash commands), Events (inbound hooks), Mux (bring your own — app routes; nil = synckit creates one).

Deploy-agent

A host-side binary (needs docker + git) that runs a declarative pipeline on POST. Define deploy-agent.yaml:

repo: /home/david/repos/EggLedgerSyncServer
steps:
  - git-pull
  - docker-build: { tag: ledgersyncserver:latest }
  - container-recreate: { name: ledgersync }
  - webhook: { url_env: PORTAINER_WEBHOOK_URL }

Step types: git-pull, docker-build, container-recreate, webhook, shell. git-pull records from/to short hashes and short-circuits on "Already up to date." shell runs arbitrary commands — yaml is trusted operator input. A consumer parses this with agent.ParseConfig, builds an agent.Executor, and serves it via agent.NewHandler(secret, exec.Run).

Frame host setup

The sync server runs in a container; the deploy-agent runs on the host under systemd (it needs the docker socket + git). To register it:

cd deploy
cp install.sh.tmpl install.sh   # edit the vars at the top
bash install.sh

This writes /etc/synckit/<app>.env, installs synckit-agent-<app>.service, runs daemon-reload, and enables + starts it. The bot's /updateserver then POSTs to the agent, which pulls/builds/recreates and pings the Portainer webhook.

HTTP contract

The contract package holds frozen JSON types shared with non-Go consumers (the .NET app, the device farm): DeployResponse, VerifyInfo, NewVersionEvent. The device farm POSTs NewVersionEvent to /events/new-version (bearer-authed via EventHandlers.EventSecret) when it detects a new game version; the consumer's Events.NewVersion handler then drives generate-and-deploy.

Packages

Package Purpose
contract Frozen HTTP JSON types.
bot Discord bot: verify, updateserver, command dispatch, embeds.
agent Deploy-agent: typed-step pipeline, yaml config, HTTP handler.
auth Discord OAuth helpers + bearer-token middleware.
db Generic Postgres init + migration runner (no app schema).
(root) synckit AppProfile, Run, NewVersionHandler.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewVersionHandler

func NewVersionHandler(secret string, fn func(contract.NewVersionEvent) error) http.Handler

NewVersionHandler is the bearer-authed inbound endpoint the device farm POSTs to when it detects a new game version.

func Run

func Run(p AppProfile) error

Run stands up the sync server from a profile: optional DB, bot, event routes. It blocks until SIGINT/SIGTERM, then cleans up.

Types

type AgentRef

type AgentRef struct {
	URL    string
	Secret string
}

AgentRef points the bot at a deploy-agent.

type AppProfile

type AppProfile struct {
	Name        string
	Discord     DiscordConfig
	Build       contract.VerifyInfo
	DeployAgent AgentRef
	DB          *DBConfig
	Commands    []bot.Command
	Events      EventHandlers
	Mux         *http.ServeMux
	RepoURL     string
}

AppProfile is the single struct a Go consumer fills to stand up a sync server.

type DBConfig

type DBConfig struct {
	ConnStr       string
	MigrationsDir string
}

DBConfig configures optional Postgres. Nil profile.DB = run DB-free.

type DiscordConfig

type DiscordConfig struct {
	Token             string
	AppID             string
	GuildID           string
	OAuthClientID     string
	OAuthClientSecret string
	OAuthRedirectURL  string
}

DiscordConfig carries gateway + OAuth identifiers.

type EventHandlers

type EventHandlers struct {
	NewVersion  func(contract.NewVersionEvent) error
	EventSecret string
}

EventHandlers carries optional inbound HTTP event hooks.

Directories

Path Synopsis
Package contract holds the stable JSON types shared across the synckit HTTP surface — between the bot, the deploy-agent, and any non-Go consumer (the .NET app, the device farm).
Package contract holds the stable JSON types shared across the synckit HTTP surface — between the bot, the deploy-agent, and any non-Go consumer (the .NET app, the device farm).
Package db provides generic Postgres plumbing — connection + migration running — with no app-specific schema.
Package db provides generic Postgres plumbing — connection + migration running — with no app-specific schema.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL