Skip to content

chore: regenerate Symfony config reference #338

chore: regenerate Symfony config reference

chore: regenerate Symfony config reference #338

Workflow file for this run

name: CI
on:
push:
branches: ["main", "v4"]
pull_request:
branches: ["**"]
permissions:
contents: read
jobs:
setup:
name: Setup Dependencies
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1
- name: Pull or build E2E image
run: |
# Try to pull pre-built image, fall back to building
docker pull ghcr.io/netresearch/timetracker:e2e || docker buildx bake app-e2e --load
- name: Prepare directories
run: |
mkdir -p vendor var/cache var/log bin node_modules public/build
chmod -R 777 vendor var bin node_modules public
- name: Install PHP dependencies
env:
COMPOSE_PROFILES: e2e
run: |
# --ignore-platform-req=php needed until laminas-ldap adds PHP 8.5 support
docker compose run --rm app-e2e composer install --no-interaction --prefer-dist --ignore-platform-req=php
- name: Install Node dependencies
env:
COMPOSE_PROFILES: e2e
run: |
docker compose run --rm app-e2e npm install --legacy-peer-deps
- name: Build frontend assets
env:
COMPOSE_PROFILES: e2e
run: |
docker compose run --rm app-e2e npm run build
- name: Upload dependencies artifact
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: dependencies
path: |
vendor/
bin/
node_modules/
public/build/
retention-days: 1
lint:
name: Lint & Static Analysis
runs-on: ubuntu-latest
timeout-minutes: 10
needs: setup
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1
- name: Pull E2E image
run: docker pull ghcr.io/netresearch/timetracker:e2e || docker buildx bake app-e2e --load
- name: Download dependencies
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: dependencies
- name: Prepare directories
run: |
mkdir -p var/cache var/log
chmod -R 777 var bin vendor
if [ ! -f phpstan.neon ] && [ -f phpstan.dist.neon ]; then cp phpstan.dist.neon phpstan.neon; fi
- name: Warmup Symfony cache
env:
COMPOSE_PROFILES: e2e
run: |
docker compose run --rm -e APP_ENV=dev app-e2e php bin/console cache:warmup --env=dev
- name: Validate composer.json
env:
COMPOSE_PROFILES: e2e
run: |
docker compose run --rm app-e2e composer validate --no-check-publish
- name: Composer audit (security)
env:
COMPOSE_PROFILES: e2e
run: |
docker compose run --rm app-e2e composer audit --format=plain
- name: Static analysis (PHPStan)
env:
COMPOSE_PROFILES: e2e
run: |
docker compose run --rm app-e2e php -d memory_limit=1G bin/phpstan analyze --no-progress
- name: Architecture analysis (PHPat)
env:
COMPOSE_PROFILES: e2e
run: |
docker compose run --rm app-e2e php -d memory_limit=1G bin/phpstan analyze config/quality/phpat.php --no-progress
- name: Code style (PHP-CS-Fixer)
env:
COMPOSE_PROFILES: e2e
run: |
docker compose run --rm app-e2e php -d memory_limit=512M bin/php-cs-fixer fix --dry-run --diff
- name: Rector (dry-run)
env:
COMPOSE_PROFILES: e2e
run: |
docker compose run --rm app-e2e php -d memory_limit=1G bin/rector process src --config=config/quality/rector.php --dry-run
- name: Lint Twig templates
env:
COMPOSE_PROFILES: e2e
run: |
docker compose run --rm -e XDEBUG_MODE=off app-e2e php bin/console lint:twig templates/
test-unit:
name: Unit Tests
runs-on: ubuntu-latest
timeout-minutes: 10
needs: setup
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1
- name: Pull E2E image
run: docker pull ghcr.io/netresearch/timetracker:e2e || docker buildx bake app-e2e --load
- name: Download dependencies
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: dependencies
- name: Prepare directories
run: |
mkdir -p var/cache var/log var/coverage
chmod -R 777 var bin vendor
if [ ! -f phpunit.xml ] && [ -f phpunit.xml.dist ]; then cp phpunit.xml.dist phpunit.xml; fi
- name: Warmup Symfony cache
env:
COMPOSE_PROFILES: e2e
run: |
docker compose run --rm -e APP_ENV=test app-e2e php bin/console cache:warmup --env=test
- name: Run unit tests with coverage
env:
COMPOSE_PROFILES: e2e
run: |
docker compose run --rm -e APP_ENV=test -e XDEBUG_MODE=coverage app-e2e \
php -d memory_limit=1G bin/phpunit --testsuite unit --coverage-clover var/coverage/unit.xml
- name: Upload unit coverage to Codecov
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: var/coverage/unit.xml
flags: unit
fail_ci_if_error: false
verbose: true
test-integration:
name: Integration Tests
runs-on: ubuntu-latest
timeout-minutes: 15
needs: setup
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1
- name: Pull E2E image
run: docker pull ghcr.io/netresearch/timetracker:e2e || docker buildx bake app-e2e --load
- name: Download dependencies
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: dependencies
- name: Prepare config files and SQL
run: |
mkdir -p var/cache var/log var/coverage
chmod -R 777 var bin vendor
if [ ! -f phpunit.xml ] && [ -f phpunit.xml.dist ]; then cp phpunit.xml.dist phpunit.xml; fi
sed '1s/^/USE unittest;\\n/' sql/full.sql > sql/unittest/001_testtables.sql
- name: Warmup Symfony cache
env:
COMPOSE_PROFILES: e2e
run: |
docker compose run --rm -e APP_ENV=test app-e2e php bin/console cache:warmup --env=test
- name: Start test database
env:
COMPOSE_PROFILES: e2e
run: |
docker compose up -d db_unittest
docker compose exec -T db_unittest mariadb-admin ping -h 127.0.0.1 -uroot -pglobal123 --wait --connect-timeout=60
- name: Run integration tests with coverage
env:
COMPOSE_PROFILES: e2e
run: |
docker compose run --rm -e APP_ENV=test -e XDEBUG_MODE=coverage app-e2e \
php -d memory_limit=2G bin/phpunit --testsuite integration,controller,api-contract,api-functional --coverage-clover var/coverage/integration.xml
- name: Upload integration coverage to Codecov
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: var/coverage/integration.xml
flags: integration
fail_ci_if_error: false
verbose: true
- name: Stop database
if: always()
run: docker compose down
e2e:
name: E2E Tests (${{ matrix.shard }}/${{ strategy.job-total }})
runs-on: ubuntu-latest
timeout-minutes: 15
needs: setup
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1
- name: Pull E2E image
run: docker pull ghcr.io/netresearch/timetracker:e2e || docker buildx bake app-e2e --load
- name: Download dependencies
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: dependencies
- name: Prepare directories
run: |
mkdir -p var/cache var/log var/coverage/e2e playwright-report test-results
chmod -R 777 var bin vendor node_modules public playwright-report test-results
- name: Reinstall npm binaries
env:
COMPOSE_PROFILES: e2e
run: |
# Artifact download doesn't preserve npm binary symlinks, reinstall to fix
docker compose run --rm app-e2e npm install --legacy-peer-deps
- name: Start E2E stack with coverage
env:
COMPOSE_PROFILES: e2e
COVERAGE_ENABLED: '1'
XDEBUG_MODE: coverage
run: |
docker compose up -d
# Wait for database
docker compose exec -T db-e2e mariadb-admin ping -h 127.0.0.1 -uroot -pglobal123 --wait --connect-timeout=60
# Clear and warmup Symfony cache for test environment
docker compose exec -T app-e2e php bin/console cache:clear --env=test || true
docker compose exec -T app-e2e php bin/console cache:warmup --env=test || true
# Wait for app to be ready
echo "Waiting for app to be ready..."
for i in {1..30}; do
HTTP_CODE=$(curl -s -o /tmp/response.html -w "%{http_code}" http://localhost:8766/login 2>&1)
if [ "$HTTP_CODE" = "200" ]; then
echo "App is ready after $i attempts (HTTP $HTTP_CODE)"
break
fi
if [ $i -eq 30 ]; then
echo "App failed to start within timeout (last HTTP code: $HTTP_CODE)"
echo "=== Last response body ==="
cat /tmp/response.html 2>/dev/null | head -100 || true
echo "=== PHP-FPM logs ==="
docker compose logs app-e2e | tail -50
echo "=== Nginx logs ==="
docker compose logs httpd-e2e | tail -20
exit 1
fi
echo "Attempt $i: HTTP $HTTP_CODE, waiting..."
sleep 3
done
# Verify coverage is enabled
curl -s http://localhost:8766/coverage.php?action=status || echo "Coverage endpoint not responding"
- name: Run E2E tests (shard ${{ matrix.shard }}/10)
env:
COMPOSE_PROFILES: e2e
run: |
docker compose run --rm \
-e E2E_BASE_URL=http://httpd-e2e:80 \
-e CI=true \
app-e2e npx playwright test --shard=${{ matrix.shard }}/10 -x
- name: Collect E2E coverage
if: always()
run: |
curl -s "http://localhost:8766/coverage.php?action=report&format=clover" > var/coverage/e2e-clover-${{ matrix.shard }}.xml || true
if [ -s var/coverage/e2e-clover-${{ matrix.shard }}.xml ]; then
echo "E2E coverage collected successfully for shard ${{ matrix.shard }}"
else
echo "No E2E coverage data collected for shard ${{ matrix.shard }}"
fi
- name: Upload E2E coverage to Codecov
if: always()
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: var/coverage/e2e-clover-${{ matrix.shard }}.xml
flags: e2e
fail_ci_if_error: false
verbose: true
- name: Upload test artifacts
if: failure()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: e2e-artifacts-shard-${{ matrix.shard }}
path: |
playwright-report/
test-results/
var/coverage/
retention-days: 7
- name: Stop E2E stack
if: always()
env:
COMPOSE_PROFILES: e2e
run: docker compose down