Skip to content

chore(main): release 0.1.6 #71

chore(main): release 0.1.6

chore(main): release 0.1.6 #71

name: arch-invariants
on:
push:
branches: [main]
pull_request:
concurrency:
group: arch-invariants-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
invariants:
name: grep-based banned patterns
runs-on: ubuntu-24.04
timeout-minutes: 5
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: no phaser imports in domain/
run: |
if grep -rnE "from ['\"]phaser" src/domain 2>/dev/null; then
echo "::error::phaser imports found in src/domain/ — domain must be engine-agnostic."
exit 1
fi
- name: no Math.random in domain/
run: |
if grep -rn "Math\.random" src/domain 2>/dev/null; then
echo "::error::Math.random found in src/domain/ — inject IRandomPort."
exit 1
fi
- name: no Date.now or new Date in domain/
run: |
if grep -rnE "Date\.now|new Date\(" src/domain 2>/dev/null; then
echo "::error::Date access found in src/domain/ — inject ITimePort."
exit 1
fi
- name: no localStorage in domain/
run: |
if grep -rn "localStorage\|sessionStorage" src/domain 2>/dev/null; then
echo "::error::Storage access found in src/domain/ — use ISaveGamePort."
exit 1
fi
- name: no ignoreDestroy in runtime/
run: |
if grep -rnE "ignoreDestroy[[:space:]]*=[[:space:]]*true" src/runtime src/app 2>/dev/null; then
echo "::error::ignoreDestroy = true found — Scene/Group destroy will skip the object. (tsforge/no-ignore-destroy)"
exit 1
fi
- name: no runtime imports in domain/
run: |
if grep -rnE "from ['\"]@runtime|from ['\"]\.+/runtime" src/domain 2>/dev/null; then
echo "::error::Runtime import found in src/domain/ — domain must not depend on runtime."
exit 1
fi