Skip to content

feat(storage): show browser usage and safely clear resource caches #349

feat(storage): show browser usage and safely clear resource caches

feat(storage): show browser usage and safely clear resource caches #349

Workflow file for this run

name: ci
on:
pull_request:
branches: ["**"]
permissions:
contents: read
concurrency:
group: ci-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
changes:
name: change-scope
runs-on: ubuntu-latest
outputs:
product: ${{ steps.scope.outputs.product }}
steps:
- name: Check out the merge commit and its base parent
uses: actions/checkout@v6
with:
fetch-depth: 2
- name: Classify whether product files changed
id: scope
run: python3 scripts/ci_scope.py HEAD^1 HEAD >> "$GITHUB_OUTPUT"
contracts:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- name: Check out the repository
uses: actions/checkout@v6
- name: Set up Go
uses: actions/setup-go@v7
with:
go-version-file: go.mod
cache: true
cache-dependency-path: go.sum
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version-file: .node-version
cache: npm
cache-dependency-path: web/package-lock.json
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.13"
- name: Enforce REPEATABLE READ isolation ceiling
run: make database-isolation-check
- name: Cache the repository Node.js toolchain
uses: actions/cache@v5
with:
path: .cache/tools/node-v24.22.1-linux-x64
key: retrom-node-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.node-version', 'scripts/prepare-node.sh') }}
- name: Prepare native PostgreSQL build prerequisites
run: sudo apt-get update && sudo apt-get install -y bison flex zlib1g-dev
- name: Cache native PostgreSQL tools
uses: actions/cache@v5
with:
path: .cache/tools/postgresql-18.3
key: retrom-postgresql-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('scripts/prepare-postgres.sh') }}
- name: Check workspace, structure, API and data contracts
run: make ci-contracts
- name: Check migrations against the latest published stable release
env:
GH_TOKEN: ${{ github.token }}
run: make migration-check-released
backend:
runs-on: ubuntu-latest
timeout-minutes: 45
env:
RETROM_TEST_DATABASE_URL: postgres://retrom:retrom-test@127.0.0.1:5432/postgres?sslmode=disable
services:
postgres:
image: postgres:18.3-bookworm@sha256:80630f83606d8db77d30b3851b16a9f78be2d0d4dda6f7b82a1fdca5ebe3acba
env:
POSTGRES_USER: retrom
POSTGRES_PASSWORD: retrom-test
POSTGRES_INITDB_ARGS: "-c max_connections=200"
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U retrom -d postgres"
--health-interval 2s --health-timeout 3s --health-retries 30
steps:
- name: Use runner disk for upload temporary storage
run: |
# Upload fixtures retain 10 GiB; avoid the size-limited /tmp tmpfs.
echo "TMPDIR=$RUNNER_TEMP" >> "$GITHUB_ENV"
df -h /tmp "$RUNNER_TEMP"
- name: Check out the repository
uses: actions/checkout@v6
- name: Set up Go
uses: actions/setup-go@v7
with:
go-version-file: go.mod
cache: true
cache-dependency-path: go.sum
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.13"
- name: Cache materialized runtime dependencies
uses: actions/cache@v5
with:
path: |
data/runtime
data/dat/emulatorjs/*/fbneo
data/dat/emulatorjs/*/mame2003
data/dat/emulatorjs/*/mame2003_plus
data/dat/emulatorjs/*/fbalpha2012_cps1
data/dat/emulatorjs/*/fbalpha2012_cps2
data/auth/password-blocklists/*/payload
key: retrom-dependencies-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('data/dat/**', 'data/auth/**', 'scripts/dependencies.py', 'scripts/fbalpha2012_dat.py', 'scripts/fbalpha2012-dat-enumerator.cpp') }}
- name: Prepare pinned runtime dependencies
run: make prepare-deps
- name: Check Go formatting, build, tests and lint
run: make backend-check
integration:
runs-on: ubuntu-latest
timeout-minutes: 45
env:
RETROM_TEST_DATABASE_URL: postgres://retrom:retrom-test@127.0.0.1:5432/postgres?sslmode=disable
services:
postgres:
image: postgres:18.3-bookworm@sha256:80630f83606d8db77d30b3851b16a9f78be2d0d4dda6f7b82a1fdca5ebe3acba
env:
POSTGRES_USER: retrom
POSTGRES_PASSWORD: retrom-test
POSTGRES_INITDB_ARGS: "-c max_connections=200"
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U retrom -d postgres"
--health-interval 2s --health-timeout 3s --health-retries 30
steps:
- name: Use runner disk for upload temporary storage
run: |
# Upload fixtures retain 10 GiB; avoid the size-limited /tmp tmpfs.
echo "TMPDIR=$RUNNER_TEMP" >> "$GITHUB_ENV"
df -h /tmp "$RUNNER_TEMP"
- name: Check out the repository
uses: actions/checkout@v6
- name: Set up Go
uses: actions/setup-go@v7
with:
go-version-file: go.mod
cache: true
cache-dependency-path: go.sum
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.13"
- name: Restore materialized runtime dependencies
uses: actions/cache/restore@v5
with:
path: |
data/runtime
data/dat/emulatorjs/*/fbneo
data/dat/emulatorjs/*/mame2003
data/dat/emulatorjs/*/mame2003_plus
data/dat/emulatorjs/*/fbalpha2012_cps1
data/dat/emulatorjs/*/fbalpha2012_cps2
data/auth/password-blocklists/*/payload
key: retrom-dependencies-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('data/dat/**', 'data/auth/**', 'scripts/dependencies.py', 'scripts/fbalpha2012_dat.py', 'scripts/fbalpha2012-dat-enumerator.cpp') }}
- name: Prepare pinned runtime dependencies
run: make prepare-deps
- name: Set up Node.js for runtime integration tests
uses: actions/setup-node@v6
with:
node-version-file: .node-version
package-manager-cache: false
- name: Restore verified Provider chunks
uses: actions/cache/restore@v5
with:
path: .cache/runtime-providers
key: retrom-provider-chunks-${{ runner.os }}-${{ hashFiles('data/runtime-inputs.json') }}
restore-keys: retrom-provider-chunks-${{ runner.os }}-
- name: Materialize repository-pinned runtime inputs
env:
RETROM_RUNTIME_INPUT_BASE_URL: ${{ vars.RETROM_RUNTIME_INPUT_BASE_URL }}
run: python3 scripts/prepare_image_inputs.py
- name: Run Go integration tests
run: make integration-test
web:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- name: Check out the repository
uses: actions/checkout@v6
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version-file: .node-version
cache: npm
cache-dependency-path: web/package-lock.json
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.13"
- name: Restore the repository Node.js toolchain
uses: actions/cache/restore@v5
with:
path: .cache/tools/node-v24.22.1-linux-x64
key: retrom-node-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.node-version', 'scripts/prepare-node.sh') }}
- name: Check Web styles, lint, types, tests and build
run: make web-check
- name: Upload Web duplication report
uses: actions/upload-artifact@v4
if: always()
with:
name: web-duplication
path: .artifacts/duplicates/web/
include-hidden-files: true
if-no-files-found: ignore
browser_ui:
name: browser-ui (${{ matrix.project }})
needs: changes
if: ${{ needs.changes.outputs.product == 'true' }}
runs-on: ubuntu-latest
timeout-minutes: 90
# Every Playwright viewport project runs completely in its own isolated job.
strategy:
fail-fast: false
matrix:
project: [chrome-1280, chrome-1440p, chrome-4k-150, chrome-mobile]
env:
RETROM_TEST_DATABASE_URL: postgres://retrom:retrom-test@127.0.0.1:5432/postgres?sslmode=disable
RETROM_E2E_PROJECT: ${{ matrix.project }}
services:
postgres:
image: postgres:18.3-bookworm@sha256:80630f83606d8db77d30b3851b16a9f78be2d0d4dda6f7b82a1fdca5ebe3acba
env:
POSTGRES_USER: retrom
POSTGRES_PASSWORD: retrom-test
POSTGRES_INITDB_ARGS: "-c max_connections=200"
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U retrom -d postgres"
--health-interval 2s --health-timeout 3s --health-retries 30
steps:
- name: Use runner disk for upload temporary storage
run: |
# Upload fixtures retain 10 GiB; avoid the size-limited /tmp tmpfs.
echo "TMPDIR=$RUNNER_TEMP" >> "$GITHUB_ENV"
df -h /tmp "$RUNNER_TEMP"
- name: Check out the repository
uses: actions/checkout@v6
- name: Set up Go
uses: actions/setup-go@v7
with:
go-version-file: go.mod
cache: true
cache-dependency-path: go.sum
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version-file: .node-version
cache: npm
cache-dependency-path: web/package-lock.json
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.13"
- name: Restore the repository Node.js toolchain
uses: actions/cache/restore@v5
with:
path: .cache/tools/node-v24.22.1-linux-x64
key: retrom-node-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.node-version', 'scripts/prepare-node.sh') }}
- name: Restore materialized runtime dependencies
uses: actions/cache/restore@v5
with:
path: |
data/runtime
data/dat/emulatorjs/*/fbneo
data/dat/emulatorjs/*/mame2003
data/dat/emulatorjs/*/mame2003_plus
data/dat/emulatorjs/*/fbalpha2012_cps1
data/dat/emulatorjs/*/fbalpha2012_cps2
data/auth/password-blocklists/*/payload
key: retrom-dependencies-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('data/dat/**', 'data/auth/**', 'scripts/dependencies.py', 'scripts/fbalpha2012_dat.py', 'scripts/fbalpha2012-dat-enumerator.cpp') }}
- name: Prepare pinned runtime dependencies
run: make prepare-deps
- name: Prepare fixed Latin and CJK fonts for browser checks
run: |
scripts/prepare-e2e-fonts.sh
echo "FONTCONFIG_FILE=$PWD/.cache/tools/e2e-fonts/fonts.conf" >> "$GITHUB_ENV"
- name: Restore verified Provider chunks
uses: actions/cache/restore@v5
with:
path: .cache/runtime-providers
key: retrom-provider-chunks-${{ runner.os }}-${{ hashFiles('data/runtime-inputs.json') }}
restore-keys: retrom-provider-chunks-${{ runner.os }}-
- name: Materialize repository-pinned runtime inputs
env:
RETROM_RUNTIME_INPUT_BASE_URL: ${{ vars.RETROM_RUNTIME_INPUT_BASE_URL }}
run: python3 scripts/prepare_image_inputs.py
- name: Prepare the development application before acceptance timing
# prepare-e2e-browser below installs the Web dependencies exactly once.
run: make build
- name: Verify UI consistency in the product browser
run: |
make prepare-e2e-browser
make acceptance-prepare
make acceptance-case CASE=ACC-RF-BROWSER
- name: Upload UI review evidence
if: always()
uses: actions/upload-artifact@v4
with:
name: ui-consistency-evidence-${{ matrix.project }}
path: .artifacts/acceptance/*/cases/acc-rf-browser/
include-hidden-files: true
if-no-files-found: ignore
retention-days: 14
pfb_gateway:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.13"
- name: Verify isolated PFB gateway routing
run: make pfb-gateway-test
quality:
runs-on: ubuntu-latest
needs: [changes, contracts, backend, integration, web, browser_ui, pfb_gateway]
if: ${{ always() }}
steps:
- name: Require every quality check to pass
env:
CHANGES_RESULT: ${{ needs.changes.result }}
PRODUCT_CHANGED: ${{ needs.changes.outputs.product }}
CONTRACTS_RESULT: ${{ needs.contracts.result }}
BACKEND_RESULT: ${{ needs.backend.result }}
INTEGRATION_RESULT: ${{ needs.integration.result }}
WEB_RESULT: ${{ needs.web.result }}
BROWSER_UI_RESULT: ${{ needs.browser_ui.result }}
PFB_GATEWAY_RESULT: ${{ needs.pfb_gateway.result }}
run: |
# Only a documentation-only change may skip the product browser.
if [[ "$PRODUCT_CHANGED" == false && "$BROWSER_UI_RESULT" == skipped ]]; then
BROWSER_UI_RESULT=success
fi
for result in "$CHANGES_RESULT" "$CONTRACTS_RESULT" "$BACKEND_RESULT" "$INTEGRATION_RESULT" "$WEB_RESULT" "$BROWSER_UI_RESULT" "$PFB_GATEWAY_RESULT"; do
if [[ "$result" != success ]]; then
echo "Quality check did not pass: $result" >&2
exit 1
fi
done