diff --git a/.github/workflows/inspect.yml b/.github/workflows/inspect.yml new file mode 100644 index 0000000..1a8dfbd --- /dev/null +++ b/.github/workflows/inspect.yml @@ -0,0 +1,83 @@ +# When a PR is opened or a push is made, perform an +# architectural inspection on the code using Deptrac. +name: Deptrac + +on: + pull_request: + branches: + - 'develop' + paths: + - 'src/**' + - 'tests/**' + - 'composer.**' + - 'depfile.yaml' + - '.github/workflows/inspect.yml' + push: + branches: + - 'develop' + paths: + - 'src/**' + - 'tests/**' + - 'composer.**' + - 'depfile.yaml' + - '.github/workflows/inspect.yml' + +jobs: + build: + name: PHP ${{ matrix.php-versions }} Architectural Inspection + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php-versions: ['7.4', '8.0'] + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + tools: composer, pecl, phive, phpunit + extensions: intl, json, mbstring, gd, mysqlnd, xdebug, xml, sqlite3 + env: + COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Create composer cache directory + run: mkdir -p ${{ steps.composer-cache.outputs.dir }} + + - name: Cache composer dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Create Deptrac cache directory + run: mkdir -p build/ + + - name: Cache Deptrac results + uses: actions/cache@v2 + with: + path: build + key: ${{ runner.os }}-deptrac-${{ github.sha }} + restore-keys: ${{ runner.os }}-deptrac- + + - name: Install dependencies (limited) + if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name }} + run: composer update --no-progress --no-interaction --prefer-dist --optimize-autoloader + + - name: Install dependencies (authenticated) + if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name }} + run: composer update --no-progress --no-interaction --prefer-dist --optimize-autoloader + env: + COMPOSER_AUTH: ${{ secrets.COMPOSER_AUTH }} + + - name: Run architectural inspection + run: | + sudo phive --no-progress install --global qossmic/deptrac --trust-gpg-keys B8F640134AB1782E + deptrac analyze --cache-file=build/deptrac.cache diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7bfa417..561601d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -55,13 +55,11 @@ jobs: env: COMPOSER_AUTH: ${{ secrets.COMPOSER_AUTH }} - - name: Enable Tachycardia - run: echo "TACHYCARDIA_MONITOR_GA=enabled" >> $GITHUB_ENV - - name: Test with PHPUnit run: vendor/bin/phpunit --verbose --coverage-text env: TERM: xterm-256color + TACHYCARDIA_MONITOR_GA: enabled - if: matrix.php-versions == '8.0' name: Mutate with Infection diff --git a/composer.json b/composer.json index f592e4f..c8adc2a 100644 --- a/composer.json +++ b/composer.json @@ -58,6 +58,7 @@ "prefer-stable": true, "scripts": { "analyze": "phpstan analyze", + "inspect": "deptrac analyze --cache-file=build/deptrac.cache", "mutate": "infection --threads=2 --skip-initial-tests --coverage=build/phpunit", "style": "php-cs-fixer fix --verbose --ansi", "test": "phpunit" diff --git a/depfile.yaml b/depfile.yaml new file mode 100644 index 0000000..79ec82a --- /dev/null +++ b/depfile.yaml @@ -0,0 +1,153 @@ +paths: + - ./src + - ./vendor/codeigniter4/codeigniter4/system + - ./vendor/tatter +exclude_files: + - '#.*test.*#i' +layers: + - name: Model + collectors: + - type: bool + must: + - type: className + regex: .*[A-Za-z]+Model$ + must_not: + - type: directory + regex: vendor/.* + - name: Vendor Model + collectors: + - type: bool + must: + - type: className + regex: .*[A-Za-z]+Model$ + - type: directory + regex: vendor/.* + - name: Controller + collectors: + - type: bool + must: + - type: className + regex: .*\/Controllers\/.* + must_not: + - type: directory + regex: vendor/.* + - name: Vendor Controller + collectors: + - type: bool + must: + - type: className + regex: .*\/Controllers\/.* + - type: directory + regex: vendor/.* + - name: Config + collectors: + - type: bool + must: + - type: directory + regex: src/Config/.* + must_not: + - type: className + regex: .*Services + - type: directory + regex: vendor/.* + - name: Vendor Config + collectors: + - type: bool + must: + - type: directory + regex: vendor/.*/Config/.* + must_not: + - type: className + regex: .*Services + - name: Entity + collectors: + - type: bool + must: + - type: directory + regex: src/Entities/.* + must_not: + - type: directory + regex: vendor/.* + - name: Vendor Entity + collectors: + - type: bool + must: + - type: directory + regex: vendor/.*/Entities/.* + - name: View + collectors: + - type: bool + must: + - type: directory + regex: src/Views/.* + must_not: + - type: directory + regex: vendor/.* + - name: Vendor View + collectors: + - type: bool + must: + - type: directory + regex: vendor/.*/Views/.* + - name: Service + collectors: + - type: className + regex: .*Services.* +ruleset: + Entity: + - Config + - Model + - Service + - Vendor Config + - Vendor Entity + - Vendor Model + Config: + - Service + - Vendor Config + Model: + - Config + - Entity + - Service + - Vendor Config + - Vendor Model + Service: + - Config + - Vendor Config + + # Ignore anything in the Vendor layers + Vendor Model: + - Service + - Vendor Config + - Vendor Controller + - Vendor Entity + - Vendor Model + - Vendor View + Vendor Controller: + - Service + - Vendor Config + - Vendor Controller + - Vendor Entity + - Vendor Model + - Vendor View + Vendor Config: + - Service + - Vendor Config + - Vendor Controller + - Vendor Entity + - Vendor Model + - Vendor View + Vendor Entity: + - Service + - Vendor Config + - Vendor Controller + - Vendor Entity + - Vendor Model + - Vendor View + Vendor View: + - Service + - Vendor Config + - Vendor Controller + - Vendor Entity + - Vendor Model + - Vendor View +skip_violations: