refactor: extract shared player, session, and chat packages #5
@@ -1,45 +0,0 @@
|
||||
Create a new Gitea release for this project using semantic versioning.
|
||||
|
||||
## Current state
|
||||
|
||||
Fetch tags and find the latest version:
|
||||
|
||||
```
|
||||
!git fetch --tags && git tag --sort=-v:refname | head -5
|
||||
```
|
||||
|
||||
Commits since the last release (if no tags exist, this shows all commits):
|
||||
|
||||
```
|
||||
!git log $(git describe --tags --abbrev=0 2>/dev/null && echo "$(git describe --tags --abbrev=0)..HEAD" || echo "") --oneline
|
||||
```
|
||||
|
||||
## Instructions
|
||||
|
||||
1. **Determine current version** from the tag output above. If no `vX.Y.Z` tags exist, treat current version as `v0.0.0`.
|
||||
|
||||
2. **Analyze commits** using conventional commit prefixes to pick the semver bump:
|
||||
- Breaking changes (`!` after type, or `BREAKING CHANGE` in body) → **major** bump
|
||||
- `feat:` → **minor** bump
|
||||
- `fix:`, `chore:`, `deps:`, `revert:`, and everything else → **patch** bump
|
||||
- Use the **highest** applicable bump level across all commits
|
||||
|
||||
3. **Generate release notes** — group commits into sections:
|
||||
- **Features** — `feat:` commits
|
||||
- **Fixes** — `fix:` commits
|
||||
- **Other** — everything else (`chore:`, `deps:`, `revert:`, etc.)
|
||||
- Omit empty sections. Each commit is a bullet point with its short description (strip the prefix).
|
||||
|
||||
4. **Present for approval** — show the user:
|
||||
- Current version → proposed new version
|
||||
- The full release notes
|
||||
- The exact `tea` command that will run
|
||||
- Ask the user to confirm before proceeding
|
||||
|
||||
5. **Create the release** — on user approval, run:
|
||||
```
|
||||
tea releases create --login gitea --repo ryan/c4 --tag <version> --target main -t "<version>" -n "<release notes>"
|
||||
```
|
||||
Do NOT create a local git tag — Gitea creates it server-side.
|
||||
|
||||
6. **Verify** — run `tea releases ls --login gitea --repo ryan/c4` to confirm the release was created.
|
||||
@@ -1,10 +1,10 @@
|
||||
c4
|
||||
c4.db
|
||||
games
|
||||
games.db
|
||||
data/
|
||||
deploy/
|
||||
.env
|
||||
.git
|
||||
.gitignore
|
||||
assets/css/output.css
|
||||
c4-deploy-*.tar.gz
|
||||
c4-deploy-*_b64*.txt
|
||||
games-deploy-*.tar.gz
|
||||
games-deploy-*_b64*.txt
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Log level (TRACE, DEBUG, INFO, WARN, ERROR). Defaults to INFO.
|
||||
# LOG_LEVEL=DEBUG
|
||||
|
||||
# SQLite database path. Defaults to data/c4.db.
|
||||
# DB_PATH=data/c4.db
|
||||
# SQLite database path. Defaults to data/games.db.
|
||||
# DB_PATH=data/games.db
|
||||
|
||||
# Application URL for invite links. Defaults to https://games.adriatica.io.
|
||||
# APP_URL=http://localhost:7331
|
||||
@@ -12,5 +12,5 @@
|
||||
|
||||
# Goose CLI migration config (only needed for running goose manually)
|
||||
GOOSE_DRIVER=sqlite3
|
||||
GOOSE_DBSTRING=data/c4.db?_pragma=foreign_keys(1)&_pragma=journal_mode(WAL)
|
||||
GOOSE_DBSTRING=data/games.db?_pragma=foreign_keys(1)&_pragma=journal_mode(WAL)
|
||||
GOOSE_MIGRATION_DIR=db/migrations
|
||||
|
||||
@@ -6,7 +6,7 @@ on:
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
DEPLOY_DIR: /home/ryan/c4
|
||||
DEPLOY_DIR: /home/ryan/games
|
||||
|
||||
jobs:
|
||||
test:
|
||||
|
||||
@@ -9,10 +9,10 @@ RUN go mod download
|
||||
COPY . .
|
||||
RUN go tool gotailwind -i assets/css/input.css -o assets/css/output.css --minify
|
||||
RUN --mount=type=cache,target=/root/.cache/go-build \
|
||||
CGO_ENABLED=0 go build -ldflags="-s" -o /bin/c4 .
|
||||
RUN upx -9 -k /bin/c4
|
||||
CGO_ENABLED=0 go build -ldflags="-s" -o /bin/games .
|
||||
RUN upx -9 -k /bin/games
|
||||
|
||||
FROM scratch
|
||||
ENV PORT=8080
|
||||
COPY --from=build /bin/c4 /
|
||||
ENTRYPOINT ["/c4"]
|
||||
COPY --from=build /bin/games /
|
||||
ENTRYPOINT ["/games"]
|
||||
|
||||
10
Taskfile.yml
10
Taskfile.yml
@@ -27,9 +27,9 @@ tasks:
|
||||
- "assets/css/output.css"
|
||||
|
||||
build:
|
||||
desc: Production build to bin/c4
|
||||
desc: Production build to bin/games
|
||||
cmds:
|
||||
- go build -o bin/c4 .
|
||||
- go build -o bin/games .
|
||||
deps:
|
||||
- build:templ
|
||||
- build:styles
|
||||
@@ -49,8 +49,8 @@ tasks:
|
||||
cmds:
|
||||
- |
|
||||
go tool air \
|
||||
-build.cmd "go build -tags=dev -o tmp/bin/c4 ." \
|
||||
-build.bin "tmp/bin/c4" \
|
||||
-build.cmd "go build -tags=dev -o tmp/bin/games ." \
|
||||
-build.bin "tmp/bin/games" \
|
||||
-build.exclude_dir "data,bin,tmp,deploy" \
|
||||
-build.include_ext "go,templ" \
|
||||
-misc.clean_on_exit "true"
|
||||
@@ -75,7 +75,7 @@ tasks:
|
||||
run:
|
||||
desc: Build and run the server
|
||||
cmds:
|
||||
- ./bin/c4
|
||||
- ./bin/games
|
||||
deps:
|
||||
- build
|
||||
|
||||
|
||||
@@ -71,6 +71,6 @@ func loadBase() *Config {
|
||||
}
|
||||
}(),
|
||||
AppURL: getEnv("APP_URL", "https://games.adriatica.io"),
|
||||
DBPath: getEnv("DB_PATH", "data/c4.db"),
|
||||
DBPath: getEnv("DB_PATH", "data/games.db"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
# Deploy the c4 binary to /opt/c4, then restart the service.
|
||||
# Deploy the games binary to /opt/games, then restart the service.
|
||||
# Works from the repo (builds first) or from an extracted tarball (pre-built binary).
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
INSTALL_DIR="/opt/c4"
|
||||
BINARY="$ROOT_DIR/c4"
|
||||
INSTALL_DIR="/opt/games"
|
||||
BINARY="$ROOT_DIR/games"
|
||||
|
||||
# If Go is available and we have source, build fresh
|
||||
if [[ -f "$ROOT_DIR/go.mod" ]] && command -v go &>/dev/null; then
|
||||
@@ -13,7 +13,7 @@ if [[ -f "$ROOT_DIR/go.mod" ]] && command -v go &>/dev/null; then
|
||||
(cd "$ROOT_DIR" && go tool gotailwind -i assets/css/input.css -o assets/css/output.css --minify)
|
||||
|
||||
echo "Building binary..."
|
||||
(cd "$ROOT_DIR" && CGO_ENABLED=0 go build -o c4 .)
|
||||
(cd "$ROOT_DIR" && CGO_ENABLED=0 go build -o games .)
|
||||
fi
|
||||
|
||||
if [[ ! -f "$BINARY" ]]; then
|
||||
@@ -22,10 +22,10 @@ if [[ ! -f "$BINARY" ]]; then
|
||||
fi
|
||||
|
||||
echo "Installing to $INSTALL_DIR..."
|
||||
install -o games -g games -m 755 "$BINARY" "$INSTALL_DIR/c4"
|
||||
install -o games -g games -m 755 "$BINARY" "$INSTALL_DIR/games"
|
||||
|
||||
echo "Restarting service..."
|
||||
systemctl restart c4.service
|
||||
systemctl restart games.service
|
||||
|
||||
echo "Done. Status:"
|
||||
systemctl status c4.service --no-pager
|
||||
systemctl status games.service --no-pager
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
[Unit]
|
||||
Description=C4 Game Lobby
|
||||
Description=Games Lobby
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=games
|
||||
Group=games
|
||||
WorkingDirectory=/opt/c4
|
||||
ExecStart=/opt/c4/c4
|
||||
WorkingDirectory=/opt/games
|
||||
ExecStart=/opt/games/games
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
@@ -17,7 +17,7 @@ Environment=PORT=8080
|
||||
NoNewPrivileges=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadWritePaths=/opt/c4
|
||||
ReadWritePaths=/opt/games
|
||||
PrivateTmp=true
|
||||
|
||||
[Install]
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build the c4 binary, bundle it with deploy files into a tarball,
|
||||
# Build the games binary, bundle it with deploy files into a tarball,
|
||||
# base64-encode it, and split into 25MB chunks for transfer.
|
||||
set -euo pipefail
|
||||
|
||||
@@ -7,14 +7,14 @@ REPO_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$REPO_DIR"
|
||||
|
||||
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
|
||||
TARBALL="c4-deploy-${TIMESTAMP}.tar.gz"
|
||||
BASE64_FILE="c4-deploy-${TIMESTAMP}_b64.txt"
|
||||
TARBALL="games-deploy-${TIMESTAMP}.tar.gz"
|
||||
BASE64_FILE="games-deploy-${TIMESTAMP}_b64.txt"
|
||||
|
||||
#==============================================================================
|
||||
# Clean previous artifacts
|
||||
#==============================================================================
|
||||
echo "--- Cleaning old artifacts ---"
|
||||
rm -f ./c4 c4-deploy-*.tar.gz c4-deploy-*_b64*.txt
|
||||
rm -f ./games games-deploy-*.tar.gz games-deploy-*_b64*.txt
|
||||
|
||||
#==============================================================================
|
||||
# Build
|
||||
@@ -23,18 +23,18 @@ echo "--- Building CSS ---"
|
||||
go tool gotailwind -i assets/css/input.css -o assets/css/output.css --minify
|
||||
|
||||
echo "--- Building binary (linux/amd64) ---"
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o c4 .
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o games .
|
||||
|
||||
#==============================================================================
|
||||
# Verify required files
|
||||
#==============================================================================
|
||||
echo "--- Verifying files ---"
|
||||
REQUIRED_FILES=(
|
||||
c4
|
||||
games
|
||||
deploy/setup.sh
|
||||
deploy/deploy.sh
|
||||
deploy/reassemble.sh
|
||||
deploy/c4.service
|
||||
deploy/games.service
|
||||
)
|
||||
for f in "${REQUIRED_FILES[@]}"; do
|
||||
if [[ ! -f "$f" ]]; then
|
||||
@@ -48,12 +48,12 @@ done
|
||||
# Create tarball
|
||||
#==============================================================================
|
||||
echo "--- Creating tarball ---"
|
||||
tar -czf "/tmp/${TARBALL}" --transform 's,^,c4/,' \
|
||||
c4 \
|
||||
tar -czf "/tmp/${TARBALL}" --transform 's,^,games/,' \
|
||||
games \
|
||||
deploy/setup.sh \
|
||||
deploy/deploy.sh \
|
||||
deploy/reassemble.sh \
|
||||
deploy/c4.service
|
||||
deploy/games.service
|
||||
|
||||
mv "/tmp/${TARBALL}" .
|
||||
echo " -> ${TARBALL} ($(du -h "${TARBALL}" | cut -f1))"
|
||||
@@ -66,10 +66,10 @@ base64 "${TARBALL}" > "${BASE64_FILE}"
|
||||
echo " -> ${BASE64_FILE} ($(du -h "${BASE64_FILE}" | cut -f1))"
|
||||
|
||||
echo "--- Splitting into 25MB chunks ---"
|
||||
split -b 25M -d --additional-suffix=.txt "${BASE64_FILE}" "c4-deploy-${TIMESTAMP}_b64_part"
|
||||
split -b 25M -d --additional-suffix=.txt "${BASE64_FILE}" "games-deploy-${TIMESTAMP}_b64_part"
|
||||
rm -f "${BASE64_FILE}"
|
||||
|
||||
CHUNKS=(c4-deploy-${TIMESTAMP}_b64_part*.txt)
|
||||
CHUNKS=(games-deploy-${TIMESTAMP}_b64_part*.txt)
|
||||
echo " -> ${#CHUNKS[@]} chunk(s):"
|
||||
for chunk in "${CHUNKS[@]}"; do
|
||||
echo " $chunk ($(du -h "$chunk" | cut -f1))"
|
||||
@@ -83,5 +83,5 @@ echo "=== Package Complete ==="
|
||||
echo ""
|
||||
echo "Transfer the chunk files to the target server, then run:"
|
||||
echo " ./reassemble.sh"
|
||||
echo " cd ~/c4 && sudo ./deploy/setup.sh # first time only"
|
||||
echo " cd ~/c4 && sudo ./deploy/deploy.sh"
|
||||
echo " cd ~/games && sudo ./deploy/setup.sh # first time only"
|
||||
echo " cd ~/games && sudo ./deploy/deploy.sh"
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
# Reassembles base64 chunks and extracts the c4 deployment tarball.
|
||||
# Reassembles base64 chunks and extracts the games deployment tarball.
|
||||
# Expects chunk files in the current directory.
|
||||
set -euo pipefail
|
||||
|
||||
cd "$HOME"
|
||||
|
||||
echo "=== C4 Deployment Reassembler ==="
|
||||
echo "=== Games Deployment Reassembler ==="
|
||||
echo "Working directory: $HOME"
|
||||
echo ""
|
||||
|
||||
@@ -14,10 +14,10 @@ echo ""
|
||||
#==============================================================================
|
||||
echo "--- Finding chunk files ---"
|
||||
|
||||
CHUNKS=($(ls -1 c4-deploy-*_b64_part*.txt 2>/dev/null | sort))
|
||||
CHUNKS=($(ls -1 games-deploy-*_b64_part*.txt 2>/dev/null | sort))
|
||||
|
||||
if [[ ${#CHUNKS[@]} -eq 0 ]]; then
|
||||
echo "ERROR: No chunk files found matching c4-deploy-*_b64_part*.txt"
|
||||
echo "ERROR: No chunk files found matching games-deploy-*_b64_part*.txt"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -32,8 +32,8 @@ done
|
||||
echo ""
|
||||
echo "--- Reassembling chunks ---"
|
||||
|
||||
TIMESTAMP=$(echo "${CHUNKS[0]}" | sed -E 's/c4-deploy-([0-9]+-[0-9]+)_b64_part.*/\1/')
|
||||
TARBALL="c4-deploy-${TIMESTAMP}.tar.gz"
|
||||
TIMESTAMP=$(echo "${CHUNKS[0]}" | sed -E 's/games-deploy-([0-9]+-[0-9]+)_b64_part.*/\1/')
|
||||
TARBALL="games-deploy-${TIMESTAMP}.tar.gz"
|
||||
COMBINED="combined_b64.txt"
|
||||
|
||||
echo "Concatenating chunks..."
|
||||
@@ -58,12 +58,12 @@ fi
|
||||
echo ""
|
||||
echo "--- Archiving existing source ---"
|
||||
|
||||
if [[ -d c4 ]]; then
|
||||
rm -rf c4.bak
|
||||
mv c4 c4.bak
|
||||
echo " -> Moved c4 -> c4.bak"
|
||||
if [[ -d games ]]; then
|
||||
rm -rf games.bak
|
||||
mv games games.bak
|
||||
echo " -> Moved games -> games.bak"
|
||||
else
|
||||
echo " -> No existing c4 directory"
|
||||
echo " -> No existing games directory"
|
||||
fi
|
||||
|
||||
#==============================================================================
|
||||
@@ -73,7 +73,7 @@ echo ""
|
||||
echo "--- Extracting tarball ---"
|
||||
|
||||
tar -xzf "$TARBALL"
|
||||
echo " -> Extracted to ~/c4"
|
||||
echo " -> Extracted to ~/games"
|
||||
|
||||
#==============================================================================
|
||||
# Cleanup
|
||||
@@ -91,6 +91,6 @@ echo ""
|
||||
echo "=== Reassembly Complete ==="
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " cd ~/c4"
|
||||
echo " cd ~/games"
|
||||
echo " sudo ./deploy/setup.sh # first time only"
|
||||
echo " sudo ./deploy/deploy.sh"
|
||||
|
||||
@@ -10,20 +10,20 @@ fi
|
||||
|
||||
# Create system user if it doesn't exist
|
||||
if ! id -u games &>/dev/null; then
|
||||
useradd --system --shell /usr/sbin/nologin --home-dir /opt/c4 --create-home games
|
||||
useradd --system --shell /usr/sbin/nologin --home-dir /opt/games --create-home games
|
||||
echo "Created system user: games"
|
||||
else
|
||||
echo "User 'games' already exists"
|
||||
fi
|
||||
|
||||
# Ensure install directory exists with correct ownership
|
||||
install -d -o games -g games -m 755 /opt/c4
|
||||
install -d -o games -g games -m 755 /opt/c4/data
|
||||
install -d -o games -g games -m 755 /opt/games
|
||||
install -d -o games -g games -m 755 /opt/games/data
|
||||
|
||||
# Install systemd unit
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
cp "$SCRIPT_DIR/c4.service" /etc/systemd/system/c4.service
|
||||
cp "$SCRIPT_DIR/games.service" /etc/systemd/system/games.service
|
||||
systemctl daemon-reload
|
||||
systemctl enable c4.service
|
||||
systemctl enable games.service
|
||||
|
||||
echo "Setup complete. Run deploy.sh to build and start the service."
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
services:
|
||||
c4:
|
||||
games:
|
||||
build: .
|
||||
container_name: c4
|
||||
container_name: games
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8080:8080"
|
||||
|
||||
@@ -23,7 +23,7 @@ func SetupSessionManager(db *sql.DB) (*scs.SessionManager, func()) {
|
||||
sessionManager := scs.New()
|
||||
sessionManager.Store = store
|
||||
sessionManager.Lifetime = 30 * 24 * time.Hour
|
||||
sessionManager.Cookie.Name = "c4_session"
|
||||
sessionManager.Cookie.Name = "games_session"
|
||||
sessionManager.Cookie.Path = "/"
|
||||
sessionManager.Cookie.HttpOnly = true
|
||||
sessionManager.Cookie.Secure = true
|
||||
|
||||
Reference in New Issue
Block a user