name: E2E Tests on: workflow_call: outputs: coverage-artifact: description: "E2E coverage artifact name" value: ${{ jobs.cypress.outputs.coverage-artifact }} jobs: cypress: name: Cypress E2E Tests runs-on: ubuntu-latest outputs: coverage-artifact: e2e-coverage services: postgres: image: postgres:16-alpine env: POSTGRES_USER: postgres POSTGRES_PASSWORD: testpassword POSTGRES_DB: ackify_test options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 ports: - 5432:5432 mailhog: image: mailhog/mailhog:latest ports: - 1025:1025 - 8025:8025 steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Go uses: actions/setup-go@v5 with: go-version: '1.24.5' cache: true cache-dependency-path: go.sum - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' cache-dependency-path: webapp/package-lock.json - name: Install frontend dependencies working-directory: webapp run: npm ci - name: Build frontend (with instrumentation for coverage) working-directory: webapp env: CYPRESS_COVERAGE: "true" run: npm run build - name: Install backend dependencies run: go mod download - name: Run database migrations env: ACKIFY_DB_DSN: "postgres://postgres:testpassword@localhost:5432/ackify_test?sslmode=disable" ACKIFY_APP_PASSWORD: "testpassword" run: | go run ./backend/cmd/migrate/main.go -migrations-path file://backend/migrations up - name: Copy frontend dist for embed run: | mkdir -p backend/cmd/community/web/dist cp -r webapp/dist/* backend/cmd/community/web/dist/ - name: Start Ackify server env: ACKIFY_DB_DSN: "postgres://postgres:testpassword@localhost:5432/ackify_test?sslmode=disable" ACKIFY_BASE_URL: "http://localhost:8080" ACKIFY_ORGANISATION: "Ackify Test" ACKIFY_OAUTH_PROVIDER: "github" ACKIFY_OAUTH_CLIENT_ID: "test_client_id" ACKIFY_OAUTH_CLIENT_SECRET: "test_client_secret" ACKIFY_OAUTH_COOKIE_SECRET: "dGVzdF9jb29raWVfc2VjcmV0X2Zvcl90ZXN0aW5nXzEyMzQ1Njc4OTA=" ACKIFY_ED25519_PRIVATE_KEY: "kKjNo0cTUOdXcamyxYCcmGfUm7zXzeI8T2jaLEjvbcpA0IIO7HbR3ANBlUlqlWuV3D+RjDT+8p5o37n98+Wu5A==" ACKIFY_LISTEN_ADDR: ":8080" ACKIFY_ADMIN_EMAILS: "admin@test.com" ACKIFY_MAIL_HOST: "localhost" ACKIFY_MAIL_PORT: "1025" ACKIFY_MAIL_TLS: "false" ACKIFY_MAIL_STARTTLS: "false" ACKIFY_MAIL_FROM: "noreply@ackify.test" ACKIFY_MAIL_FROM_NAME: "Ackify Test" ACKIFY_LOG_LEVEL: "debug" ACKIFY_AUTH_MAGICLINK_ENABLED: "true" ACKIFY_LOCALES_DIR: "${{ github.workspace }}/backend/locales" ACKIFY_TEMPLATES_DIR: "${{ github.workspace }}/backend/templates" ACKIFY_AUTH_MAGICLINK_RATE_LIMIT_EMAIL: "1000" ACKIFY_AUTH_MAGICLINK_RATE_LIMIT_IP: "1000" ACKIFY_AUTH_RATE_LIMIT: "1000" ACKIFY_DOCUMENT_RATE_LIMIT: "1000" ACKIFY_GENERAL_RATE_LIMIT: "1000" ACKIFY_STORAGE_TYPE: "local" ACKIFY_STORAGE_LOCAL_PATH: "/tmp/ackify-storage" ACKIFY_STORAGE_MAX_SIZE_MB: "50" run: | mkdir -p /tmp/ackify-storage go build -o ackify ./backend/cmd/community ./ackify > /tmp/ackify.log 2>&1 & echo $! > /tmp/ackify.pid # Wait for server to be ready for i in $(seq 1 60); do if curl -s http://localhost:8080/api/v1/health > /dev/null 2>&1; then echo "Server is ready after ${i}s" exit 0 fi sleep 1 done echo "Server failed to start. Logs:" cat /tmp/ackify.log exit 1 - name: Run Cypress tests uses: cypress-io/github-action@v6 with: working-directory: webapp install: false wait-on: 'http://localhost:8080/api/v1/health' wait-on-timeout: 60 browser: chrome headed: false env: CYPRESS_baseUrl: http://localhost:8080 CYPRESS_mailhogUrl: http://localhost:8025 - name: Upload Cypress screenshots uses: actions/upload-artifact@v4 if: failure() with: name: cypress-screenshots path: webapp/cypress/screenshots retention-days: 7 - name: Upload Cypress videos uses: actions/upload-artifact@v4 if: failure() with: name: cypress-videos path: webapp/cypress/videos retention-days: 7 - name: Upload E2E coverage artifact uses: actions/upload-artifact@v4 if: always() with: name: e2e-coverage path: webapp/coverage-e2e/lcov.info retention-days: 1 - name: Stop Ackify server if: always() run: | if [ -f /tmp/ackify.pid ]; then kill $(cat /tmp/ackify.pid) || true fi