cmd/api/main.go: registerWebUI serves a built web/ as a single-page app - Echo's static middleware in HTML5 mode, with a Skipper that exempts /api/*, /hello, /docs, /schemas/* and openapi.json/.yaml so it can never shadow a real API route. It reads WEB_DIST_DIR (default /frontend, where the Dockerfile puts it) and no-ops if that directory doesn't exist, so `go run ./cmd/api` and CI stay Node-free and API-only; only the Docker image actually turns the web UI on. Dockerfile: new node:22-alpine stage builds web/, copied into the final image at /frontend alongside the existing Go-built binary. Added .dockerignore (web/node_modules, web/dist, web/.angular, .git) now that a second language's tooling is in the build context. Looked at how your other Gitea projects (MusicServer et al.) structure this, since I can't exercise Gitea Actions itself from here: MusicServer's own Dockerfile already does "copy a prebuilt frontend into the Go image, serve it from Go" (there, from a separately-published frontend image) - registerWebUI does the same thing in spirit, just within one image rather than two, since this UI isn't meant to be published separately. release.yml: - build-gui now also cross-compiles the Fyne GUI for windows/amd64 via mingw-w64, alongside the existing linux/amd64. Verified for real, not just written: installed mingw-w64 locally and cross-built cmd/gui, first plain (got a working PE32+ console exe), then with -ldflags "-H=windowsgui" (got the GUI-subsystem exe actually wanted, no console window). macOS isn't attempted - cgo has no equivalent cross-toolchain for Darwin and there's no registered macOS runner here. - new build-docker job pushes the API image (now carrying the web build) to gitea.sanplex.xyz/sansan/completed, tagged with the version and latest. - replaced the hand-rolled curl+jq Gitea-release creation with akkuman/gitea-release-action, and artifact upload with the Gitea generic package registry - both are what your other projects (HanjaKanaMun, MusicPlayer) actually use, found by reading their workflows rather than guessing. Same for the registry host, owner, and secrets.TOKEN name (previously secrets.GITHUB_TOKEN, which nothing else here uses). ci.yml: new docker job builds the same image on every push to main/develop (push: false) as a health check, matching MusicServer's build-vs-release split. Verified for real wherever I could: a full `docker build` of the new Dockerfile, then running that image against a real Postgres container and hitting it with curl - / serves the actual built Angular index.html, /games (a client-side route) correctly falls back to it, /api/games and /hello are untouched (still return real API responses, not shadowed by the static handler), and register+list-games works end to end through the container. Also ran it the documented way, `docker compose up --build`, with the same results. Separately confirmed the Windows Fyne cross-build produces a real, correctly-subsystemed .exe. What I could not run from here is Gitea Actions itself - the workflow YAML is written to match your other projects' established, working conventions, but its first real execution on your Gitea instance is still the first real test of it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
218 lines
6.5 KiB
YAML
218 lines
6.5 KiB
YAML
#
|
|
# .gitea/workflows/release.yml
|
|
#
|
|
# On a version tag (e.g. v1.2.3): builds every client, pushes the API's
|
|
# Docker image, uploads all build artifacts to the Gitea generic package
|
|
# registry, and creates a Gitea release with those same files attached.
|
|
#
|
|
name: Release
|
|
|
|
on:
|
|
push:
|
|
tags: ["v*.*.*"]
|
|
|
|
env:
|
|
PROJECT_NAME: Completed
|
|
REGISTRY: gitea.sanplex.xyz
|
|
REGISTRY_OWNER: sansan
|
|
|
|
jobs:
|
|
# cmd/api and cmd/tui are pure Go (no cgo), so they cross-compile cleanly
|
|
# from one Linux runner for every OS/arch below.
|
|
build-go:
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
matrix:
|
|
include:
|
|
- goos: linux
|
|
goarch: amd64
|
|
- goos: linux
|
|
goarch: arm64
|
|
- goos: darwin
|
|
goarch: amd64
|
|
- goos: darwin
|
|
goarch: arm64
|
|
- goos: windows
|
|
goarch: amd64
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: actions/setup-go@v5
|
|
with:
|
|
go-version-file: go.mod
|
|
|
|
- name: Build api and tui
|
|
env:
|
|
GOOS: ${{ matrix.goos }}
|
|
GOARCH: ${{ matrix.goarch }}
|
|
CGO_ENABLED: "0"
|
|
run: |
|
|
mkdir -p dist
|
|
ext=""
|
|
if [ "${{ matrix.goos }}" = "windows" ]; then ext=".exe"; fi
|
|
go build -o "dist/completed-api${ext}" ./cmd/api
|
|
go build -o "dist/completed-tui${ext}" ./cmd/tui
|
|
|
|
- name: Archive
|
|
run: |
|
|
cd dist
|
|
base="${PROJECT_NAME}_${{ matrix.goos }}_${{ matrix.goarch }}"
|
|
if [ "${{ matrix.goos }}" = "windows" ]; then
|
|
zip "../${base}.zip" completed-api.exe completed-tui.exe
|
|
else
|
|
tar czf "../${base}.tar.gz" completed-api completed-tui
|
|
fi
|
|
|
|
- uses: actions/upload-artifact@v4
|
|
with:
|
|
name: ${{ env.PROJECT_NAME }}_${{ matrix.goos }}_${{ matrix.goarch }}
|
|
path: ${{ env.PROJECT_NAME }}_${{ matrix.goos }}_${{ matrix.goarch }}.*
|
|
retention-days: 7
|
|
|
|
# cmd/gui (Fyne) uses cgo, so unlike build-go above it can't just cross-
|
|
# compile with CGO_ENABLED=0. Linux is native to this runner; Windows
|
|
# cross-compiles cleanly with the mingw-w64 toolchain (verified locally:
|
|
# a real PE32+ GUI-subsystem .exe, linking Fyne's OpenGL/glfw backend,
|
|
# with no changes needed beyond CC and the usual GOOS/GOARCH). macOS
|
|
# isn't included - cross-compiling cgo to Darwin from Linux has no
|
|
# equivalent well-supported toolchain, so that would need an actual
|
|
# macOS runner, which isn't registered for this repo.
|
|
build-gui:
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
matrix:
|
|
include:
|
|
- goos: linux
|
|
goarch: amd64
|
|
packages: libgl1-mesa-dev xorg-dev
|
|
- goos: windows
|
|
goarch: amd64
|
|
packages: gcc-mingw-w64-x86-64
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: actions/setup-go@v5
|
|
with:
|
|
go-version-file: go.mod
|
|
|
|
- name: Install system dependencies
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y ${{ matrix.packages }}
|
|
|
|
- name: Build gui
|
|
env:
|
|
GOOS: ${{ matrix.goos }}
|
|
GOARCH: ${{ matrix.goarch }}
|
|
CGO_ENABLED: "1"
|
|
run: |
|
|
mkdir -p dist
|
|
if [ "${{ matrix.goos }}" = "windows" ]; then
|
|
CC=x86_64-w64-mingw32-gcc go build -ldflags "-H=windowsgui" -o dist/completed-gui.exe ./cmd/gui
|
|
else
|
|
go build -o dist/completed-gui ./cmd/gui
|
|
fi
|
|
|
|
- name: Archive
|
|
run: |
|
|
cd dist
|
|
base="../${PROJECT_NAME}-gui_${{ matrix.goos }}_${{ matrix.goarch }}"
|
|
if [ "${{ matrix.goos }}" = "windows" ]; then
|
|
zip "${base}.zip" completed-gui.exe
|
|
else
|
|
tar czf "${base}.tar.gz" completed-gui
|
|
fi
|
|
|
|
- uses: actions/upload-artifact@v4
|
|
with:
|
|
name: ${{ env.PROJECT_NAME }}-gui_${{ matrix.goos }}_${{ matrix.goarch }}
|
|
path: ${{ env.PROJECT_NAME }}-gui_${{ matrix.goos }}_${{ matrix.goarch }}.*
|
|
retention-days: 7
|
|
|
|
build-web:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "22"
|
|
cache: npm
|
|
cache-dependency-path: web/package-lock.json
|
|
|
|
- name: Build
|
|
working-directory: web
|
|
run: |
|
|
npm ci
|
|
npm run build
|
|
|
|
- name: Archive
|
|
run: tar czf ${PROJECT_NAME}-web_dist.tar.gz -C web/dist/web/browser .
|
|
|
|
- uses: actions/upload-artifact@v4
|
|
with:
|
|
name: ${{ env.PROJECT_NAME }}-web_dist
|
|
path: ${{ env.PROJECT_NAME }}-web_dist.tar.gz
|
|
retention-days: 7
|
|
|
|
# Builds and pushes the API's image, which embeds the web build as its
|
|
# static UI (see the Dockerfile and cmd/api/main.go's registerWebUI).
|
|
build-docker:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
with:
|
|
config-inline: |
|
|
[registry."${{ env.REGISTRY }}/${{ env.REGISTRY_OWNER }}"]
|
|
http = true
|
|
insecure = true
|
|
|
|
- name: Login to Gitea
|
|
uses: docker/login-action@v2
|
|
with:
|
|
registry: ${{ env.REGISTRY }}
|
|
username: ${{ github.repository_owner }}
|
|
password: ${{ secrets.TOKEN }}
|
|
|
|
- name: Build and push
|
|
uses: docker/build-push-action@v5
|
|
with:
|
|
context: .
|
|
file: ./Dockerfile
|
|
push: true
|
|
tags: |
|
|
${{ env.REGISTRY }}/${{ env.REGISTRY_OWNER }}/completed:${{ gitea.ref_name }}
|
|
${{ env.REGISTRY }}/${{ env.REGISTRY_OWNER }}/completed:latest
|
|
|
|
release:
|
|
needs: [build-go, build-gui, build-web]
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/download-artifact@v4
|
|
with:
|
|
path: artifacts
|
|
merge-multiple: true
|
|
|
|
- name: Upload to the Gitea generic package registry
|
|
env:
|
|
VERSION: ${{ gitea.ref_name }}
|
|
run: |
|
|
for f in artifacts/*; do
|
|
name="$(basename "$f")"
|
|
echo "Uploading $name"
|
|
curl --fail --user "${{ github.repository_owner }}:${{ secrets.TOKEN }}" \
|
|
--upload-file "$f" \
|
|
"https://${{ env.REGISTRY }}/api/packages/${{ env.REGISTRY_OWNER }}/generic/${{ env.PROJECT_NAME }}/${VERSION}/${name}"
|
|
done
|
|
|
|
- name: Create release
|
|
uses: akkuman/gitea-release-action@v1
|
|
env:
|
|
NODE_OPTIONS: "--experimental-fetch" # if nodejs < 18
|
|
with:
|
|
files: |-
|
|
artifacts/**
|