From f3dce4f08a309f7023bf036154128700c6a97894 Mon Sep 17 00:00:00 2001 From: Zsolt Tasnadi Date: Fri, 31 Jul 2026 18:33:44 +0200 Subject: [PATCH] initial commit --- README.md | 52 ++++++++++++++++++++++++++ example-makefile.make | 83 +++++++++++++++++++++++++++++++++++++++++ example-tasks.json | 35 +++++++++++++++++ example-woodpecker.yaml | 38 +++++++++++++++++++ web/index.html | 20 ++++++++++ 5 files changed, 228 insertions(+) create mode 100644 README.md create mode 100644 example-makefile.make create mode 100644 example-tasks.json create mode 100644 example-woodpecker.yaml create mode 100644 web/index.html diff --git a/README.md b/README.md new file mode 100644 index 0000000..e3da837 --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ +# bevy-tools + +CI/CD templates for [Bevy](https://bevyengine.org) (Rust) game +projects, in the same spirit as +[ebitengine-tools](../ebitengine-tools) and +[godot-tools](../godot-tools). + +- `example-makefile.make` — project Makefile: local dev targets + (`build`, `run`, `wasm`, `export`, `watch`, `clean`) plus the + Woodpecker pipeline targets (`ci-version`, `ci-export`, `ci-upload`, + `ci-update`). +- `example-woodpecker.yaml` — Woodpecker pipeline: version → build + (Rust, `wasm32-unknown-unknown` target + `wasm-bindgen` in the + `rust:1-alpine` image) → upload (scp to the droparea) → update + (calls the teletypegames `/update` endpoint with `platform=bevy`). +- `example-tasks.json` — VS Code `.vscode/tasks.json` with the common + dev tasks: **Run** (`cargo run`, default build task, `Cmd+Shift+B`), + **Build & Run**, **Build WASM** and **Make build**. +- `web/index.html` — the HTML shell downloaded by `make export` and + packaged next to the `wasm-bindgen` output (`game.js` + + `game_bg.wasm`). + +## Usage in a game repo + +1. Copy `example-makefile.make` to `Makefile` and set `PROJECT` + (must match the crate name in `Cargo.toml`; the native binary is + built to `bin/$(PROJECT)`). +2. Pin the `wasm-bindgen` crate in `Cargo.toml` to the exact version + in `WASM_BINDGEN_VERSION`: + + ```toml + [target.'cfg(target_arch = "wasm32")'.dependencies] + wasm-bindgen = "=0.2.100" + ``` + + The `wasm-bindgen` CLI and the crate **must be the same version**, + otherwise the generated JS glue refuses to load. The pipeline + installs the CLI version parsed from the Makefile. +3. Copy `example-woodpecker.yaml` to `.woodpecker.yaml` and add the + `droparea_ssh_password` / `update_secret_key` secrets in Woodpecker. +4. Copy `example-tasks.json` to `.vscode/tasks.json` and replace the + binary name (`bevydemo`) with `$(PROJECT)`. + +Local WASM builds additionally need +`rustup target add wasm32-unknown-unknown` and the `wasm-bindgen` CLI +(`cargo install wasm-bindgen-cli --version 0.2.100`). + +The pipeline uploads `$(PROJECT)-$(VERSION).html.zip` to the droparea, +then triggers +`/update?platform=bevy&name=$(PROJECT)&version=$(VERSION)`. + +Detailed documentation lives on the wiki: `/development/bevy`. diff --git a/example-makefile.make b/example-makefile.make new file mode 100644 index 0000000..f08bd62 --- /dev/null +++ b/example-makefile.make @@ -0,0 +1,83 @@ +# ----------------------------------------- +# Makefile – Bevy project builder +# ----------------------------------------- + +PROJECT = bevydemo + +# Must match the `wasm-bindgen` version pinned in Cargo.toml +# ([target.'cfg(target_arch = "wasm32")'.dependencies] wasm-bindgen = "=0.2.100") +WASM_BINDGEN_VERSION = 0.2.100 + +BIN_DIR = bin +DIST_DIR = dist +WASM_TARGET = wasm32-unknown-unknown +WASM_RELEASE = target/$(WASM_TARGET)/release/$(PROJECT).wasm +OUTPUT_ZIP = $(PROJECT)-$(VERSION).html.zip + +VERSION_FILE = .version +INDEX_HTML_URL = https://git.teletype.hu/tools/bevy-tools/raw/branch/master/web/index.html + +all: build + +build: + @mkdir -p $(BIN_DIR) + cargo build --release + cp target/release/$(PROJECT) $(BIN_DIR)/$(PROJECT) + +run: + cargo run + +wasm: + @mkdir -p $(DIST_DIR) + cargo build --release --target $(WASM_TARGET) + wasm-bindgen --target web --no-typescript \ + --out-dir $(DIST_DIR) --out-name game $(WASM_RELEASE) + +export: wasm + @if [ -z "$(VERSION)" ]; then \ + echo "ERROR: VERSION not set!"; exit 1; \ + fi + @echo "==> Downloading index.html" + curl -sSL $(INDEX_HTML_URL) -o $(DIST_DIR)/index.html + @echo "==> Packaging HTML/WASM for $(VERSION)" + zip -r $(OUTPUT_ZIP) -j $(DIST_DIR)/game_bg.wasm $(DIST_DIR)/game.js $(DIST_DIR)/index.html + @echo "==> Cleaning temporary files" + rm -f $(DIST_DIR)/game_bg.wasm $(DIST_DIR)/game.js $(DIST_DIR)/index.html + +watch: + fswatch -o src | while read; do make build; done + +clean: + rm -rf $(BIN_DIR) $(DIST_DIR) target + +ci-version: + @if [ -f metadata.json ]; then \ + VERSION=$$(jq -r '.version' metadata.json); \ + else \ + VERSION=$$(git rev-parse --short HEAD); \ + fi; \ + BRANCH=$$(git rev-parse --abbrev-ref HEAD); \ + if [ "$$BRANCH" != "main" ] && [ "$$BRANCH" != "master" ]; then \ + VERSION="dev-$$VERSION-$$BRANCH"; \ + fi; \ + echo $$VERSION > $(VERSION_FILE) + +ci-export: + @VERSION=$$(cat $(VERSION_FILE)); \ + $(MAKE) export VERSION=$$VERSION + +ci-upload: + @VERSION=$$(cat $(VERSION_FILE)); \ + FILE="$(PROJECT)-$$VERSION.html.zip"; \ + META_SRC="metadata.json"; \ + META_DST="$(PROJECT)-$$VERSION.metadata.json"; \ + cp $$META_SRC $$META_DST; \ + sshpass -p "$(DROPAREA_SSH_PASSWORD)" scp -o StrictHostKeyChecking=no -P $(DROPAREA_PORT) \ + $$FILE $$META_DST \ + $(DROPAREA_USER)@$(DROPAREA_HOST):$(DROPAREA_TARGET_PATH)/ + +ci-update: + @VERSION=$$(cat $(VERSION_FILE)); \ + curl "$(UPDATE_SERVER)/update?secret=$(UPDATE_SECRET)&name=$(PROJECT)&platform=bevy&version=$$VERSION" + +.PHONY: all build run wasm export watch clean ci-version ci-export ci-upload ci-update diff --git a/example-tasks.json b/example-tasks.json new file mode 100644 index 0000000..885bf4e --- /dev/null +++ b/example-tasks.json @@ -0,0 +1,35 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + // Copy to .vscode/tasks.json and replace "bevydemo" with your PROJECT name. + "version": "2.0.0", + "tasks": [ + { + "label": "Run", + "type": "shell", + "command": "cargo run", + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "Build & Run", + "type": "shell", + "command": "make clean && make build && ./bin/bevydemo", + "problemMatcher": [] + }, + { + "label": "Build WASM", + "type": "shell", + "command": "make wasm", + "problemMatcher": [] + }, + { + "label": "Make build", + "type": "shell", + "command": "make build" + } + ] +} diff --git a/example-woodpecker.yaml b/example-woodpecker.yaml new file mode 100644 index 0000000..c5b10b8 --- /dev/null +++ b/example-woodpecker.yaml @@ -0,0 +1,38 @@ +steps: + - name: version + image: alpine + commands: + - apk add --no-cache git make jq + - make ci-version + + - name: build + image: rust:1-alpine + commands: + - apk add --no-cache musl-dev zip make curl + - rustup target add wasm32-unknown-unknown + - WB=$(grep -o 'WASM_BINDGEN_VERSION *= *[0-9.]*' Makefile | grep -o '[0-9.]*$') + - curl -sSL "https://github.com/rustwasm/wasm-bindgen/releases/download/$${WB}/wasm-bindgen-$${WB}-x86_64-unknown-linux-musl.tar.gz" | tar xz -C /usr/local/bin --strip-components=1 + - make ci-export + + - name: upload + image: alpine + environment: + DROPAREA_HOST: vps.teletype.hu + DROPAREA_PORT: 2223 + DROPAREA_TARGET_PATH: /home/drop + DROPAREA_USER: drop + DROPAREA_SSH_PASSWORD: + from_secret: droparea_ssh_password + commands: + - apk add --no-cache make openssh-client sshpass + - make ci-upload + + - name: update + image: alpine + environment: + UPDATE_SERVER: https://teletypegames.org + UPDATE_SECRET: + from_secret: update_secret_key + commands: + - apk add --no-cache make curl + - make ci-update diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..f93eb47 --- /dev/null +++ b/web/index.html @@ -0,0 +1,20 @@ + + + + + Bevy Game + + + + + +