diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a634bd2 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,109 @@ +# Continuous Integration workflow for FlowFi +# Covers frontend linting/build, backend build/test, and Soroban contract build/test. +name: CI + +on: + push: + branches: [ main, develop ] + pull_request: + branches: [ main, develop ] + +jobs: + frontend: + name: Frontend CI + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: frontend/package-lock.json + + - name: Install dependencies + run: npm ci + working-directory: frontend + + - name: Lint + run: npm run lint + working-directory: frontend + + - name: Build + run: npm run build + working-directory: frontend + + backend: + name: Backend CI + runs-on: ubuntu-latest + services: + postgres: + image: postgres:15 + env: + POSTGRES_USER: user + POSTGRES_PASSWORD: password + POSTGRES_DB: flowfi_test + ports: + - 5432:5432 + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: backend/package-lock.json + + - name: Install dependencies + run: npm ci + working-directory: backend + + - name: Generate Prisma Client + run: npx prisma generate + working-directory: backend + + - name: Build + run: npm run build + working-directory: backend + + - name: Run Backend Tests + run: npm test + working-directory: backend + env: + DATABASE_URL: postgresql://user:password@localhost:5432/flowfi_test + + contracts: + name: Soroban Contracts CI + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + targets: wasm32-unknown-unknown + + - name: Rust Cache + uses: Swatinem/rust-cache@v2 + with: + workspaces: "contracts -> target" + + - name: Build Contracts + run: cargo build --target wasm32-unknown-unknown --release + working-directory: contracts + + - name: Run Contract Tests + run: cargo test + working-directory: contracts diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index e7cf1b2..ab9827e 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -14,30 +14,30 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'npm' - - - name: Install dependencies - run: npm ci - - - name: Run npm audit - run: npm audit --audit-level=moderate || true - - - name: Check for known vulnerabilities in frontend - run: | - cd frontend - npm audit --audit-level=moderate || true - - - name: Check for known vulnerabilities in backend - run: | - cd backend - npm audit --audit-level=moderate || true + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Run npm audit + run: npm audit --audit-level=moderate + + - name: Check for known vulnerabilities in frontend + run: | + cd frontend + npm audit --audit-level=moderate + + - name: Check for known vulnerabilities in backend + run: | + cd backend + npm audit --audit-level=moderate codeql-analysis: name: CodeQL Analysis diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6a8745c..daa2b8a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -286,22 +286,47 @@ This repository uses GitHub Actions for continuous integration. Workflows are lo - CodeQL analysis for JavaScript/TypeScript - View workflow: [Security Checks](.github/workflows/security.yml) +- **CI** (`.github/workflows/ci.yml`) + - Runs on: push to `main`/`develop` and pull requests + - Performs: + - Frontend: lint and build + - Backend: prisma generation, build, and tests + - Soroban Contracts: build (wasm) and tests + - View workflow: [CI](.github/workflows/ci.yml) + ### Running CI Checks Locally -Before pushing, ensure your changes pass: +Before pushing, ensure your changes pass all the same checks that run in GitHub Actions. + +#### 1. Frontend Checks +```bash +cd frontend +npm run lint # Runs ESLint +npm run build # Verifies the build +``` +#### 2. Backend Checks ```bash -# Frontend linting -cd frontend && npm run lint +cd backend +npm run prisma:generate # Ensure Prisma client is up to date +npm run build # Verifies TypeScript compilation +npm run test # Runs backend vitest suite +``` +*Note: Backend tests require a running PostgreSQL instance and `DATABASE_URL` environment variable.* -# Backend tests -cd backend && npm run test +#### 3. Smart Contract Checks +```bash +cd contracts +cargo build --target wasm32-unknown-unknown --release # Verifies contract build +cargo test # Runs contract tests +``` -# Security verification +#### 4. Security Verification +```bash +# From the repository root npm run verify-security ``` -For more details, see the [Security Workflow](.github/workflows/security.yml). --- diff --git a/frontend/package.json b/frontend/package.json index 19e62c7..54459b0 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -13,9 +13,9 @@ "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" + "react": "19.2.4", + "react-dom": "19.2.4", + "lucide-react": "^0.575.0" }, "devDependencies": { "@tailwindcss/postcss": "^4", @@ -27,4 +27,4 @@ "tailwindcss": "^4", "typescript": "^5" } -} +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index eb53eca..808876e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -66,6 +66,8 @@ "lucide-react": "^0.575.0", "next": "16.1.6", "next-themes": "^0.4.6", + "react": "19.2.4", + "react-dom": "19.2.4" "react": "19.2.3", "react-dom": "19.2.3", "react-hot-toast": "^2.6.0" @@ -81,27 +83,6 @@ "typescript": "^5" } }, - "frontend/node_modules/react": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", - "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "frontend/node_modules/react-dom": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", - "license": "MIT", - "dependencies": { - "scheduler": "^0.27.0" - }, - "peerDependencies": { - "react": "^19.2.3" - } - }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", @@ -8542,7 +8523,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -8552,7 +8532,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.27.0" },