diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml new file mode 100644 index 00000000..e64ea34a --- /dev/null +++ b/.github/actions/setup/action.yml @@ -0,0 +1,15 @@ +name: 'Setup Node.js with cached dependencies' +description: 'Sets up Node.js and restores node_modules from the artifact uploaded by the setup job.' + +runs: + using: composite + steps: + - uses: actions/setup-node@v4 + with: + node-version: '20' + - uses: actions/download-artifact@v4 + with: + name: node-modules + path: . + - run: tar -xzf node-modules.tar.gz && rm node-modules.tar.gz + shell: bash diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..5ed900d6 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,78 @@ +name: CI + +on: + pull_request: + types: [opened, synchronize, reopened] + +permissions: + contents: read + +jobs: + setup: + name: Install Dependencies + runs-on: ubuntu-latest + permissions: + contents: read + actions: write + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + - run: npm ci + - run: tar -czf node-modules.tar.gz node_modules + - uses: actions/upload-artifact@v4 + with: + name: node-modules + path: node-modules.tar.gz + retention-days: 1 + + lint: + name: Lint + needs: setup + runs-on: ubuntu-latest + permissions: + contents: read + actions: read + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/setup + - run: npm run lint + + format-check: + name: Format Check + needs: setup + runs-on: ubuntu-latest + permissions: + contents: read + actions: read + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/setup + - run: npm run format:check + + build: + name: Build + needs: setup + runs-on: ubuntu-latest + permissions: + contents: read + actions: read + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/setup + - run: npm run build + + test: + name: Test & Coverage + needs: setup + runs-on: ubuntu-latest + permissions: + contents: read + actions: read + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/setup + - name: Enforce 80% coverage + run: npm run test:coverage diff --git a/eslint.config.js b/eslint.config.js index a0b326c3..6f82ce4d 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -15,7 +15,7 @@ module.exports = tseslint.config( ecmaVersion: 'latest', sourceType: 'module', parserOptions: { - projectService: true, + project: ['packages/backend/tsconfig.eslint.json'], tsconfigRootDir: __dirname, }, globals: { @@ -54,6 +54,7 @@ module.exports = tseslint.config( '@typescript-eslint/unbound-method': 'warn', }, }, + { files: ['**/*.spec.ts'], rules: { diff --git a/packages/backend/Dockerfile b/packages/backend/Dockerfile index 39d0ba17..c624fb26 100644 --- a/packages/backend/Dockerfile +++ b/packages/backend/Dockerfile @@ -12,13 +12,8 @@ COPY packages/backend/tsconfig.json packages/backend/ COPY packages/backend/tsconfig.prod.json packages/backend/ COPY packages/backend/src packages/backend/src -# Copy config files for linting -COPY eslint.config.js .prettierrc.js ./ - # Install dependencies and build RUN npm ci -RUN npm run lint -w @mocker/backend -RUN npm run test -w @mocker/backend RUN npm run build:prod -w @mocker/backend FROM node:20-alpine AS release diff --git a/packages/backend/tsconfig.eslint.json b/packages/backend/tsconfig.eslint.json new file mode 100644 index 00000000..a8a05124 --- /dev/null +++ b/packages/backend/tsconfig.eslint.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["node_modules", "dist"] +}