- research: searches SearXNG, reads the best pages through the reader, has the model list the server's variants, then checks every Docker image and Steam app it named for real before an admin sees it. - build: first boot of the variant's images (skipping ones that need root), a draft by the model, then the draft deployed with the node-agent's BootTest like CI does; crashes, error lines and saves outside /server go back to the model, three boots at most. - worker: polls the panel's builder queue (outbound only), runs research or build in a fresh clone, streams the output as the job log, and opens the result as a pull request from the bot account. - Dockerfile.builder, a workflow publishing gbr-builder:latest, and BUILDER.md. Everything about where it runs comes from environment variables; deployment files live outside this public repo. draft now keeps its conversation in a drafter, so build can send boot failures back to the same model session. The boot-test runner comment no longer names its VM. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
123 lines
4.6 KiB
YAML
123 lines
4.6 KiB
YAML
name: Validate game templates
|
|
|
|
# Push-only on purpose: this repo is public, and a pull_request trigger would run a fork's
|
|
# version of this workflow on our self-hosted runners. PRs from branches in this repo are
|
|
# still checked through their push.
|
|
on:
|
|
push:
|
|
workflow_dispatch:
|
|
inputs:
|
|
games:
|
|
description: "Games to boot-test: comma-separated ids, or 'all'"
|
|
required: true
|
|
default: all
|
|
|
|
env:
|
|
PANEL_WEBHOOK_URL: https://api.gbrhosting.com/api/v1/webhooks/gitea
|
|
|
|
jobs:
|
|
validate:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
games: ${{ steps.changed.outputs.games }}
|
|
steps:
|
|
- name: Checkout Code
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v5
|
|
with:
|
|
go-version-file: go.mod
|
|
# Three small modules aren't worth caching, and the runners' cache server is unreachable
|
|
# from job containers: each restore/save attempt timed out after ~4.7 minutes.
|
|
cache: false
|
|
|
|
- name: Validate
|
|
run: |
|
|
go test ./...
|
|
go run ./cmd/gbrgames validate
|
|
|
|
# main: games changed since the previous main commit. Branches: games changed against main,
|
|
# so results show up before merging. Manual runs pick their own.
|
|
- name: Find changed games
|
|
id: changed
|
|
run: |
|
|
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
|
games=$(scripts/changed-games.sh "${{ inputs.games }}")
|
|
elif [ "${{ github.ref }}" = "refs/heads/main" ]; then
|
|
before="${{ github.event.before }}"
|
|
if [ -z "$before" ] || ! git cat-file -e "$before" 2>/dev/null; then
|
|
games=$(scripts/changed-games.sh all)
|
|
else
|
|
games=$(scripts/changed-games.sh "$before" "${{ github.sha }}")
|
|
fi
|
|
else
|
|
games=$(scripts/changed-games.sh "$(git merge-base origin/main HEAD)" HEAD)
|
|
fi
|
|
echo "Games to boot-test: ${games:-none}"
|
|
echo "games=$(echo $games)" >> "$GITHUB_OUTPUT"
|
|
|
|
boot-test:
|
|
needs: validate
|
|
if: needs.validate.outputs.games != ''
|
|
# A dedicated runner whose game containers can reach the internet but not private networks
|
|
runs-on: game-test
|
|
steps:
|
|
- name: Checkout Code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v5
|
|
with:
|
|
go-version-file: go.mod
|
|
# Three small modules aren't worth caching, and the runners' cache server is unreachable
|
|
# from job containers: each restore/save attempt timed out after ~4.7 minutes.
|
|
cache: false
|
|
|
|
# Secrets named in a game's test.yaml must be listed here to reach the boot test
|
|
- name: Boot test changed games
|
|
env:
|
|
DRAGONWILDS_OWNER_ID: ${{ secrets.DRAGONWILDS_OWNER_ID }}
|
|
run: scripts/boot-test.sh ${{ needs.validate.outputs.games }}
|
|
|
|
# main is the source of truth: send every template to the panel, which saves the changed ones
|
|
# (new games arrive disabled). Runs only if the changed games booted, or none changed.
|
|
publish:
|
|
needs: [validate, boot-test]
|
|
if: >-
|
|
always() && github.ref == 'refs/heads/main' && github.event_name == 'push'
|
|
&& needs.validate.result == 'success'
|
|
&& (needs.boot-test.result == 'success' || needs.boot-test.result == 'skipped')
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout Code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v5
|
|
with:
|
|
go-version-file: go.mod
|
|
# Three small modules aren't worth caching, and the runners' cache server is unreachable
|
|
# from job containers: each restore/save attempt timed out after ~4.7 minutes.
|
|
cache: false
|
|
|
|
# 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
|
|
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
|