From 821449a2f7881198e5075daacafef028b30ae61a Mon Sep 17 00:00:00 2001 From: Achilles Date: Thu, 15 Jan 2026 17:38:53 -0600 Subject: [PATCH] Add GitHub Actions CI workflow - Run backend linting (PHP_CodeSniffer and PHPStan) - Run backend tests (PHPUnit) - Run frontend linting (ESLint) - Run frontend E2E tests (Playwright) - Trigger on PRs to any branch and pushes to main --- .github/workflows/ci.yml | 127 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..602269f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,127 @@ +name: CI + +on: + pull_request: + branches: + - '*' + push: + branches: + - main + +jobs: + backend-lint: + name: Backend Linting + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Run backend linting + run: | + PROJECT_NAME="ci-backend-lint" + COMPOSE_FILES="-f docker-compose.yml -f docker-compose.override.yml" + docker compose -p $PROJECT_NAME $COMPOSE_FILES build --quiet backend + docker compose -p $PROJECT_NAME $COMPOSE_FILES run --rm backend ./lint.sh + + backend-test: + name: Backend Tests + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Run backend tests + run: | + PROJECT_NAME="ci-backend-test" + COMPOSE_FILES="-f docker-compose.yml -f docker-compose.override.yml -f docker-compose.test.yml" + docker compose -p $PROJECT_NAME $COMPOSE_FILES build backend + docker compose -p $PROJECT_NAME $COMPOSE_FILES up -d db + sleep 5 + docker compose -p $PROJECT_NAME $COMPOSE_FILES up -d backend + sleep 10 + docker compose -p $PROJECT_NAME $COMPOSE_FILES exec -T backend ./seed.sh + docker compose -p $PROJECT_NAME $COMPOSE_FILES exec -T backend ./tests.sh + + - name: Cleanup backend test + if: always() + run: | + PROJECT_NAME="ci-backend-test" + COMPOSE_FILES="-f docker-compose.yml -f docker-compose.override.yml -f docker-compose.test.yml" + docker compose -p $PROJECT_NAME $COMPOSE_FILES down -v + + frontend-lint: + name: Frontend Linting + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Run frontend linting + run: | + PROJECT_NAME="ci-frontend-lint" + COMPOSE_FILES="-f docker-compose.yml -f docker-compose.override.yml" + docker compose -p $PROJECT_NAME $COMPOSE_FILES build --quiet frontend + docker compose -p $PROJECT_NAME $COMPOSE_FILES run --rm frontend ./lint.sh + + frontend-test: + name: Frontend Tests + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Start services + run: | + PROJECT_NAME="ci-frontend-test" + COMPOSE_FILES="-f docker-compose.yml -f docker-compose.override.yml -f docker-compose.test.yml" + docker compose -p $PROJECT_NAME $COMPOSE_FILES build + docker compose -p $PROJECT_NAME $COMPOSE_FILES up -d + env: + VITE_BACKEND_URL: http://backend:8000 + PLAYWRIGHT_BASE_URL: http://localhost:3000 + + - name: Wait for backend to be healthy + run: | + PROJECT_NAME="ci-frontend-test" + COMPOSE_FILES="-f docker-compose.yml -f docker-compose.override.yml -f docker-compose.test.yml" + timeout 120 bash -c 'until docker compose -p $PROJECT_NAME $COMPOSE_FILES exec -T backend curl -f http://localhost:8000/health > /dev/null 2>&1; do sleep 2; done' + + - name: Seed database + run: | + PROJECT_NAME="ci-frontend-test" + COMPOSE_FILES="-f docker-compose.yml -f docker-compose.override.yml -f docker-compose.test.yml" + docker compose -p $PROJECT_NAME $COMPOSE_FILES exec -T backend ./seed.sh + + - name: Wait for frontend to be ready + run: | + PROJECT_NAME="ci-frontend-test" + COMPOSE_FILES="-f docker-compose.yml -f docker-compose.override.yml -f docker-compose.test.yml" + sleep 10 + timeout 60 bash -c 'until curl -f http://localhost:13000 > /dev/null 2>&1; do sleep 2; done' + + - name: Run frontend E2E tests + run: | + PROJECT_NAME="ci-frontend-test" + COMPOSE_FILES="-f docker-compose.yml -f docker-compose.override.yml -f docker-compose.test.yml" + docker compose -p $PROJECT_NAME $COMPOSE_FILES exec -T frontend ./tests.sh + env: + PLAYWRIGHT_BASE_URL: http://localhost:3000 + + - name: Cleanup + if: always() + run: | + PROJECT_NAME="ci-frontend-test" + COMPOSE_FILES="-f docker-compose.yml -f docker-compose.override.yml -f docker-compose.test.yml" + docker compose -p $PROJECT_NAME $COMPOSE_FILES down -v