diff --git a/.forgejo/workflows/e2e-tests.yaml b/.forgejo/workflows/e2e-tests.yaml new file mode 100644 index 00000000..877de515 --- /dev/null +++ b/.forgejo/workflows/e2e-tests.yaml @@ -0,0 +1,181 @@ +name: E2E Tests (Manual) + +on: + workflow_dispatch: + inputs: + browser: + description: 'Browser to test (all, chromium, firefox, webkit)' + required: false + default: 'all' + type: choice + options: + - all + - chromium + - firefox + - webkit + +env: + MIX_ENV: dev + DATABASE_URL: ecto://postgres:postgres@postgres/towerops_dev + +jobs: + test-e2e: + name: Run E2E Tests + runs-on: ubuntu-22.04 + + services: + postgres: + image: timescale/timescaledb:latest-pg17 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: towerops_dev + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - name: Checkout code + uses: https://github.com/actions/checkout@v4 + + - name: Set up Elixir + uses: https://github.com/erlef/setup-beam@v1 + with: + version-type: strict + elixir-version: '1.18.1' + otp-version: '27.2' + + - name: Set up Node.js + uses: https://github.com/actions/setup-node@v4 + with: + node-version: '22' + + - name: Cache Mix + uses: https://github.com/actions/cache@v4 + with: + path: ~/.mix + key: ${{ runner.os }}-mix-1.18.1-27.2 + restore-keys: ${{ runner.os }}-mix- + + - name: Cache deps + uses: https://github.com/actions/cache@v4 + with: + path: deps + key: ${{ runner.os }}-deps-${{ hashFiles('mix.lock') }} + restore-keys: ${{ runner.os }}-deps- + + - name: Cache _build + uses: https://github.com/actions/cache@v4 + with: + path: _build + key: ${{ runner.os }}-build-${{ hashFiles('lib/**/*.ex') }}-${{ hashFiles('mix.lock') }} + restore-keys: ${{ runner.os }}-build- + + - name: Cache npm + uses: https://github.com/actions/cache@v4 + with: + path: e2e/node_modules + key: ${{ runner.os }}-npm-${{ hashFiles('e2e/package-lock.json') }} + restore-keys: ${{ runner.os }}-npm- + + - name: Cache Playwright browsers + uses: https://github.com/actions/cache@v4 + with: + path: ~/.cache/ms-playwright + key: ${{ runner.os }}-playwright-${{ hashFiles('e2e/package-lock.json') }} + restore-keys: ${{ runner.os }}-playwright- + + - name: Install system dependencies + run: | + sudo apt-get update + sudo apt-get install -y libssl-dev libsnmp-dev snmp-mibs-downloader postgresql-client + + - name: Install Elixir dependencies + run: mix deps.get + + - name: Compile C NIF + run: make -C c_src + + - name: Setup database + run: | + mix ecto.create + mix ecto.load --skip-if-loaded + mix run priv/repo/seeds_e2e.exs + + - name: Start Phoenix server in background + run: | + mix phx.server > phoenix.log 2>&1 & + echo $! > phoenix.pid + echo "Phoenix server started with PID $(cat phoenix.pid)" + sleep 10 + echo "=== Phoenix startup logs (after 10s) ===" + cat phoenix.log || echo "No logs yet" + echo "=== Process status ===" + ps aux | grep $(cat phoenix.pid) || echo "Process not found" + env: + SECRET_KEY_BASE: ${{ secrets.SECRET_KEY_BASE || 'dev_secret_key_base_for_testing_only_min_64_chars_required_here' }} + PHX_HOST: localhost + + - name: Wait for Phoenix to start + run: | + timeout 60 bash -c 'until curl -f http://localhost:4000/health; do sleep 2; done' + + - name: Show Phoenix logs on failure + if: failure() + run: | + echo "=== Full Phoenix logs ===" + cat phoenix.log || echo "No log file found" + echo "=== Process status ===" + ps aux | grep phoenix || echo "No Phoenix processes found" + + - name: Install Playwright dependencies + working-directory: e2e + run: | + npm ci + npx playwright install --with-deps + + - name: Run e2e tests + working-directory: e2e + run: | + if [ "${{ inputs.browser }}" = "all" ]; then + npm test + else + npm test -- --project=${{ inputs.browser }} + fi + env: + CI: true + TEST_USER_EMAIL: test@example.com + TEST_USER_PASSWORD: TestPassword123! + TEST_USER_TOTP_SECRET: JBSWY3DPEHPK3PXP + + - name: Upload test results + if: always() + uses: https://github.com/actions/upload-artifact@v4 + with: + name: playwright-report-${{ inputs.browser }} + path: e2e/playwright-report/ + retention-days: 7 + + - name: Upload test videos + if: always() + uses: https://github.com/actions/upload-artifact@v4 + with: + name: playwright-videos-${{ inputs.browser }} + path: e2e/test-results/ + retention-days: 7 + + - name: Test summary + if: always() + run: | + echo "### E2E Test Results" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Browser:** ${{ inputs.browser }}" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + if [ -f e2e/playwright-report/index.html ]; then + echo "✅ Test report generated successfully" >> $GITHUB_STEP_SUMMARY + echo "Download artifacts to view the full report" >> $GITHUB_STEP_SUMMARY + else + echo "❌ No test report found" >> $GITHUB_STEP_SUMMARY + fi diff --git a/.forgejo/workflows/production.yaml b/.forgejo/workflows/production.yaml index f887e6dd..cdf448bd 100644 --- a/.forgejo/workflows/production.yaml +++ b/.forgejo/workflows/production.yaml @@ -79,145 +79,9 @@ jobs: - name: Run tests run: mix test - test-e2e: - name: Run E2E Tests - runs-on: ubuntu-22.04 - if: false # Temporarily disabled - env: - MIX_ENV: dev - DATABASE_URL: ecto://postgres:postgres@postgres/towerops_dev - - services: - postgres: - image: timescale/timescaledb:latest-pg17 - env: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: towerops_dev - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - - steps: - - name: Checkout code - uses: https://github.com/actions/checkout@v4 - - - name: Set up Elixir - uses: https://github.com/erlef/setup-beam@v1 - with: - version-type: strict - elixir-version: '1.18.1' - otp-version: '27.2' - - - name: Set up Node.js - uses: https://github.com/actions/setup-node@v4 - with: - node-version: '22' - - - name: Cache Mix - uses: https://github.com/actions/cache@v4 - with: - path: ~/.mix - key: ${{ runner.os }}-mix-1.18.1-27.2 - restore-keys: ${{ runner.os }}-mix- - - - name: Cache deps - uses: https://github.com/actions/cache@v4 - with: - path: deps - key: ${{ runner.os }}-deps-${{ hashFiles('mix.lock') }} - restore-keys: ${{ runner.os }}-deps- - - - name: Cache _build - uses: https://github.com/actions/cache@v4 - with: - path: _build - key: ${{ runner.os }}-build-${{ hashFiles('lib/**/*.ex') }}-${{ hashFiles('mix.lock') }} - restore-keys: ${{ runner.os }}-build- - - - name: Cache npm - uses: https://github.com/actions/cache@v4 - with: - path: e2e/node_modules - key: ${{ runner.os }}-npm-${{ hashFiles('e2e/package-lock.json') }} - restore-keys: ${{ runner.os }}-npm- - - - name: Cache Playwright browsers - uses: https://github.com/actions/cache@v4 - with: - path: ~/.cache/ms-playwright - key: ${{ runner.os }}-playwright-${{ hashFiles('e2e/package-lock.json') }} - restore-keys: ${{ runner.os }}-playwright- - - - name: Install system dependencies - run: | - sudo apt-get update - sudo apt-get install -y libssl-dev libsnmp-dev snmp-mibs-downloader postgresql-client - - - name: Install Elixir dependencies - run: mix deps.get - - - name: Setup database - run: | - mix ecto.create - mix ecto.load --skip-if-loaded - mix run priv/repo/seeds_e2e.exs - - - name: Start Phoenix server in background - run: | - mix phx.server > phoenix.log 2>&1 & - echo $! > phoenix.pid - echo "Phoenix server started with PID $(cat phoenix.pid)" - sleep 10 - echo "=== Phoenix startup logs (after 10s) ===" - cat phoenix.log || echo "No logs yet" - echo "=== Process status ===" - ps aux | grep $(cat phoenix.pid) || echo "Process not found" - env: - SECRET_KEY_BASE: ${{ secrets.SECRET_KEY_BASE || 'dev_secret_key_base_for_testing_only_min_64_chars_required_here' }} - PHX_HOST: localhost - - - name: Wait for Phoenix to start - run: | - timeout 60 bash -c 'until curl -f http://localhost:4000/health; do sleep 2; done' - - - name: Show Phoenix logs on failure - if: failure() - run: | - echo "=== Full Phoenix logs ===" - cat phoenix.log || echo "No log file found" - echo "=== Process status ===" - ps aux | grep phoenix || echo "No Phoenix processes found" - - - name: Install Playwright dependencies - working-directory: e2e - run: | - npm ci - npx playwright install --with-deps - - - name: Run e2e tests - working-directory: e2e - run: npm test - env: - CI: true - TEST_USER_EMAIL: test@example.com - TEST_USER_PASSWORD: TestPassword123! - TEST_USER_TOTP_SECRET: JBSWY3DPEHPK3PXP - - - name: Upload test results - if: failure() - uses: https://github.com/actions/upload-artifact@v4 - with: - name: playwright-report - path: e2e/playwright-report/ - retention-days: 7 - build-and-deploy: name: Build and Deploy to Production runs-on: ubuntu-22.04 - # Only require ExUnit tests to pass, e2e is optional needs: [test-exunit] steps: @@ -281,13 +145,30 @@ jobs: - name: Update deployment manifest run: | IMAGE_TAG="${{ steps.tag.outputs.tag }}" - sed -i "s|image: ${REGISTRY}/${IMAGE_NAME}:.*|image: ${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}|g" k8s/deployment.yaml + # Configure git git config user.name "Forgejo Actions" git config user.email "actions@git.mcintire.me" + + # Fetch and checkout production branch + git fetch origin production + git checkout production + git pull origin production --rebase + + # Merge main branch changes + git merge origin/main --no-edit + + # Update deployment manifest + sed -i "s|image: ${REGISTRY}/${IMAGE_NAME}:.*|image: ${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}|g" k8s/deployment.yaml + + # Commit and push if there are changes git add k8s/deployment.yaml - git commit -m "chore: update production image to ${IMAGE_TAG} [skip ci]" || echo "No changes to commit" - git push origin HEAD:production + if git diff --staged --quiet; then + echo "No changes to deployment.yaml" + else + git commit -m "chore: update production image to ${IMAGE_TAG} [skip ci]" + git push origin production + fi - name: Deployment summary run: |