Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 83 additions & 12 deletions .github/workflows/docker-buildx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ on:
workflow_dispatch:
schedule:
- cron: "5 4 1,15 * *"
workflow_run:
workflows: ["Test Drupal Installation"]
branches: [main]
types:
- completed
push:
branches:
- main
pull_request:

env:
DOCKERFILE_DIR: php8
Expand All @@ -18,7 +17,6 @@ concurrency:

jobs:
buildx:
if: github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
strategy:
matrix:
Expand Down Expand Up @@ -50,9 +48,7 @@ jobs:
with:
username: hussainweb
password: ${{ secrets.DOCKERHUB_TOKEN }}
if: |
(github.event_name == 'workflow_run' && github.event.workflow_run.head_branch == 'main') ||
(github.event_name != 'workflow_run' && github.ref == 'refs/heads/main')
if: github.ref == 'refs/heads/main'
- name: Set Dockerfile directory
if: ${{ matrix.php_version == '8.2' || matrix.php_version == '8.3' || matrix.php_version == '8.4' || matrix.php_version == '8.5' }}
run: echo "DOCKERFILE_DIR=php8" >> $GITHUB_ENV
Expand All @@ -78,13 +74,88 @@ jobs:
fi

echo "tags=${TAGS}" >> $GITHUB_OUTPUT

- name: Set up environment variables
run: |
echo "PHP_VERSION=${{ matrix.php_version }}" >> $GITHUB_ENV
echo "VARIANT=${{ matrix.variant }}" >> $GITHUB_ENV
if [ "${{ matrix.variant }}" = "frankenphp-trixie" ]; then
echo "WEB_ROOT=/app" >> $GITHUB_ENV
else
echo "WEB_ROOT=/var/www/html" >> $GITHUB_ENV
fi
if [ "${{ matrix.variant }}" = "fpm-alpine" ]; then
echo "COMPOSE_FILE=tests/docker-compose.fpm.yml" >> $GITHUB_ENV
else
echo "COMPOSE_FILE=tests/docker-compose.yml" >> $GITHUB_ENV
fi
echo "CONTAINER_NAME=drupal" >> $GITHUB_ENV

- name: Build and load Docker image for testing
uses: docker/build-push-action@v6
with:
context: ${{ env.DOCKERFILE_DIR }}/${{ matrix.variant }}/
load: true
tags: drupal-test:${{ matrix.php_version }}-${{ matrix.variant }}
build-args: |
PHP_VERSION=${{ matrix.php_version }}
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Create test directory structure
run: |
rm -rf drupal-root
mkdir -p drupal-root
mkdir -p test-results
chmod 777 drupal-root

- name: Start Docker containers
run: |
docker compose up -d
# install-drupal.sh handles waiting for container readiness
docker compose ps

- name: Install Drupal
run: |
chmod +x tests/install-drupal.sh
# The script uses 'docker compose exec -T drupal', which matches our service name 'drupal'
if [ "${{ matrix.php_version }}" == "8.2" ]; then
./tests/install-drupal.sh ${{ matrix.variant }} "^10"
else
./tests/install-drupal.sh ${{ matrix.variant }} "^11"
fi

- name: Run Drupal verification tests
run: |
chmod +x tests/verify-drupal.sh
./tests/verify-drupal.sh ${{ matrix.variant }}

- name: Capture logs
if: failure()
run: |
echo "=== Docker Compose Logs ==="
docker compose logs
echo "=== Container Status ==="
docker compose ps
docker compose logs > test-results/docker-logs-${{ matrix.variant }}.txt

- name: Upload test results
if: failure()
uses: actions/upload-artifact@v4
with:
name: test-results-${{ matrix.php_version }}-${{ matrix.variant }}
path: test-results/
if-no-files-found: ignore

- name: Clean up
if: always()
run: docker compose down -v

- name: Build and push Docker image for PHP ${{ matrix.php_version }}
uses: docker/build-push-action@v6
with:
context: ${{ env.DOCKERFILE_DIR }}/${{ matrix.variant }}/
push: |
${{ (github.event_name == 'workflow_run' && github.event.workflow_run.head_branch == 'main') ||
(github.event_name != 'workflow_run' && github.ref == 'refs/heads/main') }}
push: ${{ github.ref == 'refs/heads/main' }}
tags: ${{ steps.tags.outputs.tags }}
build-args: |
PHP_VERSION=${{ matrix.php_version }}
Expand Down
92 changes: 0 additions & 92 deletions .github/workflows/test-drupal.yml

This file was deleted.

2 changes: 1 addition & 1 deletion php8/apache-bookworm/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ RUN set -eux; \
curl -fsSL "https://www.sqlite.org/${SQLITE_YEAR}/sqlite-autoconf-${SQLITE_VERSION}.tar.gz" -o sqlite.tar.gz; \
tar -xzf sqlite.tar.gz; \
cd sqlite-autoconf-${SQLITE_VERSION}; \
./configure --prefix=/usr/local; \
./configure --prefix=/usr/local CPPFLAGS="-DSQLITE_ENABLE_COLUMN_METADATA=1"; \
make -j"$(nproc)"; \
make install; \
cd ..; \
Expand Down
53 changes: 45 additions & 8 deletions tests/install-drupal.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
set -e

VARIANT=$1
DRUPAL_VERSION=$2
CONSTRAINT=$2

echo "===================================="
echo "Installing Drupal ${DRUPAL_VERSION} on ${VARIANT}"
echo "Installing Drupal ${CONSTRAINT} on ${VARIANT}"
echo "===================================="

# Use service name instead of container name
Expand Down Expand Up @@ -35,14 +35,24 @@ for i in {1..12}; do
sleep 5
done

# Check if Drupal is already installed
INSTALLED=$(docker compose exec -T $SERVICE sh -c "if [ -f ${WEBROOT}/web/sites/default/settings.php ] && grep -q 'database' ${WEBROOT}/web/sites/default/settings.php 2>/dev/null; then echo 'yes'; else echo 'no'; fi" || echo "no")
echo "Creating Drupal project..."

if [ "$INSTALLED" = "yes" ]; then
echo "Drupal appears to be already installed. Skipping installation."
exit 0
# Clean directory first to ensure composer create-project works
# We use . to install in current directory
docker compose exec -T $SERVICE sh -c "rm -rf ${WEBROOT}/* ${WEBROOT}/.* 2>/dev/null || true"

# Create project
# We use specific arguments to avoid shell expansion issues
if [ -n "$CONSTRAINT" ]; then
docker compose exec -T $SERVICE composer create-project drupal/recommended-project . "$CONSTRAINT" --no-interaction --no-dev
else
docker compose exec -T $SERVICE composer create-project drupal/recommended-project . --no-interaction --no-dev
fi

# Require Drush
echo "Requiring Drush..."
docker compose exec -T $SERVICE composer require drush/drush --no-interaction

# Set proper permissions
echo "Setting up permissions..."
docker compose exec -T $SERVICE sh -c "mkdir -p ${WEBROOT}/web/sites/default/files && chmod -R 777 ${WEBROOT}/web/sites/default/files"
Expand All @@ -51,7 +61,7 @@ docker compose exec -T $SERVICE sh -c "chmod 777 ${WEBROOT}/web/sites/default"
# Install Drupal using drush with SQLite database file
echo "Installing Drupal using drush with SQLite..."
docker compose exec -T $SERVICE sh -c "cd ${WEBROOT} && vendor/bin/drush site:install minimal \
--db-url="sqlite://localhost/sites/default/files/.ht.sqlite" \
--db-url="sqlite://sites/default/files/.ht.sqlite" \
--site-name="Drupal Test Site" \
--account-name=admin \
--account-pass=admin \
Expand All @@ -68,6 +78,33 @@ echo "$DRUSH_STATUS"
# Check if bootstrap was successful
if echo "$DRUSH_STATUS" | grep -q "bootstrap"; then
echo "✓ Drupal installation completed successfully"

# Extract SQLite database path from drush status output
# Format: "db-name": "/path/to/db.sqlite" or "db-name": "/path/to/db.sqlite",
# We use sed to extract the value inside quotes after "db-name":
DB_PATH=$(echo "$DRUSH_STATUS" | grep "\"db-name\"" | sed -E 's/.*"db-name": "([^"]+)".*/\1/')

# Check if path is relative (doesn't start with /)
if [[ "$DB_PATH" != /* ]]; then
echo "Relative database path detected: $DB_PATH"
DB_PATH="${WEBROOT}/web/${DB_PATH}"
fi

echo "Resolved database path: $DB_PATH"

if [ -n "$DB_PATH" ] && [[ "$DB_PATH" != *"null"* ]]; then
# Get directory containing the database
# Note: logic runs locally, so DB_DIR will be a local path string, which matches the container path structure
DB_DIR=$(dirname "$DB_PATH")
echo "Ensuring database directory is writable: $DB_DIR"
# Ensure the directory containing the SQLite file is writable
# We need to escape the variable for the remote shell execution
docker compose exec -T $SERVICE sh -c "chmod 777 \"$DB_DIR\""

# Ensure the SQLite file itself is writable (as requested)
echo "Ensuring database file is writable: $DB_PATH"
docker compose exec -T $SERVICE sh -c "chmod 666 \"$DB_PATH\""
fi
else
echo "✗ Drupal installation may have issues"
exit 1
Expand Down
30 changes: 25 additions & 5 deletions tests/verify-drupal.sh
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,31 @@ else
echo "--- Fetching page content with error details ---"
curl -v "$BASE_URL" 2>&1 | head -50
echo ""
echo "--- Checking file permissions ---"
docker compose exec -T $SERVICE sh -c "ls -la ${WEBROOT}/web/sites/default/files/" || true
echo "--- Checking SQLite database permissions (via drush status) ---"
# Get DB path from drush status JSON output
# Format: "db-name": "/path/to/db.sqlite" or "db-name": "/path/to/db.sqlite",
DRUSH_JSON=$(docker compose exec -T $SERVICE sh -c "cd ${WEBROOT} && vendor/bin/drush status --format=json" 2>/dev/null || echo "{}")
DB_PATH=$(echo "$DRUSH_JSON" | grep "\"db-name\"" | sed -E 's/.*"db-name": "([^"]+)".*/\1/')

# Check if path is relative (doesn't start with /)
if [[ "$DB_PATH" != /* ]]; then
echo "Relative database path detected: $DB_PATH"
DB_PATH="${WEBROOT}/web/${DB_PATH}"
fi

echo "Resolved DB Path: $DB_PATH"

if [ -n "$DB_PATH" ] && [[ "$DB_PATH" != *"null"* ]]; then
echo "Permissions for DB file:"
docker compose exec -T $SERVICE sh -c "ls -la \"$DB_PATH\"" || echo "File not found"

DB_DIR=$(dirname "$DB_PATH")
echo "Permissions for DB directory ($DB_DIR):"
docker compose exec -T $SERVICE sh -c "ls -ld \"$DB_DIR\"" || echo "Directory not found"
else
echo "Could not determine DB path from drush status"
echo "Raw drush output: $DRUSH_JSON"
fi
echo ""
echo "--- Checking web server user ---"
docker compose exec -T $SERVICE sh -c 'ps aux | grep -E "(apache|httpd|nginx|php-fpm|frankenphp)" | grep -v grep | head -5' || true
Expand All @@ -103,9 +126,6 @@ else
echo "--- Checking Drupal watchdog errors ---"
docker compose exec -T $SERVICE sh -c "cd ${WEBROOT} && vendor/bin/drush watchdog:show --severity=Error --count=10 2>&1" || true
echo ""
echo "--- Checking SQLite database permissions ---"
docker compose exec -T $SERVICE sh -c "ls -la ${WEBROOT}/web/sites/default/files/.ht.sqlite* 2>/dev/null" || true
echo ""
echo "--- Checking PHP modules loaded via web server ---"
docker compose exec -T $SERVICE sh -c "echo '<?php header(\"Content-Type: text/plain\"); foreach (get_loaded_extensions() as \$ext) { echo \$ext . \"\\n\"; }' > ${WEBROOT}/web/check_modules.php" || true
echo "Modules from web server:"
Expand Down