diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml deleted file mode 100644 index ace4871..0000000 --- a/.github/workflows/nightly.yml +++ /dev/null @@ -1,112 +0,0 @@ -name: Nightly Tests - -on: - schedule: - # Run at 2 AM UTC every day - - cron: '0 2 * * *' - workflow_dispatch: - -jobs: - nightly-matrix: - name: Nightly Matrix Test - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - php-version: ['8.2', '8.3'] - dependencies: ['lowest', 'locked', 'highest'] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv - coverage: xdebug - tools: composer:v2 - - - name: Install dependencies (${{ matrix.dependencies }}) - run: | - if [ "${{ matrix.dependencies }}" = "lowest" ]; then - composer update --prefer-lowest --prefer-dist --no-progress --no-suggest - elif [ "${{ matrix.dependencies }}" = "highest" ]; then - composer update --prefer-dist --no-progress --no-suggest - else - composer install --prefer-dist --no-progress --no-suggest - fi - - - name: Run PHPUnit Tests - run: XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-text - - - name: Run Behat Tests - run: ./vendor/bin/behat --format=progress - - - name: Check Coverage - run: php bin/check-coverage.php - - dependency-security: - name: Security & Dependency Check - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.2' - tools: composer:v2 - - - name: Install dependencies - run: composer install --prefer-dist --no-progress - - - name: Security audit - run: composer audit - - - name: Check for outdated dependencies - run: composer outdated --direct - - notify-on-failure: - name: Notify on Failure - runs-on: ubuntu-latest - needs: [nightly-matrix, dependency-security] - if: failure() - - steps: - - name: Create Issue on Failure - uses: actions/github-script@v6 - with: - script: | - const issue = await github.rest.issues.create({ - owner: context.repo.owner, - repo: context.repo.repo, - title: '๐Ÿšจ Nightly Tests Failed - ' + new Date().toISOString().split('T')[0], - body: ` - ## Nightly Test Failure Report - - The nightly tests have failed. Please investigate the following: - - **Failed Run:** ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - - **Timestamp:** ${new Date().toISOString()} - - **Possible Causes:** - - Dependency version conflicts - - Security vulnerabilities in dependencies - - Breaking changes in dependencies - - Infrastructure issues - - **Action Required:** - Please review the failed workflow and address any issues found. - - This issue was automatically created by the nightly test workflow. - `, - labels: ['bug', 'nightly-failure', 'automated'] - }); - - console.log('Created issue:', issue.data.number); diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index a003240..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,115 +0,0 @@ -name: Release Pipeline - -on: - push: - tags: - - 'v*' - release: - types: [published] - -jobs: - comprehensive-test: - name: Comprehensive Testing (Release) - runs-on: ubuntu-latest - - strategy: - matrix: - php-version: ['8.2', '8.3'] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv - coverage: xdebug - tools: composer:v2 - - - name: Install Composer dependencies - run: composer install --prefer-dist --no-progress --no-suggest --optimize-autoloader --no-dev - - - name: Install dev dependencies for testing - run: composer install --prefer-dist --no-progress --no-suggest --optimize-autoloader - - - name: Validate composer files - run: composer validate --strict - - - name: Security audit - run: composer audit - - - name: Run PHPUnit with Coverage - run: XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-clover coverage/clover.xml --coverage-text - - - name: Run Behat Tests - run: ./vendor/bin/behat --format=progress --strict - - - name: Verify 100% Code Coverage (Critical for Release) - run: php bin/check-coverage.php - - - name: Test production autoloader - run: | - composer install --no-dev --optimize-autoloader - php -r "require 'vendor/autoload.php'; echo 'Autoloader OK' . PHP_EOL;" - - package-integrity: - name: Package Integrity Check - runs-on: ubuntu-latest - needs: comprehensive-test - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.2' - tools: composer:v2 - - - name: Create distribution package - run: | - # Create a clean copy without dev dependencies - mkdir -p dist - cp -r src dist/ - cp composer.json dist/ - cp composer.lock dist/ - cp README.md dist/ - cp LICENSE dist/ 2>/dev/null || echo "No LICENSE file found" - - - name: Test package installation - run: | - cd dist - composer install --no-dev --optimize-autoloader - php -r " - require 'vendor/autoload.php'; - if (class_exists('GryfOSS\\\\Mvc\\\\Normalizer\\\\DefaultViewModelNormalizer')) { - echo 'โœ… Package classes loadable' . PHP_EOL; - } else { - echo 'โŒ Package classes not loadable' . PHP_EOL; - exit(1); - } - " - - - name: Archive distribution package - uses: actions/upload-artifact@v4 - with: - name: distribution-package - path: dist/ - retention-days: 90 - - release-validation: - name: Release Validation - runs-on: ubuntu-latest - needs: [comprehensive-test, package-integrity] - if: github.event_name == 'release' - - steps: - - name: Validate Release - run: | - echo "โœ… All release checks passed!" - echo "Tag: ${{ github.ref_name }}" - echo "Release: ${{ github.event.release.tag_name }}" - echo "Package is ready for distribution" diff --git a/.github/workflows/ci.yml b/.github/workflows/tests.yml similarity index 99% rename from .github/workflows/ci.yml rename to .github/workflows/tests.yml index fe6b68e..f1407f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/tests.yml @@ -1,4 +1,4 @@ -name: CI Pipeline +name: Tests on: push: diff --git a/CI-CD.md b/CI-CD.md deleted file mode 100644 index d276f26..0000000 --- a/CI-CD.md +++ /dev/null @@ -1,155 +0,0 @@ -# CI/CD Pipeline Documentation - -This project uses GitHub Actions for comprehensive continuous integration and deployment pipelines. - -## ๐Ÿš€ Workflows Overview - -### 1. **CI Pipeline** (`.github/workflows/ci.yml`) - -**Triggers:** Push to `main`, `develop`, `tests` branches and all pull requests - -**Jobs:** -- **Test Suite**: Runs on PHP 8.2 and 8.3 - - PHPUnit tests with 100% coverage verification - - Behat acceptance tests - - Composer validation and security audit - - Local coverage report generation -- **Code Quality**: Linting and static analysis -- **Matrix Check**: Ensures all matrix jobs pass - -### 2. **Release Pipeline** (`.github/workflows/release.yml`) - -**Triggers:** Version tags (`v*`) and GitHub releases - -**Features:** -- Comprehensive testing across PHP versions -- Package integrity verification -- Production autoloader testing -- Critical 100% coverage enforcement -- Distribution package creation - -### 3. **Nightly Tests** (`.github/workflows/nightly.yml`) - -**Triggers:** Daily at 2 AM UTC and manual dispatch - -**Features:** -- Tests with lowest, locked, and highest dependencies -- Security vulnerability scanning -- Automatic issue creation on failure -- Dependency freshness monitoring - -## ๐Ÿงช Local Testing - -### Quick Test Run -```bash -# Run all tests locally -./bin/run-ci-tests.sh -``` - -### Individual Test Suites -```bash -# PHPUnit with coverage -XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-text - -# Behat acceptance tests -./vendor/bin/behat - -# Coverage verification -php bin/check-coverage.php - -# Get coverage percentage for badges -php bin/coverage-badge.php -``` - -## ๐Ÿ“Š Coverage Requirements - -- **Minimum Coverage**: 100% line coverage required -- **Coverage Types**: Lines, Methods, and Classes tracked -- **Verification**: Automated enforcement in all pipelines -- **Reports**: HTML reports generated in `coverage/html/` - -## ๐Ÿ”ง Scripts - -### `bin/run-ci-tests.sh` -Comprehensive test runner that mimics CI environment: -- Validates composer files -- Runs security audit -- Executes PHPUnit with coverage -- Runs Behat tests -- Verifies 100% coverage -- Colorized output with status indicators - -### `bin/check-coverage.php` -Coverage verification script: -- Runs PHPUnit with coverage -- Extracts coverage percentage -- Exits with error if not 100% -- Used by CI for quality gates - -### `bin/coverage-badge.php` -Badge-friendly coverage reporter: -- Outputs just the coverage percentage -- Used for generating coverage badges -- Silent operation for automation - -## ๐Ÿท๏ธ Badges - -Add these badges to your README: - -```markdown -![CI](https://github.com/praetoriantechnology/mvc-vm-normalizer/workflows/CI%20Pipeline/badge.svg) -![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen) -![PHP](https://img.shields.io/badge/php-8.2%20%7C%208.3-blue) -``` - -## ๐Ÿšจ Quality Gates - -All pipelines enforce these quality gates: - -1. **โœ… Code Syntax**: PHP syntax validation -2. **โœ… Composer Validation**: Valid and secure composer files -3. **โœ… Security Audit**: No known vulnerabilities -4. **โœ… Unit Tests**: All PHPUnit tests pass -5. **โœ… Integration Tests**: All Behat scenarios pass -6. **โœ… 100% Coverage**: Line coverage must be exactly 100% -7. **โœ… Package Integrity**: Production package loads correctly - -## ๐Ÿ”„ Workflow Status - -### Matrix Testing -- **PHP Versions**: 8.2, 8.3 -- **Dependencies**: lowest, locked, highest (nightly) -- **Operating System**: Ubuntu Latest - -### Failure Handling -- **Nightly failures**: Automatic GitHub issue creation -- **PR failures**: Block merge until resolved -- **Release failures**: Prevent tag deployment - -## ๐Ÿ“ˆ Monitoring - -### Coverage Tracking -- Local coverage verification ensuring 100% coverage -- HTML reports archived for 30 days -- Coverage badge auto-updated - -### Security Monitoring -- Daily dependency vulnerability scans -- Composer security audit on every build -- Automated security issue reporting - -## ๐ŸŽฏ Best Practices - -### For Contributors -1. Run `./bin/run-ci-tests.sh` before committing -2. Ensure 100% test coverage for new code -3. Add Behat scenarios for new features -4. Update tests when modifying existing code - -### For Maintainers -1. Review coverage reports before merging PRs -2. Monitor nightly test failures -3. Keep dependencies updated -4. Verify release pipeline before tagging - -This comprehensive CI/CD setup ensures code quality, security, and reliability at every stage of development. diff --git a/README.md b/README.md index ac0098b..d0f2032 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,12 @@ MVC View Model Normalizer ========================= -![CI Pipeline](https://github.com/praetoriantechnology/mvc-vm-normalizer/workflows/CI%20Pipeline/badge.svg) +![Tests](https://github.com/gryfoss/mvc-vm-normalizer/workflows/tests/badge.svg) ![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen) ![PHP](https://img.shields.io/badge/php-8.2%20%7C%208.3-blue) ![Tests](https://img.shields.io/badge/tests-PHPUnit%20%2B%20Behat-blue) -This adds the `DefaultViewModel` attribute into the system and `ViewSubscriber` which hooks into the `kernel.view` event. -Changes a model or entity into the defined view model before passing for further serialization. +This adds the `DefaultViewModel` attribute into the system and a Symfony Serializer normalizer that automatically transforms entities into their designated ViewModels during serialization. ## โœจ Features @@ -26,40 +25,22 @@ Changes a model or entity into the defined view model before passing for further composer require gryfoss/mvc-vm-normalizer ``` -### Basic Usage +### Configuration -1. Configure the ViewSubscriber in your `services.yaml`: +Configure the normalizer in your `services.yaml`: ```yaml -GryfOSS\Mvc\Subscriber\ViewSubscriber: - autowire: true - autoconfigure: true + GryfOSS\Mvc\Normalizer\DefaultViewModelNormalizer: + tags: + - { name: serializer.normalizer, priority: 100 } ``` -2. Add the attribute to your entities: - -```php -#[DefaultViewModel(viewModelClass: AbcViewModel::class)]alizer -========================= - -This adds the `DefaultViewModel` attribute into the system and `ViewSubscriber` which hooks into the `kernel.view` event. -Changes a model or entity into the defined view model before passing for further serialization. - -Usage: -1. Be sure to add `ViewSubscriber` to your `services.yaml` file: - -```yaml -GryfOSS\Mvc\Subscriber\ViewSubscriber: - autowire: true - autoconfigure: true -``` +### Basic Usage -2. Add to to classes which should have the ViewModel attached: +1. Add the attribute to your entities: ```php -#[DefaultViewModel(viewModelClass: AbcViewModel::class)] -```php -#[DefaultViewModel(viewModelClass: AbcViewModel::class)] +#[DefaultViewModel(viewModelClass: UserViewModel::class)] class User implements NormalizableInterface { public function __construct( @@ -70,7 +51,11 @@ class User implements NormalizableInterface // getters... } +``` + +2. Create your ViewModel: +```php class UserViewModel implements ViewModelInterface { public function __construct(private User $user) {}