Uploaded images, fonts and sounds belonged to nobody. Every account saw every file in the pickers, and only an administrator could delete one, through the API alone. Now every account uploads into a folder of its own, sees its own files and nobody's, and can delete a file of its own that no project uses. - Files are stored as data/<kind>/<folder>/<sha256>.<ext>, and the folder is part of asset.file. A name without a folder belongs to nobody. - The folder is a random 12-character name kept in users.json and given with the first upload. Renaming an account moves no file, and a released game's URLs carry no account name. - The list shows the caller's own files and nobody's. An administrator sees all, each with owner and deletable. - DELETE takes the name with its folder. It answers 403 unless the file is the caller's or the caller is an administrator, and 409 while a project, snapshot or release of any account names it (FileUsage). The 409 names the caller's own projects only. - The pickers have a Delete button. The first press asks, the second deletes, and a refusal shows the server's reason. - A deleted account's folder stays and only administrators see it. - tools/migrate-file-owners.php moved every used file into the folder of the account using it (a copy each for two accounts) and rewrote projects, snapshots and releases. A project's revision goes up, so an open editor gets a conflict instead of saving old names back. - Font families are named after the hash alone, so a folder never ends up in a CSS family name. Run on stein2 on 2026-10-07, backup in /root/config-backup-20261007/data-before-344: 25 files used, 27 copies, 8 projects, 53 snapshots and 1 release rewritten, 30 unused files stay nobody's. Afterwards all 600 references resolve to a file in their owner's folder. Found while building: the Delete button cut its new label to "Del…" because a button does not measure itself again on a new text. The picker now lays its button row out again. Tests: - PHP files.test.php (new): 46 checks, counter-check 3 red - Unit core + editor: 220 files, 3403 tests - e2e 34 (melektaus-atx): ALL PASSED - 67 checks (2 new) - Gate (melektaus-atx): CHECK EXIT 0, 256 files, 3977 tests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
70 lines
2.3 KiB
YAML
70 lines
2.3 KiB
YAML
# Runs the whole proof on the Gitea runner: gate, the editor suite and the three example games.
|
||
#
|
||
# The suite runs on `game-maker-wsl`, the runner in the WSL2 distro game-maker-ci on
|
||
# melektaus-atx (#283). Its label picks the image built from tools/ci/Dockerfile. The GPU
|
||
# (/dev/dxg and the Windows driver libraries), /dev/shm and GAME_MAKER_BROWSER=wsl come from that
|
||
# runner's own config.yaml, not from here – without them chromium falls back to software WebGL and
|
||
# the harness stops. The gate needs no GPU and runs on `game-maker-ci`, the runner on stein2 with
|
||
# the same image. Pointing the suite at that label too moves the browser runs back to stein2.
|
||
#
|
||
# Two jobs without `needs:`, so they start together. The gate does not stand in front of the
|
||
# suite: a lint error used to cost the full e2e run before it was reported, and the run reported
|
||
# it after six minutes instead of one. Both still have to pass for the push to be green.
|
||
#
|
||
# On two runners the gate's vitest no longer shares cores with the suite's chromium, which
|
||
# measures text widths and frame counts. GM_TEST_WORKERS still caps vitest at two workers, for the
|
||
# day both jobs share one runner again.
|
||
name: game-maker
|
||
|
||
on:
|
||
push:
|
||
workflow_dispatch:
|
||
|
||
jobs:
|
||
gate:
|
||
runs-on: game-maker-ci
|
||
timeout-minutes: 20
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: Install
|
||
run: npm ci --no-audit --no-fund
|
||
|
||
- name: Gate
|
||
run: ./check.sh
|
||
env:
|
||
GM_TEST_WORKERS: 2
|
||
|
||
# The API's own rules (#180, #179, #231, #266). Not part of check.sh: the host the editor is built
|
||
# on has no PHP, the image does.
|
||
- name: PHP tests
|
||
run: |
|
||
php tests/php/accounts.test.php
|
||
php tests/php/snapshots.test.php
|
||
php tests/php/releases.test.php
|
||
php tests/php/files.test.php
|
||
|
||
suite:
|
||
runs-on: game-maker-wsl
|
||
timeout-minutes: 45
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: Versions
|
||
run: |
|
||
node --version
|
||
chromium --version
|
||
php --version | head -1
|
||
|
||
- name: Install
|
||
run: npm ci --no-audit --no-fund
|
||
|
||
- name: Build
|
||
run: npm run build
|
||
|
||
- name: Editor suite
|
||
run: tools/ci/run-e2e.sh
|
||
|
||
- name: Example games
|
||
run: tools/ci/run-smokes.sh
|