feat: add tests #5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Test Suite | |
| on: | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| jobs: | |
| test: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| services: | |
| mysql: | |
| image: mysql:8 | |
| env: | |
| MYSQL_ROOT_PASSWORD: password | |
| MYSQL_DATABASE: catalog_test | |
| ports: | |
| - 3307:3306 | |
| options: >- | |
| --health-cmd="mysqladmin ping" | |
| --health-interval=10s | |
| --health-timeout=5s | |
| --health-retries=3 | |
| opensearch: | |
| image: opensearchproject/opensearch:3 | |
| env: | |
| cluster.name: test-opensearch-cluster | |
| node.name: test-opensearch | |
| discovery.type: single-node | |
| bootstrap.memory_lock: true | |
| OPENSEARCH_JAVA_OPTS: -Xms256m -Xmx256m | |
| DISABLE_SECURITY_PLUGIN: true | |
| ports: | |
| - 9201:9200 | |
| options: >- | |
| --health-cmd="curl -f http://localhost:9200/_cluster/health || exit 1" | |
| --health-interval=30s | |
| --health-timeout=10s | |
| --health-retries=3 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "lts/*" | |
| cache: pnpm | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Generate Prisma client | |
| run: pnpm run generate | |
| - name: Wait for services to be ready | |
| run: | | |
| # Wait for MySQL | |
| for i in {1..30}; do | |
| if mysqladmin ping -h 127.0.0.1 -P 3307 -u root -ppassword &> /dev/null; then | |
| echo "MySQL is ready" | |
| break | |
| fi | |
| echo "Waiting for MySQL..." | |
| sleep 2 | |
| done | |
| # Wait for OpenSearch | |
| for i in {1..30}; do | |
| if curl -f http://localhost:9201/_cluster/health &> /dev/null; then | |
| echo "OpenSearch is ready" | |
| break | |
| fi | |
| echo "Waiting for OpenSearch..." | |
| sleep 2 | |
| done | |
| - name: Run database migrations | |
| run: pnpm run db:migrate | |
| env: | |
| DATABASE_URL: mysql://root:password@localhost:3307/catalog_test | |
| - name: Run linting | |
| run: | | |
| pnpm run lint:biome | |
| pnpm run lint:types | |
| - name: Run unit tests | |
| run: pnpm run test | |
| env: | |
| DATABASE_URL: mysql://root:password@localhost:3307/catalog_test | |
| OPENSEARCH_URL: http://localhost:9201 | |
| NODE_ENV: test | |
| - name: Check coverage threshold | |
| run: | | |
| # Extract coverage percentage from coverage report | |
| COVERAGE=$(cat coverage/coverage-summary.json | jq -r '.total.lines.pct') | |
| echo "Coverage: $COVERAGE%" | |
| # Fail if coverage is below 95% | |
| if (( $(echo "$COVERAGE < 95" | bc -l) )); then | |
| echo "Coverage $COVERAGE% is below required 95%" | |
| exit 1 | |
| fi | |
| echo "Coverage check passed: $COVERAGE%" | |
| - name: Upload coverage reports | |
| uses: codecov/codecov-action@v4 | |
| if: always() | |
| with: | |
| file: ./coverage/coverage-final.json | |
| fail_ci_if_error: false | |
| - name: "Report Coverage" | |
| if: always() | |
| uses: davelosert/vitest-coverage-report-action@v2 | |
| # Job to enforce that tests must pass | |
| test-status-check: | |
| runs-on: ubuntu-latest | |
| needs: test | |
| if: always() | |
| steps: | |
| - name: Test Status Check | |
| run: | | |
| if [ "${{ needs.test.result }}" != "success" ]; then | |
| echo "Tests failed or were cancelled" | |
| exit 1 | |
| fi | |
| echo "All tests passed successfully" | |