524 lines
10 KiB
Markdown
524 lines
10 KiB
Markdown
# CI/CD Integration for TYPO3 Testing
|
|
|
|
Continuous Integration and Continuous Deployment workflows for automated TYPO3 extension testing.
|
|
|
|
## GitHub Actions
|
|
|
|
### Basic Workflow
|
|
|
|
Create `.github/workflows/tests.yml`:
|
|
|
|
```yaml
|
|
name: Tests
|
|
|
|
on:
|
|
push:
|
|
branches: [ main, develop ]
|
|
pull_request:
|
|
branches: [ main ]
|
|
|
|
jobs:
|
|
lint:
|
|
name: Lint PHP
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup PHP
|
|
uses: shivammathur/setup-php@v2
|
|
with:
|
|
php-version: '8.4'
|
|
|
|
- name: Install dependencies
|
|
run: composer install --no-progress
|
|
|
|
- name: Run linting
|
|
run: composer ci:test:php:lint
|
|
|
|
phpstan:
|
|
name: PHPStan
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup PHP
|
|
uses: shivammathur/setup-php@v2
|
|
with:
|
|
php-version: '8.4'
|
|
|
|
- name: Install dependencies
|
|
run: composer install --no-progress
|
|
|
|
- name: Run PHPStan
|
|
run: composer ci:test:php:phpstan
|
|
|
|
unit:
|
|
name: Unit Tests
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
matrix:
|
|
php: ['8.1', '8.2', '8.3', '8.4']
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup PHP ${{ matrix.php }}
|
|
uses: shivammathur/setup-php@v2
|
|
with:
|
|
php-version: ${{ matrix.php }}
|
|
coverage: xdebug
|
|
|
|
- name: Install dependencies
|
|
run: composer install --no-progress
|
|
|
|
- name: Run unit tests
|
|
run: composer ci:test:php:unit
|
|
|
|
- name: Upload coverage
|
|
# Upload coverage for all PHP versions
|
|
uses: codecov/codecov-action@v3
|
|
|
|
functional:
|
|
name: Functional Tests
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
matrix:
|
|
php: ['8.1', '8.2', '8.3', '8.4']
|
|
database: ['mysqli', 'pdo_mysql', 'postgres', 'sqlite']
|
|
|
|
services:
|
|
mysql:
|
|
image: mysql:8.0
|
|
env:
|
|
MYSQL_ROOT_PASSWORD: root
|
|
MYSQL_DATABASE: typo3_test
|
|
ports:
|
|
- 3306:3306
|
|
options: >-
|
|
--health-cmd="mysqladmin ping"
|
|
--health-interval=10s
|
|
--health-timeout=5s
|
|
--health-retries=3
|
|
|
|
postgres:
|
|
image: postgres:15
|
|
env:
|
|
POSTGRES_PASSWORD: postgres
|
|
POSTGRES_DB: typo3_test
|
|
ports:
|
|
- 5432:5432
|
|
options: >-
|
|
--health-cmd pg_isready
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup PHP ${{ matrix.php }}
|
|
uses: shivammathur/setup-php@v2
|
|
with:
|
|
php-version: ${{ matrix.php }}
|
|
extensions: ${{ matrix.database == 'postgres' && 'pdo_pgsql' || 'mysqli' }}
|
|
|
|
- name: Install dependencies
|
|
run: composer install --no-progress
|
|
|
|
- name: Run functional tests
|
|
run: |
|
|
export typo3DatabaseDriver=${{ matrix.database }}
|
|
export typo3DatabaseHost=127.0.0.1
|
|
export typo3DatabaseName=typo3_test
|
|
export typo3DatabaseUsername=${{ matrix.database == 'postgres' && 'postgres' || 'root' }}
|
|
export typo3DatabasePassword=${{ matrix.database == 'postgres' && 'postgres' || 'root' }}
|
|
composer ci:test:php:functional
|
|
```
|
|
|
|
### Matrix Strategy
|
|
|
|
Test multiple PHP and TYPO3 versions:
|
|
|
|
```yaml
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
php: ['8.1', '8.2', '8.3', '8.4']
|
|
typo3: ['12.4', '13.0']
|
|
exclude:
|
|
- php: '8.1'
|
|
typo3: '13.0' # TYPO3 v13 requires PHP 8.2+
|
|
|
|
steps:
|
|
- name: Install TYPO3 v${{ matrix.typo3 }}
|
|
run: |
|
|
composer require "typo3/cms-core:^${{ matrix.typo3 }}" --no-update
|
|
composer update --no-progress
|
|
```
|
|
|
|
### Caching Dependencies
|
|
|
|
```yaml
|
|
- name: Cache Composer dependencies
|
|
uses: actions/cache@v3
|
|
with:
|
|
path: ~/.composer/cache
|
|
key: composer-${{ runner.os }}-${{ matrix.php }}-${{ hashFiles('composer.lock') }}
|
|
restore-keys: |
|
|
composer-${{ runner.os }}-${{ matrix.php }}-
|
|
composer-${{ runner.os }}-
|
|
|
|
- name: Install dependencies
|
|
run: composer install --no-progress --prefer-dist
|
|
```
|
|
|
|
### Code Coverage
|
|
|
|
```yaml
|
|
- name: Run tests with coverage
|
|
run: vendor/bin/phpunit -c Build/phpunit/UnitTests.xml --coverage-clover coverage.xml
|
|
|
|
- name: Upload coverage to Codecov
|
|
uses: codecov/codecov-action@v3
|
|
with:
|
|
file: ./coverage.xml
|
|
flags: unittests
|
|
name: codecov-umbrella
|
|
```
|
|
|
|
## GitLab CI
|
|
|
|
### Basic Pipeline
|
|
|
|
Create `.gitlab-ci.yml`:
|
|
|
|
```yaml
|
|
variables:
|
|
COMPOSER_CACHE_DIR: ".composer-cache"
|
|
MYSQL_ROOT_PASSWORD: "root"
|
|
MYSQL_DATABASE: "typo3_test"
|
|
|
|
cache:
|
|
key: "$CI_COMMIT_REF_SLUG"
|
|
paths:
|
|
- .composer-cache/
|
|
|
|
stages:
|
|
- lint
|
|
- analyze
|
|
- test
|
|
|
|
.php:
|
|
image: php:${PHP_VERSION}-cli
|
|
before_script:
|
|
- apt-get update && apt-get install -y git zip unzip
|
|
- curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
|
- composer install --no-progress
|
|
|
|
lint:
|
|
extends: .php
|
|
stage: lint
|
|
variables:
|
|
PHP_VERSION: "8.2"
|
|
script:
|
|
- composer ci:test:php:lint
|
|
|
|
phpstan:
|
|
extends: .php
|
|
stage: analyze
|
|
variables:
|
|
PHP_VERSION: "8.2"
|
|
script:
|
|
- composer ci:test:php:phpstan
|
|
|
|
cgl:
|
|
extends: .php
|
|
stage: analyze
|
|
variables:
|
|
PHP_VERSION: "8.2"
|
|
script:
|
|
- composer ci:test:php:cgl
|
|
|
|
unit:8.1:
|
|
extends: .php
|
|
stage: test
|
|
variables:
|
|
PHP_VERSION: "8.1"
|
|
script:
|
|
- composer ci:test:php:unit
|
|
|
|
unit:8.2:
|
|
extends: .php
|
|
stage: test
|
|
variables:
|
|
PHP_VERSION: "8.2"
|
|
script:
|
|
- composer ci:test:php:unit
|
|
coverage: '/^\s*Lines:\s*\d+.\d+\%/'
|
|
artifacts:
|
|
reports:
|
|
coverage_report:
|
|
coverage_format: cobertura
|
|
path: coverage.xml
|
|
|
|
functional:8.2:
|
|
extends: .php
|
|
stage: test
|
|
variables:
|
|
PHP_VERSION: "8.2"
|
|
typo3DatabaseDriver: "mysqli"
|
|
typo3DatabaseHost: "mysql"
|
|
typo3DatabaseName: "typo3_test"
|
|
typo3DatabaseUsername: "root"
|
|
typo3DatabasePassword: "root"
|
|
services:
|
|
- mysql:8.0
|
|
script:
|
|
- composer ci:test:php:functional
|
|
```
|
|
|
|
### Multi-Database Testing
|
|
|
|
```yaml
|
|
.functional:
|
|
extends: .php
|
|
stage: test
|
|
variables:
|
|
PHP_VERSION: "8.2"
|
|
script:
|
|
- composer ci:test:php:functional
|
|
|
|
functional:mysql:
|
|
extends: .functional
|
|
variables:
|
|
typo3DatabaseDriver: "mysqli"
|
|
typo3DatabaseHost: "mysql"
|
|
typo3DatabaseName: "typo3_test"
|
|
typo3DatabaseUsername: "root"
|
|
typo3DatabasePassword: "root"
|
|
services:
|
|
- mysql:8.0
|
|
|
|
functional:postgres:
|
|
extends: .functional
|
|
variables:
|
|
typo3DatabaseDriver: "pdo_pgsql"
|
|
typo3DatabaseHost: "postgres"
|
|
typo3DatabaseName: "typo3_test"
|
|
typo3DatabaseUsername: "postgres"
|
|
typo3DatabasePassword: "postgres"
|
|
services:
|
|
- postgres:15
|
|
before_script:
|
|
- apt-get update && apt-get install -y libpq-dev
|
|
- docker-php-ext-install pdo_pgsql
|
|
|
|
functional:sqlite:
|
|
extends: .functional
|
|
variables:
|
|
typo3DatabaseDriver: "pdo_sqlite"
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
### 1. Fast Feedback Loop
|
|
|
|
Order jobs by execution time (fastest first):
|
|
|
|
```yaml
|
|
stages:
|
|
- lint # ~30 seconds
|
|
- analyze # ~1-2 minutes (PHPStan, CGL)
|
|
- unit # ~2-5 minutes
|
|
- functional # ~5-15 minutes
|
|
- acceptance # ~15-30 minutes
|
|
```
|
|
|
|
### 2. Fail Fast
|
|
|
|
```yaml
|
|
strategy:
|
|
fail-fast: true # Stop on first failure
|
|
matrix:
|
|
php: ['8.1', '8.2', '8.3', '8.4']
|
|
```
|
|
|
|
### 3. Parallel Execution
|
|
|
|
```yaml
|
|
# GitHub Actions - parallel jobs
|
|
jobs:
|
|
lint: ...
|
|
phpstan: ...
|
|
unit: ...
|
|
# All run in parallel
|
|
|
|
# GitLab CI - parallel jobs
|
|
test:
|
|
parallel:
|
|
matrix:
|
|
- PHP_VERSION: ['8.1', '8.2', '8.3']
|
|
```
|
|
|
|
### 4. Cache Dependencies
|
|
|
|
GitHub Actions:
|
|
```yaml
|
|
- uses: actions/cache@v3
|
|
with:
|
|
path: ~/.composer/cache
|
|
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
|
```
|
|
|
|
GitLab CI:
|
|
```yaml
|
|
cache:
|
|
key: ${CI_COMMIT_REF_SLUG}
|
|
paths:
|
|
- .composer-cache/
|
|
```
|
|
|
|
### 5. Matrix Testing
|
|
|
|
Test critical combinations:
|
|
|
|
```yaml
|
|
strategy:
|
|
matrix:
|
|
include:
|
|
# Minimum supported versions
|
|
- php: '8.1'
|
|
typo3: '12.4'
|
|
|
|
# Current stable
|
|
- php: '8.2'
|
|
typo3: '12.4'
|
|
|
|
# Latest versions
|
|
- php: '8.3'
|
|
typo3: '13.0'
|
|
```
|
|
|
|
### 6. Artifacts and Reports
|
|
|
|
```yaml
|
|
- name: Archive test results
|
|
if: failure()
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: test-results
|
|
path: |
|
|
var/log/
|
|
typo3temp/var/tests/
|
|
```
|
|
|
|
### 7. Notifications
|
|
|
|
GitHub Actions:
|
|
```yaml
|
|
- name: Slack Notification
|
|
if: failure()
|
|
uses: rtCamp/action-slack-notify@v2
|
|
env:
|
|
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
|
```
|
|
|
|
## Quality Gates
|
|
|
|
### Required Checks
|
|
|
|
Define which checks must pass:
|
|
|
|
GitHub:
|
|
```yaml
|
|
# .github/branch-protection.json
|
|
{
|
|
"required_status_checks": {
|
|
"strict": true,
|
|
"contexts": [
|
|
"lint",
|
|
"phpstan",
|
|
"unit (8.2)",
|
|
"functional (8.2, mysqli)"
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
GitLab:
|
|
```yaml
|
|
# .gitlab-ci.yml
|
|
unit:8.2:
|
|
only:
|
|
- merge_requests
|
|
allow_failure: false # Required check
|
|
```
|
|
|
|
### Coverage Requirements
|
|
|
|
```yaml
|
|
- name: Check code coverage
|
|
run: |
|
|
coverage=$(vendor/bin/phpunit --coverage-text | grep "Lines:" | awk '{print $2}' | sed 's/%//')
|
|
if (( $(echo "$coverage < 80" | bc -l) )); then
|
|
echo "Coverage $coverage% is below 80%"
|
|
exit 1
|
|
fi
|
|
```
|
|
|
|
## Environment-Specific Configuration
|
|
|
|
### Development Branch
|
|
|
|
```yaml
|
|
on:
|
|
push:
|
|
branches: [ develop ]
|
|
|
|
# Run all checks, allow failures
|
|
jobs:
|
|
experimental:
|
|
continue-on-error: true
|
|
strategy:
|
|
matrix:
|
|
php: ['8.4'] # Experimental PHP version
|
|
```
|
|
|
|
### Production Branch
|
|
|
|
```yaml
|
|
on:
|
|
push:
|
|
branches: [ main ]
|
|
|
|
# Strict checks only
|
|
jobs:
|
|
tests:
|
|
strategy:
|
|
fail-fast: true
|
|
matrix:
|
|
php: ['8.2'] # LTS version only
|
|
```
|
|
|
|
### Pull Requests
|
|
|
|
```yaml
|
|
on:
|
|
pull_request:
|
|
|
|
# Full test matrix
|
|
jobs:
|
|
tests:
|
|
strategy:
|
|
matrix:
|
|
php: ['8.1', '8.2', '8.3', '8.4']
|
|
database: ['mysqli', 'postgres']
|
|
```
|
|
|
|
## Resources
|
|
|
|
- [GitHub Actions Documentation](https://docs.github.com/actions)
|
|
- [GitLab CI Documentation](https://docs.gitlab.com/ee/ci/)
|
|
- [TYPO3 Tea Extension CI](https://github.com/TYPO3BestPractices/tea/tree/main/.github/workflows)
|
|
- [shivammathur/setup-php](https://github.com/shivammathur/setup-php)
|