ci: publish templates to the control panel on main #1

Merged
greg merged 6 commits from feat/publish-to-panel into main 2026-10-25 05:13:27 +00:00
3 changed files with 85 additions and 1 deletions
Showing only changes of commit 5fb7736be2 - Show all commits

No files matched your search

+23
View File
@@ -7,6 +7,9 @@ on:
push:
workflow_dispatch:
env:
PANEL_WEBHOOK_URL: https://api.gbrhosting.com/api/v1/webhooks/gitea
jobs:
validate:
runs-on: ubuntu-latest
@@ -21,3 +24,23 @@ jobs:
- name: Validate
run: go run ./cmd/gbrgames validate
# main is the source of truth: send every template to the panel, which upserts them
# (new games arrive disabled). Unlike the node-agent notify, a failure here fails the run,
# because the panel would otherwise keep serving the previous templates silently.
- name: Publish to Control Panel
if: github.ref == 'refs/heads/main'
env:
PANEL_WEBHOOK_SECRET: ${{ secrets.PANEL_WEBHOOK_SECRET }}
run: |
if [ -z "$PANEL_WEBHOOK_SECRET" ]; then
echo "::error::PANEL_WEBHOOK_SECRET is not set; templates were not published"
exit 1
fi
go run ./cmd/gbrgames export -repo "${{ github.repository }}" -commit "${{ github.sha }}" -out payload.json
curl -sS --fail-with-body --max-time 30 --retry 3 --retry-delay 10 \
-X POST "${{ env.PANEL_WEBHOOK_URL }}" \
-H "Content-Type: application/json" \
-H "X-Gitea-Token: $PANEL_WEBHOOK_SECRET" \
-H "X-GBR-Event: games_published" \
--data-binary @payload.json
+58
View File
@@ -0,0 +1,58 @@
package main
import (
"encoding/json"
"errors"
"flag"
"fmt"
"os"
"path/filepath"
)
// runExport writes the games_published webhook payload: every game.yaml as JSON, ready for the panel.
func runExport(args []string) error {
fs := flag.NewFlagSet("export", flag.ExitOnError)
gamesDir := fs.String("games", "games", "directory holding one folder per game")
repo := fs.String("repo", "", "repository full name, e.g. gbreed-public/gbr-games")
commit := fs.String("commit", "", "commit SHA the templates come from")
out := fs.String("out", "", "file to write (default stdout)")
fs.Parse(args)
entries, err := os.ReadDir(*gamesDir)
if err != nil {
return err
}
games := []any{}
for _, e := range entries {
if !e.IsDir() {
continue
}
raw, err := os.ReadFile(filepath.Join(*gamesDir, e.Name(), "game.yaml"))
if err != nil {
return fmt.Errorf("%s: %w", e.Name(), err)
}
game, err := loadYAML(raw)
if err != nil {
return fmt.Errorf("%s/game.yaml: %w", e.Name(), err)
}
games = append(games, game)
}
if len(games) == 0 {
return errors.New("no games to export")
}
payload := map[string]any{
"repository": map[string]any{"full_name": *repo},
"after": *commit,
"games": games,
}
b, err := json.Marshal(payload)
if err != nil {
return err
}
if *out == "" {
_, err = os.Stdout.Write(b)
return err
}
return os.WriteFile(*out, b, 0o644)
}
+4 -1
View File
@@ -2,6 +2,7 @@
//
// go run ./cmd/gbrgames validate # check every games/<id>/game.yaml (+ test.yaml)
// go run ./cmd/gbrgames import export.json # write games/<id>/ from GET /api/v1/admin/games
// go run ./cmd/gbrgames export -out p.json # build the games_published payload CI sends to the panel
package main
import (
@@ -19,6 +20,8 @@ func main() {
err = runValidate(os.Args[2:])
case "import":
err = runImport(os.Args[2:])
case "export":
err = runExport(os.Args[2:])
default:
usage()
}
@@ -29,6 +32,6 @@ func main() {
}
func usage() {
fmt.Fprintln(os.Stderr, "usage: gbrgames validate [-games DIR] | import [-games DIR] [-all] EXPORT.json")
fmt.Fprintln(os.Stderr, "usage: gbrgames validate [-games DIR] | import [-games DIR] [-all] EXPORT.json | export [-repo R] [-commit SHA] [-out FILE]")
os.Exit(2)
}