feat(hooks): make hook tooling config-driven #280
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Integration Tests | |
| on: | |
| push: | |
| branches: [main, develop] | |
| paths: | |
| - 'booster/**' | |
| - 'tools/internal-test/**' | |
| - '.github/workflows/integration-tests.yml' | |
| pull_request: | |
| branches: [main, develop] | |
| paths: | |
| - 'booster/**' | |
| - 'tools/**' | |
| - '.github/workflows/integration-tests.yml' | |
| schedule: | |
| # Run weekly on Sunday at 2 AM UTC | |
| - cron: '0 2 * * 0' | |
| workflow_dispatch: | |
| inputs: | |
| project_type: | |
| description: 'Project type to test' | |
| required: false | |
| default: 'laravel' | |
| type: choice | |
| options: | |
| - laravel | |
| - symfony | |
| test_action: | |
| description: 'Test action to run' | |
| required: false | |
| default: 'full' | |
| type: choice | |
| options: | |
| - full | |
| - setup | |
| - integrate | |
| - verify | |
| - test-hooks | |
| concurrency: | |
| group: integration-tests-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| integration-test: | |
| name: Integration Test (${{ matrix.project_type }}) | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| project_type: [laravel, symfony] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install mise | |
| uses: jdx/mise-action@v2 | |
| with: | |
| cache: true | |
| - name: Create cache directories | |
| run: | | |
| mkdir -p ~/.composer/cache | |
| mkdir -p ~/.cache/composer | |
| mkdir -p ~/.ddev/downloads | |
| - name: Cache Composer packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.composer/cache | |
| ~/.cache/composer | |
| key: ${{ runner.os }}-composer-${{ matrix.project_type }}-${{ hashFiles('**/composer.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-composer-${{ matrix.project_type }}- | |
| ${{ runner.os }}-composer- | |
| - name: Cache DDEV downloads | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.ddev/downloads | |
| key: ${{ runner.os }}-ddev-downloads-${{ matrix.project_type }} | |
| - name: Get pnpm store directory | |
| id: pnpm-cache | |
| shell: bash | |
| run: | | |
| echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT | |
| - name: Setup pnpm cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} | |
| key: ${{ runner.os }}-pnpm-store-${{ matrix.project_type }}-${{ hashFiles('**/pnpm-lock.yaml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pnpm-store-${{ matrix.project_type }}- | |
| ${{ runner.os }}-pnpm-store- | |
| - name: Cache test fixtures | |
| uses: actions/cache@v4 | |
| with: | |
| path: tests/.fixtures-cache | |
| key: ${{ runner.os }}-test-fixtures-v2-${{ matrix.project_type }}-${{ hashFiles('tools/internal-test/lib/project_setup.py') }} | |
| restore-keys: | | |
| ${{ runner.os }}-test-fixtures-v2-${{ matrix.project_type }}- | |
| ${{ runner.os }}-test-fixtures-v2- | |
| - name: Install DDEV | |
| uses: ddev/github-action-setup-ddev@v1 | |
| with: | |
| autostart: false | |
| - name: Configure DDEV | |
| run: | | |
| ddev config global --instrumentation-opt-in=false | |
| ddev config global --omit-containers=ddev-ssh-agent | |
| ddev version | |
| - name: Check requirements | |
| run: | | |
| python3 tools/internal-test/test-integration.py env-check | |
| - name: Build integration script from source | |
| run: | | |
| make build | |
| - name: Build and verify booster.zip contents | |
| if: matrix.project_type == 'laravel' | |
| run: | | |
| mkdir -p /tmp/booster-package | |
| (cd booster && sh package-release.sh /tmp/booster-package) | |
| unzip -Z1 /tmp/booster-package/booster.zip > /tmp/booster-zip-entries.txt | |
| : > /tmp/booster-zip-expected.txt | |
| jq -r '.directories.items[] | "booster/\(.)/"' booster/manifest.json >> /tmp/booster-zip-expected.txt | |
| jq -r '.files.topLevel.items[] | "booster/\(.)"' booster/manifest.json >> /tmp/booster-zip-expected.txt | |
| jq -r '.files.config.items[] | "booster/\(.)"' booster/manifest.json >> /tmp/booster-zip-expected.txt | |
| jq -r '.files.php.items[] | "booster/\(.)"' booster/manifest.json >> /tmp/booster-zip-expected.txt | |
| jq -r '.files.packageManagement.items[] | "booster/\(.)"' booster/manifest.json >> /tmp/booster-zip-expected.txt | |
| [ -d booster/openapi ] && echo "booster/openapi/" >> /tmp/booster-zip-expected.txt | |
| [ -f booster/.ddev/config.yaml ] && echo "booster/.ddev/config.yaml" >> /tmp/booster-zip-expected.txt | |
| [ -d booster/.ddev/commands ] && echo "booster/.ddev/commands/" >> /tmp/booster-zip-expected.txt | |
| [ -d booster/.ddev/php ] && echo "booster/.ddev/php/" >> /tmp/booster-zip-expected.txt | |
| [ -d booster/.ddev/web-build ] && echo "booster/.ddev/web-build/" >> /tmp/booster-zip-expected.txt | |
| [ -d booster/.ddev/scripts ] && echo "booster/.ddev/scripts/" >> /tmp/booster-zip-expected.txt | |
| [ -d booster/src ] && echo "booster/src/" >> /tmp/booster-zip-expected.txt | |
| [ -f booster/manifest.json ] && echo "booster/manifest.json" >> /tmp/booster-zip-expected.txt | |
| [ -f booster/README_SNIPPET.md ] && echo "booster/README_SNIPPET.md" >> /tmp/booster-zip-expected.txt | |
| missing=0 | |
| while IFS= read -r expected; do | |
| if [ -z "$expected" ]; then | |
| continue | |
| fi | |
| if [ "${expected%/}" != "$expected" ]; then | |
| if ! grep -Fq "$expected" /tmp/booster-zip-entries.txt; then | |
| echo "Missing directory in booster.zip: $expected" | |
| missing=1 | |
| fi | |
| else | |
| if ! grep -Fxq "$expected" /tmp/booster-zip-entries.txt; then | |
| echo "Missing file in booster.zip: $expected" | |
| missing=1 | |
| fi | |
| fi | |
| done < /tmp/booster-zip-expected.txt | |
| if [ "$missing" -ne 0 ]; then | |
| echo "booster.zip is missing expected files." | |
| exit 1 | |
| fi | |
| echo "booster.zip contains all expected manifest and runtime files." | |
| - name: Run integration test | |
| run: | | |
| # Use manual input if workflow_dispatch, otherwise use matrix | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| PROJECT_TYPE="${{ github.event.inputs.project_type }}" | |
| TEST_ACTION="${{ github.event.inputs.test_action }}" | |
| else | |
| PROJECT_TYPE="${{ matrix.project_type }}" | |
| TEST_ACTION="full" | |
| fi | |
| echo "Running test: $TEST_ACTION for project type: $PROJECT_TYPE" | |
| python3 tools/internal-test/test-integration.py "$TEST_ACTION" "$PROJECT_TYPE" | |
| - name: Show test results | |
| if: always() | |
| run: | | |
| echo "Test completed. Checking status..." | |
| python3 tools/internal-test/test-integration.py status ${{ matrix.project_type }} | |
| manual-test: | |
| name: Manual Test (workflow_dispatch only) | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'workflow_dispatch' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install mise | |
| uses: jdx/mise-action@v2 | |
| with: | |
| cache: true | |
| - name: Create cache directories | |
| run: | | |
| mkdir -p ~/.composer/cache | |
| mkdir -p ~/.cache/composer | |
| mkdir -p ~/.ddev/downloads | |
| - name: Cache Composer packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.composer/cache | |
| ~/.cache/composer | |
| key: ${{ runner.os }}-composer-${{ github.event.inputs.project_type }}-${{ hashFiles('**/composer.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-composer-${{ github.event.inputs.project_type }}- | |
| ${{ runner.os }}-composer- | |
| - name: Cache DDEV downloads | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.ddev/downloads | |
| key: ${{ runner.os }}-ddev-downloads-${{ github.event.inputs.project_type }} | |
| - name: Get pnpm store directory | |
| id: pnpm-cache | |
| shell: bash | |
| run: | | |
| echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT | |
| - name: Setup pnpm cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} | |
| key: ${{ runner.os }}-pnpm-store-${{ github.event.inputs.project_type }}-${{ hashFiles('**/pnpm-lock.yaml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pnpm-store-${{ github.event.inputs.project_type }}- | |
| ${{ runner.os }}-pnpm-store- | |
| - name: Cache test fixtures | |
| uses: actions/cache@v4 | |
| with: | |
| path: tests/.fixtures-cache | |
| key: ${{ runner.os }}-test-fixtures-v2-${{ github.event.inputs.project_type }}-${{ hashFiles('tools/internal-test/lib/project_setup.py') }} | |
| restore-keys: | | |
| ${{ runner.os }}-test-fixtures-v2-${{ github.event.inputs.project_type }}- | |
| ${{ runner.os }}-test-fixtures-v2- | |
| - name: Install DDEV | |
| uses: ddev/github-action-setup-ddev@v1 | |
| with: | |
| autostart: false | |
| - name: Configure DDEV | |
| run: | | |
| ddev config global --instrumentation-opt-in=false | |
| ddev config global --omit-containers=ddev-ssh-agent | |
| ddev version | |
| - name: Check requirements | |
| run: | | |
| python3 tools/internal-test/test-integration.py env-check | |
| - name: Build integration script from source | |
| run: | | |
| make build | |
| - name: Build and verify booster.zip contents | |
| run: | | |
| mkdir -p /tmp/booster-package | |
| (cd booster && sh package-release.sh /tmp/booster-package) | |
| unzip -Z1 /tmp/booster-package/booster.zip > /tmp/booster-zip-entries.txt | |
| : > /tmp/booster-zip-expected.txt | |
| jq -r '.directories.items[] | "booster/\(.)/"' booster/manifest.json >> /tmp/booster-zip-expected.txt | |
| jq -r '.files.topLevel.items[] | "booster/\(.)"' booster/manifest.json >> /tmp/booster-zip-expected.txt | |
| jq -r '.files.config.items[] | "booster/\(.)"' booster/manifest.json >> /tmp/booster-zip-expected.txt | |
| jq -r '.files.php.items[] | "booster/\(.)"' booster/manifest.json >> /tmp/booster-zip-expected.txt | |
| jq -r '.files.packageManagement.items[] | "booster/\(.)"' booster/manifest.json >> /tmp/booster-zip-expected.txt | |
| [ -d booster/openapi ] && echo "booster/openapi/" >> /tmp/booster-zip-expected.txt | |
| [ -f booster/.ddev/config.yaml ] && echo "booster/.ddev/config.yaml" >> /tmp/booster-zip-expected.txt | |
| [ -d booster/.ddev/commands ] && echo "booster/.ddev/commands/" >> /tmp/booster-zip-expected.txt | |
| [ -d booster/.ddev/php ] && echo "booster/.ddev/php/" >> /tmp/booster-zip-expected.txt | |
| [ -d booster/.ddev/web-build ] && echo "booster/.ddev/web-build/" >> /tmp/booster-zip-expected.txt | |
| [ -d booster/.ddev/scripts ] && echo "booster/.ddev/scripts/" >> /tmp/booster-zip-expected.txt | |
| [ -d booster/src ] && echo "booster/src/" >> /tmp/booster-zip-expected.txt | |
| [ -f booster/manifest.json ] && echo "booster/manifest.json" >> /tmp/booster-zip-expected.txt | |
| [ -f booster/README_SNIPPET.md ] && echo "booster/README_SNIPPET.md" >> /tmp/booster-zip-expected.txt | |
| missing=0 | |
| while IFS= read -r expected; do | |
| if [ -z "$expected" ]; then | |
| continue | |
| fi | |
| if [ "${expected%/}" != "$expected" ]; then | |
| if ! grep -Fq "$expected" /tmp/booster-zip-entries.txt; then | |
| echo "Missing directory in booster.zip: $expected" | |
| missing=1 | |
| fi | |
| else | |
| if ! grep -Fxq "$expected" /tmp/booster-zip-entries.txt; then | |
| echo "Missing file in booster.zip: $expected" | |
| missing=1 | |
| fi | |
| fi | |
| done < /tmp/booster-zip-expected.txt | |
| if [ "$missing" -ne 0 ]; then | |
| echo "booster.zip is missing expected files." | |
| exit 1 | |
| fi | |
| echo "booster.zip contains all expected manifest and runtime files." | |
| - name: Run manual test | |
| run: | | |
| PROJECT_TYPE="${{ github.event.inputs.project_type }}" | |
| TEST_ACTION="${{ github.event.inputs.test_action }}" | |
| echo "Running manual test: $TEST_ACTION for project type: $PROJECT_TYPE" | |
| python3 tools/internal-test/test-integration.py "$TEST_ACTION" "$PROJECT_TYPE" | |
| - name: Show test results | |
| if: always() | |
| run: | | |
| echo "Manual test completed. Checking status..." | |
| python3 tools/internal-test/test-integration.py status ${{ github.event.inputs.project_type }} |