Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#11 ch: Setup CI workflow for testing, coverage reporting, building and linting #30

Merged
merged 1 commit into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 16 additions & 13 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,34 @@ module.exports = {
root: true,
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended'
],
rules: {
'@typescript-eslint/no-explicit-any': 'off',
"@typescript-eslint/no-unused-vars": [
"warn",
'@typescript-eslint/no-unused-vars': [
'warn',
{
"args": "all",
"argsIgnorePattern": "^_",
"caughtErrors": "all",
"caughtErrorsIgnorePattern": "^_",
"destructuredArrayIgnorePattern": "^_",
"varsIgnorePattern": "^_",
"ignoreRestSiblings": true
}
args: 'all',
argsIgnorePattern: '^_',
caughtErrors: 'all',
caughtErrorsIgnorePattern: '^_',
destructuredArrayIgnorePattern: '^_',
varsIgnorePattern: '^_',
ignoreRestSiblings: true,
},
],
'no-undef': 'off',
'semi': ['warn', 'always'],
'no-multi-spaces': 'warn',
'no-trailing-spaces': 'warn',
'space-before-function-paren': ['warn', 'always'],
'func-style': ['warn', 'declaration', { 'allowArrowFunctions': true }],
'func-style': ['warn', 'declaration', { allowArrowFunctions: true }],
'camelcase': 'warn',
'@typescript-eslint/explicit-function-return-type': ['warn', { allowExpressions: true }],
'@typescript-eslint/explicit-member-accessibility': ['off', { accessibility: 'explicit' }],
'no-unused-vars': 'warn',
'no-extra-semi': 'warn',
},
};
};
40 changes: 40 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: knights-ecomm-be CI

on: [push, pull_request]

env:
DEV_DB_HOST: ${{secrets.DEV_DB_HOST}}
DEV_DB_PORT: ${{secrets.DEV_DB_PORT}}
DEV_DB_USER: ${{secrets.DEV_DB_USER}}
DEV_DB_PASS: ${{secrets.DEV_DB_PASS}}
DEV_DB_NAME: ${{secrets.DEV_DB_NAME}}

jobs:
build-lint-test-coverage:
runs-on: ubuntu-latest

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

- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x'

- name: Install dependencies
run: npm install

- name: Run ESLint and Prettier
run: npm run lint

- name: Build project
run: npm run build --if-present

- name: Run tests
run: npm test

- name: Upload coverage report to Coveralls
uses: coverallsapp/github-action@v2.2.3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ package-lock.json
coverage/
dist
/src/logs
.DS_Store
.DS_Stor
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ functionalities for the frontend, such as storing, retrieving, deleting data and
List of endpoints exposed by the service

## Setup

- to use loggers in program use below functions

```bash
logger.error('This is an error message');
logger.warn('This is a warning message');
Expand Down
32 changes: 16 additions & 16 deletions jest.config.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
export default {
preset: "ts-jest",
testEnvironment: "node",
testMatch: ["**/**/*.test.ts"],
verbose: true,
forceExit: true,
clearMocks: true,
resetMocks: true,
restoreMocks: true,
collectCoverageFrom: [
"src/**/*.{ts,tsx}", // Include all JavaScript/JSX files in the src directory
],
coveragePathIgnorePatterns: [
"/node_modules/", // Exclude the node_modules directory
"/__tests__/", // Exclude the tests directory
],
};
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['**/**/*.test.ts'],
verbose: true,
forceExit: true,
clearMocks: true,
resetMocks: true,
restoreMocks: true,
collectCoverageFrom: [
'src/**/*.{ts,tsx}', // Include all JavaScript/JSX files in the src directory
],
coveragePathIgnorePatterns: [
'/node_modules/', // Exclude the node_modules directory
'/__tests__/', // Exclude the tests directory
],
};
24 changes: 24 additions & 0 deletions ormconfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module.exports = {
"type": "postgres",
"host": `${process.env.DEV_DB_HOST}`,
"port": `${process.env.DEV_DB_PORT}`,
"username": `${process.env.DEV_DB_USER}`,
"password": `${process.env.DEV_DB_PASS}`,
"database": `${process.env.DEV_DB_NAME}`,
"synchronize": true,
"logging": false,
"entities": [
"src/entities/**/*.ts"
],
"migrations": [
"src/migrations/**/*.ts"
],
"subscribers": [
"src/subscribers/**/*.ts"
],
"cli": {
"entitiesDir": "src/entities",
"migrationsDir": "src/migrations",
"subscribersDir": "src/subscribers"
}
};
24 changes: 17 additions & 7 deletions src/__test__/route.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
import request from 'supertest';
import {app, server} from '../index'; // update this with the path to your app file
import { app, server } from '../index'; // update this with the path to your app file

import { createConnection, getConnection, getConnectionOptions } from 'typeorm';

beforeAll(async () => {
// Connect to the test database
const connectionOptions = await getConnectionOptions();
await createConnection({ ...connectionOptions, name: 'testConnection' });
});
afterAll(async () => {
await getConnection('testConnection').close();
server.close();
});

describe('GET /', () => {
afterAll(done => {
server.close(done);
});
// afterAll(done => {
// server.close(done);
// });

it('responds with "Knights Ecommerce API"', done => {
request(app)
.get('/')
.expect(200, 'Knights Ecommerce API', done);
request(app).get('/').expect(200, 'Knights Ecommerce API', done);
});
});
28 changes: 0 additions & 28 deletions src/configs/db_config.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/controllers/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// export all controllers
function myFunction () {
function myFunction (): void {
console.log('Hello');
}
myFunction();
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
dotenv.config();

export const app = express();
const port = process.env.PORT as string;
const port = process.env.PORT || 8000;
app.use(express.json());

app.use(cors({ origin: '*' }));
app.use(router);
addDocumentation(app);
app.all('*', (req: Request, res: Response, next) => {

Check warning on line 19 in src/index.ts

View workflow job for this annotation

GitHub Actions / build-lint-test-coverage

'res' is defined but never used. Allowed unused args must match /^_/u

Check warning on line 19 in src/index.ts

View workflow job for this annotation

GitHub Actions / build-lint-test-coverage

'res' is defined but never used. Allowed unused args must match /^_/u
const error = new CustomError(`Can't find ${req.originalUrl} on the server!`, 404);
error.status = 'fail';
next(error);
Expand Down
37 changes: 16 additions & 21 deletions src/middlewares/errorHandler.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,25 @@
import { Request, Response } from 'express';

class CustomError extends Error {
statusCode: number;
status: string;
statusCode: number;
status: string;

constructor (message: string, statusCode: number) {
super(message);
this.statusCode = statusCode;
this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error';
Error.captureStackTrace(this, this.constructor);
}
constructor (message: string, statusCode: number) {
super(message);
this.statusCode = statusCode;
this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error';
Error.captureStackTrace(this, this.constructor);
}
}

const errorHandler = (
err: CustomError,
req: Request,
res: Response,

) => {
err.statusCode = err.statusCode || 500;
err.status = err.status || 'error';
res.status(err.statusCode).json({
status: err.statusCode,
message: err.message
});
console.error(err.stack);
const errorHandler = (err: CustomError, req: Request, res: Response) => {

Check warning on line 15 in src/middlewares/errorHandler.ts

View workflow job for this annotation

GitHub Actions / build-lint-test-coverage

'req' is defined but never used. Allowed unused args must match /^_/u

Check warning on line 15 in src/middlewares/errorHandler.ts

View workflow job for this annotation

GitHub Actions / build-lint-test-coverage

Missing return type on function

Check warning on line 15 in src/middlewares/errorHandler.ts

View workflow job for this annotation

GitHub Actions / build-lint-test-coverage

'req' is defined but never used. Allowed unused args must match /^_/u

Check warning on line 15 in src/middlewares/errorHandler.ts

View workflow job for this annotation

GitHub Actions / build-lint-test-coverage

Missing return type on function
err.statusCode = err.statusCode || 500;
err.status = err.status || 'error';
res.status(err.statusCode).json({
status: err.statusCode,
message: err.message,
});
console.error(err.stack);
};

export { CustomError, errorHandler };
17 changes: 7 additions & 10 deletions src/startups/dbConnection.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { OrmConfig } from "../configs/db_config";
import { createConnection } from "typeorm";

const dbConnection = async () => {

Check warning on line 3 in src/startups/dbConnection.ts

View workflow job for this annotation

GitHub Actions / build-lint-test-coverage

Missing return type on function

Check warning on line 3 in src/startups/dbConnection.ts

View workflow job for this annotation

GitHub Actions / build-lint-test-coverage

Missing return type on function
await OrmConfig.initialize()
.then(() => {
console.log("[db]: Database connected successfully");
})
.catch((error) => {
console.log("[db]: Database connection failed");
console.log(error);
});
try {
const connection = await createConnection();

Check warning on line 5 in src/startups/dbConnection.ts

View workflow job for this annotation

GitHub Actions / build-lint-test-coverage

'connection' is assigned a value but never used. Allowed unused vars must match /^_/u

Check warning on line 5 in src/startups/dbConnection.ts

View workflow job for this annotation

GitHub Actions / build-lint-test-coverage

'connection' is assigned a value but never used

Check warning on line 5 in src/startups/dbConnection.ts

View workflow job for this annotation

GitHub Actions / build-lint-test-coverage

'connection' is assigned a value but never used. Allowed unused vars must match /^_/u

Check warning on line 5 in src/startups/dbConnection.ts

View workflow job for this annotation

GitHub Actions / build-lint-test-coverage

'connection' is assigned a value but never used
console.log('Connected to the database');
} catch (error) {
console.error('Error connecting to the database:', error);
}
};

export { dbConnection };
8 changes: 4 additions & 4 deletions src/utils/response.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ interface ApiResponse {

export const responseSuccess = (
res: Response,
status_code: number,
statusCode: number,
message: string,
data?: any
): Response<ApiResponse> => {
return res.status(200).json(
jsend.success({
code: status_code,
code: statusCode,
message,
data,
})
Expand All @@ -24,13 +24,13 @@ export const responseSuccess = (

export const responseError = (
res: Response,
status_code: number,
statusCode: number,
message: string,
data?: any
): Response<ApiResponse> => {
return res.status(400).json(
jsend.error({
code: status_code,
code: statusCode,
message,
data,
})
Expand Down
Loading