Skip to content

feat(hooks): make hook tooling config-driven #280

feat(hooks): make hook tooling config-driven

feat(hooks): make hook tooling config-driven #280

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 }}