diff --git a/.forgejo/workflows/deploy.yaml b/.forgejo/workflows/deploy.yaml new file mode 100644 index 0000000..55a7b70 --- /dev/null +++ b/.forgejo/workflows/deploy.yaml @@ -0,0 +1,96 @@ +name: Deploy + +on: + push: + branches: [master] + workflow_dispatch: + +# One deploy at a time; if you push twice quickly, cancel the older run so the +# newest commit is what lands on the server. +concurrency: + group: deploy + cancel-in-progress: true + +jobs: + build-deploy: + runs-on: arch-latest + steps: + - name: Install build dependencies + run: | + # Same keyring bootstrap the Crafter.Build CI does: the slim + # archlinux:latest image ships without a populated pacman keyring + # or local master key. + pacman-key --init + pacman-key --populate archlinux + pacman -Sy --noconfirm --needed archlinux-keyring + pacman -Syu --noconfirm --needed \ + clang lld libc++ \ + wasi-libc wasi-libc++ wasi-libc++abi wasi-compiler-rt \ + git curl tar rsync + # Container runs as root; workspace may be owned by another uid. + git config --global --add safe.directory '*' + + - name: Install crafter-build + # Pull the rolling 'latest' Linux build from the Crafter.Build repo and + # install it distro-style so it auto-discovers its modules under + # /usr/share/crafter-build. v2 = SSE4.2 baseline, safe on the CI SBC. + run: | + set -eux + url="https://forgejo.catcrafts.net/Catcrafts/Crafter.Build/releases/download/latest/crafter-build-linux-x86_64-v2.tar.gz" + mkdir -p /tmp/cb + curl -fsSL "$url" -o /tmp/cb.tar.gz + tar -xzf /tmp/cb.tar.gz -C /tmp/cb + install -Dm755 /tmp/cb/bin/crafter-build /usr/bin/crafter-build + cp -r /tmp/cb/share/crafter-build /usr/share/ + crafter-build --version || true + + - name: Checkout + uses: actions/checkout@v4 + + - name: Cache crafter-build dependency clones + # ~/.cache/crafter.build holds the Crafter.Graphics clone and prebuilt + # module cache. crafter-build still git-pulls the dep each run, so a + # stale cache only means a smaller delta fetch, never a stale build. + uses: actions/cache@v4 + with: + path: ~/.cache/crafter.build + key: crafter-cache-${{ runner.os }}-${{ hashFiles('project.cpp') }} + restore-keys: | + crafter-cache-${{ runner.os }}- + + - name: Build (wasm bundle) + run: crafter-build + + - name: Locate build output + id: out + run: | + set -eu + dist=$(find bin -maxdepth 1 -type d -name 'Catcrafts.Net-wasm32-wasip1-*' | head -n1) + if [ -z "$dist" ]; then + echo "No build output directory found under bin/" >&2 + ls -la bin || true + exit 1 + fi + echo "dist=$dist" >> "$GITHUB_OUTPUT" + echo "Built bundle: $dist" + ls -la "$dist" + + - name: Deploy to web root + # No SSH: the job already runs on the deploy box. The server's web root + # is bind-mounted into this container at /deploy via the runner config + # (container.options: "-v /path/to/webroot:/deploy"). We just copy into + # it. --delete makes the root an exact mirror of the build; Caddyfile.coi + # is a local dev helper (its 'root' points at the build machine), so the + # server's own Caddy config supplies the headers instead. + env: + DIST: ${{ steps.out.outputs.dist }} + run: | + set -eu + if [ ! -d /deploy ]; then + echo "ERROR: /deploy is not mounted into the runner container." >&2 + echo "Add '-v /your/webroot:/deploy' to the runner's container.options" >&2 + echo "in config.yaml and restart the runner." >&2 + exit 1 + fi + rsync -a --delete --exclude 'Caddyfile.coi' "$DIST"/ /deploy/ + echo "Deployed $DIST -> /deploy (host web root)" diff --git a/README.md b/README.md index be1d292..800d0a7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # catcrafts.net -This is the source code for catcrafts.net, a website built entirely in C++ using the Crafter.CppDOM library. +This is the source code for catcrafts.net, a website built entirely in C++ using the Crafter.Graphics library. ```bash crafter-build build executable diff --git a/catcrafts-head.js b/catcrafts-head.js new file mode 100644 index 0000000..409d92b --- /dev/null +++ b/catcrafts-head.js @@ -0,0 +1,24 @@ +// Head-element setup for catcrafts.net. The Crafter.Graphics Dom partition +// only exposes element creation under
, so anything that has to live in +// (title, stylesheet link, favicon link) gets injected from this +// loader. EnableWasiBrowserRuntime auto-picks up every *.js in cfg.files and +// emits a