Files
XC_VM/.github/workflows/ci.yml
T
Divarion-D baf6c8e231 build: ship a production-only vendor; install dev tools via Composer
Switch from "commit vendor with dev deps + strip at release" to the standard
application model: the committed src/vendor/ is PRODUCTION-ONLY, and dev tooling
(PHPStan, PHP-CS-Fixer + ~37 transitive deps) is installed on demand with
"composer install".

- Regenerate the committed src/vendor/ via "composer install --no-dev"
  (34 MB -> ~0.5 MB; only the Composer autoloader + gemorroj/m3u-parser +
  chrisyue/php-m3u8 remain). This also stops PHPStan\PharAutoloader registering
  in production.
- Commit src/composer.lock (un-ignored) — this is an application, so the lock is
  committed to make "composer install" reproducible across dev/CI.
- Revert the release-time strip step (Makefile hooks + tools/build/
  strip-dev-vendor.sh) — no longer needed; the archive ships the prod vendor as-is.
- CI: the phpstan and code-style jobs now run "composer install --working-dir=src"
  (with tools: composer) to obtain the dev tools before running.
- New gate tools/ci/check-vendor-prod-only.sh (+ make check-vendor-prod-only,
  wired into "make gates"): asserts no require-dev package from composer.lock is
  committed under src/vendor/ — guards against accidentally committing a
  dev-bloated vendor. Inspects git-tracked files, so it is correct even in a CI
  job that already ran "composer install".
- Fix verify-lb-archive.sh: LB legitimately ships most of Cli/Commands and
  Cli/CronJobs (edge commands + certbot/cache/cleanup crons), so flag only the
  genuinely privileged dirs + the specific install/root files, not the whole dirs.
- .gitignore / composer.json notes updated.

Verified before pruning: PHPStan no errors, PHPUnit 303, cs + gates green. After
pruning: PHPUnit 303 (prod-only vendor), all three gates green. Local dev tools
restored afterwards with "composer install" (not committed).
2026-06-25 21:51:13 +03:00

162 lines
4.8 KiB
YAML

name: CI
# Quality gate: runs on every push and pull request.
# Tests run via the committed PHAR (tools/.bin/phpunit.phar). Class loading uses
# the committed Composer PSR-4 autoloader (src/vendor/) first, with the legacy
# src/autoload.php scanner as an end-of-queue fallback. The deploy path ships
# vendor/ as-is and never runs `composer install`.
on:
push:
branches: ['**']
pull_request:
permissions:
contents: read
jobs:
lint:
name: PHP Syntax Check
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
coverage: none
- name: Check syntax
run: bash tools/php_syntax_check.sh
phpstan:
name: PHPStan (static analysis)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
# Matches phpVersion (80300) the analysis targets.
php-version: '8.3'
coverage: none
tools: composer:v2
# The committed src/vendor/ is production-only; PHPStan is a require-dev
# tool, so install it here (from the committed lock — reproducible).
- name: Install dev dependencies
run: composer install --no-interaction --working-dir=src
# Analyses against the committed baseline — fails only on NEW issues.
- name: Run PHPStan
run: make phpstan
code-style:
name: Code Style (PHP-CS-Fixer)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
coverage: none
tools: composer:v2
# PHP-CS-Fixer is a require-dev tool; the committed src/vendor/ is
# production-only, so install it here (from the committed lock).
- name: Install dev dependencies
run: composer install --no-interaction --working-dir=src
# Narrow ruleset: import / namespace hygiene only (see .php-cs-fixer.dist.php).
# Dry-run fails on diff.
- name: Run PHP-CS-Fixer
run: make cs
psr4-gates:
name: PSR-4 Regression Gates
runs-on: ubuntu-latest
steps:
- name: Checkout
# Full history not needed, but git ls-files requires the working tree.
uses: actions/checkout@v7
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
coverage: none
# check-procedural-use: procedural/view files must import every migrated
# class they use (top-of-file `use`; PHP imports are positional).
# verify-lb-archive: the LoadBalancer archive must exclude privileged code
# (security blocker 1 — silent rm misses after the PascalCase rename).
- name: Run PSR-4 gates
run: make gates
composer-audit:
name: Composer Security Audit
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
coverage: none
tools: composer:v2
# Audits the committed install set (src/vendor/composer/installed.json)
# against the Packagist advisory database. Does NOT run `composer install`
# (vendor/ is committed and shipped) and does NOT use --locked
# (composer.lock is gitignored, never committed). A no-op while every
# dependency is path-mapped/vendored without metadata, but gates real
# installed packages the moment any are added.
- name: Composer audit
run: |
count=$(php -r '$f="src/vendor/composer/installed.json";$d=is_file($f)?json_decode(file_get_contents($f),true):[];echo is_array($d["packages"]??null)?count($d["packages"]):0;')
if [ "$count" -eq 0 ]; then
echo "No installed Composer packages — nothing to audit."
else
composer audit --no-interaction --working-dir=src
fi
test:
name: PHPUnit
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
coverage: pcov
- name: Run unit tests
run: php tools/.bin/phpunit.phar -c tests/phpunit.xml.dist
- name: Coverage report
run: |
php tools/.bin/phpunit.phar -c tests/phpunit.xml.dist \
--coverage-text \
--coverage-clover coverage.xml
continue-on-error: true
- name: Upload coverage artifact
if: always()
uses: actions/upload-artifact@v7
with:
name: coverage
path: coverage.xml
if-no-files-found: ignore