Skip to content
36 changes: 36 additions & 0 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# CI/CD Workflow

This directory contains GitHub Actions workflows for automated testing and validation.

## CI / Validation Workflow (`.github/workflows/test.yml`)

**Purpose**: Prevents regressions by running all test suites and linting on every pull request to main.

**Triggers**:

- Pull requests targeting the `main` branch

**What it does**:

1. **Setup**: Installs Rust (stable) and Node.js (v20) with dependency caching
2. **Dependency Installation**: Uses `npm install` for both backend and frontend
3. **Code Quality**: Runs linting on both backend and frontend (if configured)
4. **Backend Tests**: Runs `npm test` in `/backend` (Vitest + TypeScript)
5. **Frontend Tests**: Runs `npm test --if-present` in `/frontend` (no test framework configured yet)
6. **Smart Contract Tests**: Runs `cargo test` in `/contracts` (Rust)

**Failure Behavior**:

- Workflow fails if any test or linting step fails
- Blocks PR merge until all checks pass
- Uses `--if-present` to avoid failures when test scripts are missing

**Requirements for Contributors**:

- Ensure lint and test scripts are properly configured in `package.json`
- Tests must pass in all directories where they exist
- New dependencies should be added to respective `package.json` files
- Backend uses Vitest, frontend has no test framework configured yet
- react-hot-toast is available as a root dependency

**Note**: The workflow uses `continue-on-error: false` to ensure strict validation - any failure will prevent the PR from being merged.
68 changes: 68 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: CI / Validation

on:
pull_request:
branches: [main]

jobs:
test:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable

- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"

- name: Cache Rust dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
contracts/target
key: ${{ runner.os }}-cargo-${{ hashFiles('contracts/**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-

- name: Install backend dependencies
run: npm install
working-directory: ./backend

- name: Install frontend dependencies
run: npm install
working-directory: ./frontend

- name: Run linting (backend)
run: npm run lint --if-present
working-directory: ./backend
continue-on-error: false

- name: Run linting (frontend)
run: npm run lint --if-present
working-directory: ./frontend
continue-on-error: false

- name: Run Rust tests
run: cargo test
working-directory: ./contracts
continue-on-error: false

- name: Run backend tests
run: npm test
working-directory: ./backend
continue-on-error: false

- name: Run frontend tests
run: npm test
working-directory: ./frontend
continue-on-error: false
8 changes: 7 additions & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,19 @@
"@types/cors": "^2.8.19",
"@types/express": "^5.0.6",
"@types/node": "^25.2.3",

"@types/supertest": "^6.0.3",

"@types/pg": "^8.16.0",

"@types/swagger-jsdoc": "^6.0.4",
"@types/swagger-ui-express": "^4.1.6",
"nodemon": "^3.1.11",
"prisma": "^7.4.1",
"supertest": "^7.2.2",
"ts-node": "^10.9.2",
"tsx": "^4.19.2",
"typescript": "^5.9.3"
"typescript": "^5.9.3",
"vitest": "^4.0.18"
}
}
2 changes: 1 addition & 1 deletion backend/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@
"src/**/*",
"tests/**/*"
]
}
}
1 change: 1 addition & 0 deletions frontend/__tests__/setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import "@testing-library/jest-dom";
14 changes: 11 additions & 3 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,32 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint"
"lint": "eslint",
"test": "vitest run"
},
"dependencies": {
"lucide-react": "^0.575.0",
"next": "16.1.6",
"next-themes": "^0.4.6",
"react": "19.2.3",
"react-dom": "19.2.3",

"react-hot-toast": "^2.6.0"

},
"devDependencies": {
"@tailwindcss/postcss": "^4",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "^14.6.1",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"@vitest/ui": "^4.0.18",
"eslint": "^9",
"eslint-config-next": "16.1.6",
"jsdom": "^28.1.0",
"tailwindcss": "^4",
"typescript": "^5"
"typescript": "^5",
"vitest": "^4.0.18"
}
}
16 changes: 16 additions & 0 deletions frontend/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { resolve } from "path";
import { defineConfig } from "vitest/config";

export default defineConfig({
test: {
globals: true,
environment: "jsdom",
setupFiles: ["./__tests__/setup.ts"],
passWithNoTests: true,
},
resolve: {
alias: {
"@": resolve(__dirname, "./"),
},
},
});
Loading
Loading