MOODUL 08 · TASE 3 — KESKMINE

⚙️ CI/CD ja Automatiseerimine

GitHub Actions, automaatsed testid, linting, build pipeline — iga push automaatselt testitud ja deployitud!

⏱️ ~4-5 tundi 📝 6 harjutust 🟠 Keskmine

🔄 Samm 1 — GitHub Actions Põhialused

GitHub Actions käivitab automaatselt skripte iga push'i, PR-i või scheduli peale.

.github/workflows/ci.yml
name: CI Pipeline

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  lint-and-test:
    runs-on: ubuntu-latest

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

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

      - name: Paigalda sõltuvused
        run: npm ci

      - name: ESLint kontroll
        run: npm run lint

      - name: TypeScript kompileerimine
        run: npm run typecheck

      - name: Testid
        run: npm test

      - name: Build
        run: npm run build

🚀 Samm 2 — Automaatne Deploy

.github/workflows/deploy.yml
name: Deploy to GitHub Pages

on:
  push:
    branches: [main]

permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - run: npm ci
      - run: npm run build

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: ./dist

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}

    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

🧪 Samm 3 — Testid Vitest'iga

Terminal
# Paigalda Vitest
npm install -D vitest
tests/Vector2D.test.ts
import { describe, it, expect } from 'vitest';
import { Vector2D } from '../src/math/Vector2D';

describe('Vector2D', () => {
  it('peaks liitma kaks vektorit', () => {
    const a = new Vector2D(3, 4);
    const b = new Vector2D(1, 2);
    const result = a.add(b);
    expect(result.x).toBe(4);
    expect(result.y).toBe(6);
  });

  it('peaks arvutama pikkuse', () => {
    const v = new Vector2D(3, 4);
    expect(v.magnitude).toBeCloseTo(5);
  });

  it('peaks normaliseerima', () => {
    const v = new Vector2D(10, 0);
    const n = v.normalize();
    expect(n.x).toBeCloseTo(1);
    expect(n.y).toBeCloseTo(0);
  });

  it('peaks arvutama kauguse', () => {
    const a = new Vector2D(0, 0);
    const b = new Vector2D(3, 4);
    expect(a.distanceTo(b)).toBeCloseTo(5);
  });

  it('peaks lerp töötama', () => {
    const a = new Vector2D(0, 0);
    const b = new Vector2D(10, 10);
    const mid = Vector2D.lerp(a, b, 0.5);
    expect(mid.x).toBeCloseTo(5);
    expect(mid.y).toBeCloseTo(5);
  });
});

describe('AABB Collision', () => {
  it('peaks tuvastama kokkupõrget', () => {
    const a = { x: 0, y: 0, w: 10, h: 10 };
    const b = { x: 5, y: 5, w: 10, h: 10 };
    expect(aabbCollision(a, b)).toBe(true);
  });

  it('peaks mitte tuvastama kaugeid objekte', () => {
    const a = { x: 0, y: 0, w: 10, h: 10 };
    const b = { x: 50, y: 50, w: 10, h: 10 };
    expect(aabbCollision(a, b)).toBe(false);
  });
});

📏 Samm 4 — ESLint ja Prettier

Terminal + konfiguratsioon
# Paigalda
npm install -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin prettier

# eslint.config.js
import tseslint from '@typescript-eslint/eslint-plugin';
import tsparser from '@typescript-eslint/parser';

export default [
  {
    files: ['src/**/*.ts'],
    languageOptions: {
      parser: tsparser,
      parserOptions: { project: './tsconfig.json' }
    },
    plugins: { '@typescript-eslint': tseslint },
    rules: {
      'no-unused-vars': 'error',
      '@typescript-eslint/no-explicit-any': 'warn',
      '@typescript-eslint/explicit-function-return-type': 'warn',
      'no-console': ['warn', { allow: ['warn', 'error'] }]
    }
  }
];

// package.json skriptid:
// "lint": "eslint src/",
// "lint:fix": "eslint src/ --fix",
// "typecheck": "tsc --noEmit",
// "test": "vitest run",
// "test:watch": "vitest"

🏷️ Samm 5 — Automaatne Release

.github/workflows/release.yml
name: Release

on:
  push:
    tags: ['v*']

jobs:
  release:
    runs-on: ubuntu-latest
    permissions:
      contents: write

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - run: npm ci
      - run: npm run build

      - name: Loo ZIP
        run: cd dist && zip -r ../game-${{ github.ref_name }}.zip .

      - name: GitHub Release
        uses: softprops/action-gh-release@v2
        with:
          files: game-${{ github.ref_name }}.zip
          generate_release_notes: true

📝 Harjutused

  • Esimene GitHub Actions workflow

    Loo .github/workflows/ci.yml mis käivitab npm test iga push'i peale. Tee tahtlik vigane push ja vaata et action läbi kukub, siis paranda.

  • Vitest testid mängu matemaatikale

    Kirjuta vähemalt 10 testi: Vector2D, AABB collision, lerp, clamp, random range. Kõik testid peavad läbima CI-s.

  • ESLint + Prettier seadistamine

    Seadista ESLint TypeScript'iga ja Prettier. Lisa pre-commit hook (husky + lint-staged) mis kontrollib koodi enne commit'i.

  • Automaatne deploy GitHub Pages'ile

    Loo deploy workflow mis ehitab Vite projekti ja deployib automaatselt. Testi et iga main'i push uuendab live saiti.

  • Automaatne Release tag'iga

    Loo release workflow mis käivitub git push --tags peale. Ehitab mängu, loob ZIP ja teeb GitHub Release koos binaaridega.

  • Täielik CI/CD pipeline

    Kombineeri kõik: lint → typecheck → test → build → deploy. Lisa status badges README-sse. Pipeline peab blokeerima merge'i kui testid ebaõnnestuvad.

← Moodul 07b Moodul 08b: UI/UX →