Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions .github/actions/build-wasm/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
name: Build files.wasm
description: >
Checks out the sibling repositories the path dependencies need, builds the
plugin SDK, the frontend and the wasm module. Leaves files.wasm in the plugin
directory.

inputs:
gameap-ref:
description: Ref of gameap/gameap providing web/plugin-sdk
required: true
gameap-proto-ref:
description: Ref of gameap/gameap-proto providing rust/gameap-plugin-sdk
required: true
plugin-path:
description: Directory this repository is checked out into
required: false
default: plugin-files
run-tests:
description: Run cargo test and the frontend test suite
required: false
default: 'true'
run-lint:
description: Run clippy and the frontend typecheck
required: false
default: 'true'

runs:
using: composite
steps:
# The frontend depends on file:../../gameap-api/web/plugin-sdk, so the
# gameap repo must be checked out as a sibling directory named gameap-api
- uses: actions/checkout@v4
with:
repository: gameap/gameap
ref: ${{ inputs.gameap-ref }}
path: gameap-api

# Cargo.toml depends on path = "../gameap-proto/rust/gameap-plugin-sdk"
- uses: actions/checkout@v4
with:
repository: gameap/gameap-proto
ref: ${{ inputs.gameap-proto-ref }}
path: gameap-proto

- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
cache-dependency-path: |
gameap-api/web/plugin-sdk/package-lock.json
${{ inputs.plugin-path }}/frontend/package-lock.json

# The @gameap/ui tarball on npm is missing its icons/ directory, so the
# package from the gameap checkout is installed over it. That package
# ships no type declarations, so the tsc half of the SDK's "npm run
# build" fails on the '@gameap/ui' re-export; the ambient shim types it
# as `any` so tsc can emit dist/*.d.ts — without them the frontend
# typecheck hits TS7016 on every '@gameap/plugin-sdk' import.
- name: Build plugin SDK
shell: bash
working-directory: gameap-api/web/plugin-sdk
run: |
npm ci
npm install --no-save ../frontend/packages/gameap-ui
echo "declare module '@gameap/ui';" > src/gameap-ui-shim.d.ts
npx vite build
npx tsc --emitDeclarationOnly

- name: Build frontend
shell: bash
working-directory: ${{ inputs.plugin-path }}/frontend
run: |
npm ci
npm run build

- name: Typecheck frontend
if: inputs.run-lint == 'true'
shell: bash
working-directory: ${{ inputs.plugin-path }}/frontend
run: npm run typecheck

- name: Test frontend
if: inputs.run-tests == 'true'
shell: bash
working-directory: ${{ inputs.plugin-path }}/frontend
run: npm test

# Installs the toolchain and targets pinned in rust-toolchain.toml
- name: Set up Rust
shell: bash
working-directory: ${{ inputs.plugin-path }}
run: rustup toolchain install

- uses: Swatinem/rust-cache@v2
with:
workspaces: ${{ inputs.plugin-path }}

- name: Test
if: inputs.run-tests == 'true'
shell: bash
working-directory: ${{ inputs.plugin-path }}
run: cargo test

- name: Clippy
if: inputs.run-lint == 'true'
shell: bash
working-directory: ${{ inputs.plugin-path }}
run: |
cargo clippy --target wasm32-wasip1 -- -D warnings
cargo clippy --all-targets -- -D warnings

- name: Install binaryen
shell: bash
run: sudo apt-get update && sudo apt-get install -y binaryen

- name: Build wasm
shell: bash
working-directory: ${{ inputs.plugin-path }}
run: make wasm
53 changes: 53 additions & 0 deletions .github/e2e/node-linux/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Node image for the E2E workflow: a systemd-booted container that reproduces a
# real machine closely enough for two things that a plain container cannot do.
# gameapctl takes its systemd code paths instead of the fork fallback it uses
# when PID 1 is not systemd, and install-files-linux.sh finds the systemctl it
# refuses to run without.
ARG BASE_IMAGE=debian:13
FROM ${BASE_IMAGE}

ARG DEBIAN_FRONTEND=noninteractive
ENV container=docker

# ca-certificates has to be present before gameapctl runs: when the installer
# has to install it itself, it stops and asks to be re-run instead of
# continuing. iproute2 and procps back the node fixture's listeningPorts().
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
systemd \
systemd-sysv \
dbus \
ca-certificates \
curl \
gnupg \
tar \
xz-utils \
iproute2 \
procps \
&& rm -rf /var/lib/apt/lists/*

# Masking is done with symlinks rather than `systemctl mask` because there is
# no systemd manager to talk to during the image build.
#
# udevd/modules-load have no hardware to work with; networkd-wait-online would
# hold up network-online.target for up to 2 minutes; resolved would fight
# docker over /etc/resolv.conf; apparmor.service must not load container
# profiles into the kernel shared with the host under --privileged; getty keeps
# failed units out of `systemctl is-system-running`.
RUN for unit in \
systemd-udevd.service \
systemd-udevd-kernel.socket \
systemd-udevd-control.socket \
systemd-modules-load.service \
systemd-networkd-wait-online.service \
systemd-resolved.service \
apparmor.service \
getty.target \
console-getty.service \
; do \
ln -sf /dev/null "/etc/systemd/system/${unit}"; \
done

STOPSIGNAL SIGRTMIN+3

CMD ["/sbin/init"]
98 changes: 26 additions & 72 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,85 +28,39 @@ jobs:
with:
path: plugin-files

# The frontend depends on file:../../gameap-api/web/plugin-sdk, so the
# gameap repo must be checked out as a sibling directory named gameap-api
- uses: actions/checkout@v4
- uses: ./plugin-files/.github/actions/build-wasm
with:
repository: gameap/gameap
ref: ${{ env.GAMEAP_REF }}
path: gameap-api
gameap-ref: ${{ env.GAMEAP_REF }}
gameap-proto-ref: ${{ env.GAMEAP_PROTO_REF }}
plugin-path: plugin-files

# Cargo.toml depends on path = "../gameap-proto/rust/gameap-plugin-sdk"
- uses: actions/checkout@v4
- uses: actions/upload-artifact@v4
with:
repository: gameap/gameap-proto
ref: ${{ env.GAMEAP_PROTO_REF }}
path: gameap-proto
name: files-wasm
path: plugin-files/files.wasm

# The e2e suite itself only runs nightly, so this compiles it on every change
# to keep it from rotting in between.
e2e-compile:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
cache-dependency-path: |
gameap-api/web/plugin-sdk/package-lock.json
plugin-files/frontend/package-lock.json

# The @gameap/ui tarball on npm is missing its icons/ directory, so the
# package from the gameap checkout is installed over it. That package
# ships no type declarations, so the tsc half of the SDK's "npm run
# build" fails on the '@gameap/ui' re-export; the ambient shim types it
# as `any` so tsc can emit dist/*.d.ts — without them the frontend
# typecheck hits TS7016 on every '@gameap/plugin-sdk' import.
- name: Build plugin SDK
working-directory: gameap-api/web/plugin-sdk
cache-dependency-path: e2e/package-lock.json

- name: Compile the e2e suite
working-directory: e2e
env:
E2E_ADMIN_PASSWORD: compile-only
E2E_NODE_OS: linux
E2E_NODE_HOST: 127.0.0.1
E2E_NODE_WORK_PATH: /srv/gameap
E2E_WASM_PATH: /dev/null
run: |
npm ci
npm install --no-save ../frontend/packages/gameap-ui
echo "declare module '@gameap/ui';" > src/gameap-ui-shim.d.ts
npx vite build
npx tsc --emitDeclarationOnly

- name: Build frontend
working-directory: plugin-files/frontend
run: |
npm ci
npm run build

- name: Typecheck frontend
working-directory: plugin-files/frontend
run: npm run typecheck

- name: Test frontend
working-directory: plugin-files/frontend
run: npm test

# Installs the toolchain and targets pinned in rust-toolchain.toml
- name: Set up Rust
working-directory: plugin-files
run: rustup toolchain install

- uses: Swatinem/rust-cache@v2
with:
workspaces: plugin-files

- name: Test
working-directory: plugin-files
run: cargo test

- name: Clippy
working-directory: plugin-files
run: |
cargo clippy --target wasm32-wasip1 -- -D warnings
cargo clippy --all-targets -- -D warnings

- name: Install binaryen
run: sudo apt-get update && sudo apt-get install -y binaryen

- name: Build wasm
working-directory: plugin-files
run: make wasm

- uses: actions/upload-artifact@v4
with:
name: files-wasm
path: plugin-files/files.wasm
npx tsc --noEmit
npx playwright test --list
Loading
Loading