diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 00000000..3e2025f7 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,143 @@ +name: Tests + +on: + push: + branches: [develop, main] + pull_request: + branches: [develop, main] + workflow_dispatch: + +env: + PYTHON_VERSION: "3.14" + NODE_VERSION: "24" + +jobs: + backend: + runs-on: ubuntu-latest + defaults: + run: + working-directory: backend + steps: + - uses: actions/checkout@v6 + + - name: Install uv + uses: astral-sh/setup-uv@v8.1.0 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Install dependencies + run: uv sync --frozen + + - name: Run tests + run: uv run pytest --junitxml=report.xml --cov=app --cov-report=term-missing + + - name: Upload report + if: always() + uses: actions/upload-artifact@v7 + with: + name: test-report-backend + path: backend/report.xml + + cli: + runs-on: ubuntu-latest + defaults: + run: + working-directory: cli + steps: + - uses: actions/checkout@v6 + + - name: Install uv + uses: astral-sh/setup-uv@v8.1.0 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Install dependencies + run: uv sync --frozen + + - name: Run tests + run: uv run pytest --junitxml=report.xml + + - name: Upload report + if: always() + uses: actions/upload-artifact@v7 + with: + name: test-report-cli + path: cli/report.xml + + frontend: + runs-on: ubuntu-latest + defaults: + run: + working-directory: frontend + steps: + - uses: actions/checkout@v6 + + - name: Install Node.js + uses: actions/setup-node@v6 + with: + node-version: ${{ env.NODE_VERSION }} + cache: npm + cache-dependency-path: frontend/package-lock.json + + - name: Install dependencies + run: npm ci + + - name: Run tests + run: npx vitest run --reporter=junit --reporter=default --outputFile=report.xml + + - name: Upload report + if: always() + uses: actions/upload-artifact@v7 + with: + name: test-report-frontend + path: frontend/report.xml + + report: + needs: [backend, cli, frontend] + if: always() + runs-on: ubuntu-latest + permissions: + checks: write + pull-requests: write + steps: + - uses: actions/download-artifact@v8 + with: + path: artifacts + + - name: Initialize git for test reporter + run: | + git init + git config user.email "ci@github.com" + git config user.name "CI" + git add -A + git commit --allow-empty -m "ci" + + - name: Publish test results + id: results + uses: dorny/test-reporter@v3 + with: + name: Test Results + path: "artifacts/**/report.xml" + reporter: java-junit + fail-on-error: "false" + + - name: Post PR comment + if: github.event_name == 'pull_request' + uses: actions/github-script@v9 + with: + script: | + const passed = parseInt('${{ steps.results.outputs.passed }}'); + const failed = parseInt('${{ steps.results.outputs.failed }}'); + const skipped = parseInt('${{ steps.results.outputs.skipped }}'); + const conclusion = '${{ steps.results.outputs.conclusion }}'; + const total = passed + failed + skipped; + const emoji = conclusion === 'success' ? '✅' : '❌'; + const sha = context.sha; + const shaLink = `[\`${sha.slice(0, 7)}\`](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/commit/${sha})`; + const summary = `${emoji} **Test Results** — ${passed} passed, ${failed} failed, ${skipped} skipped (${total} total) — ${shaLink}`; + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: summary, + });