Skip to content

Commit

Permalink
Merge pull request #14 from wri/release/sassy-sycamore
Browse files Browse the repository at this point in the history
[RELEASE] Sassy Sycamore
  • Loading branch information
roguenet authored Nov 14, 2024
2 parents 31c2da6 + ddbbfe6 commit 3b17b4e
Show file tree
Hide file tree
Showing 88 changed files with 2,752 additions and 418 deletions.
3 changes: 1 addition & 2 deletions .env.local.sample
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
DOCKER_HOST=unix://$HOME/.docker/run/docker.sock

USER_SERVICE_PORT=4010
JOB_SERVICE_PORT=4020
RESEARCH_SERVICE_PORT=4030

DB_HOST=localhost
DB_PORT=3360
Expand Down
11 changes: 10 additions & 1 deletion .github/workflows/deploy-service.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,24 @@ name: Service Deploy
run-name: 'Service Deploy [service: ${{ inputs.service }}, env: ${{ inputs.env }}]'

on:
workflow_call:
inputs:
service:
required: true
type: string
env:
required: true
type: string
workflow_dispatch:
inputs:
service:
description: 'Service to deploy'
type: choice
required: true
options:
- user-service
- job-service
- research-service
- user-service
env:
description: 'Deployment target environment'
type: choice
Expand Down
43 changes: 43 additions & 0 deletions .github/workflows/deploy-services.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Services Deploy (all)
run-name: 'Services Deploy (all) [env: ${{ inputs.env }}]'

on:
workflow_dispatch:
inputs:
env:
description: 'Deployment target environment'
type: choice
required: true
options:
- dev
- test
- staging
- prod

permissions:
id-token: write
contents: read

jobs:
job-service:
uses: ./.github/workflows/deploy-service.yml
with:
env: ${{ inputs.env }}
service: job-service
secrets: inherit

user-service:
uses: ./.github/workflows/deploy-service.yml
with:
env: ${{ inputs.env }}
service: user-service
secrets: inherit

research-service:
uses: ./.github/workflows/deploy-service.yml
with:
env: ${{ inputs.env }}
service: research-service
secrets: inherit


4 changes: 1 addition & 3 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ jobs:

- run: npm ci --legacy-peer-deps

- uses: nrwl/nx-set-shas@v4

- run: NX_CLOUD_DISTRIBUTED_EXECUTION=false npx nx affected -t lint build
- run: NX_CLOUD_DISTRIBUTED_EXECUTION=false npx nx run-many -t lint build

- uses: KengoTODA/actions-setup-docker-compose@v1
with:
Expand Down
10 changes: 9 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
{
"singleQuote": true
"arrowParens": "avoid",
"bracketSpacing": true,
"jsxBracketSameLine": false,
"printWidth": 120,
"semi": true,
"singleQuote": false,
"tabWidth": 2,
"trailingComma": "none",
"useTabs": false
}
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ Repository for the Microservices API backend of the TerraMatch service
* On Linux systems, the DOCKER_HOST value should be `unix:///var/run/docker.sock` instead of what's in the sample.
* To run all services:
* `nx run-many -t serve`
* The default maximum number of services it can run in parallel is 3. To run all of the services at once, use something like
`nx run-many --parallel=100 -t serve`, or you can cherry-pick which services you want to run instead with
`nx run-many -t serve --projects user-service jobs-service`.
* Some useful targets have been added to the root `package.json` for service sets. For instance, to run just the services needed
by the TM React front end, use `npm run fe-services`, or to run all use `npm run all`.
* In `.env` in your `wri-terramatch-website` repository, set your BE connection URL correctly by noting the config
in `.env.local.sample` for local development.
* The `NEXT_PUBLIC_API_BASE_URL` still points at the PHP BE directly
Expand All @@ -38,6 +43,8 @@ and main branches.
* In your local web repo, follow directions in `README.md` for setting up a new service.
* For deployment to AWS:
* Add a Dockerfile in the new app directory. A simple copy and modify from user-service is sufficient
* Add the new service name to the "service" workflow input options in `deploy-service.yml`
* Add a new job to `deploy-services.yml` to include the new services in the "all" service deployment workflow.
* In AWS:
* Add ECR repositories for each env (follow the naming scheme from user-service, e.g. `terramatch-microservices/foo-service-staging`, etc)
* Set the repo to Immutable
Expand Down
24 changes: 9 additions & 15 deletions apps/job-service/src/jobs/dto/delayed-job.dto.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,27 @@
import { JsonApiAttributes } from '@terramatch-microservices/common/dto/json-api-attributes';
import { JsonApiDto } from '@terramatch-microservices/common/decorators';
import { ApiProperty } from '@nestjs/swagger';
import { DelayedJob } from '@terramatch-microservices/database/entities';
import { JSON } from 'sequelize';
import { JsonApiAttributes } from "@terramatch-microservices/common/dto/json-api-attributes";
import { JsonApiDto } from "@terramatch-microservices/common/decorators";
import { ApiProperty } from "@nestjs/swagger";

const STATUSES = ['pending', 'failed', 'succeeded']
const STATUSES = ["pending", "failed", "succeeded"];
type Status = (typeof STATUSES)[number];

@JsonApiDto({ type: 'delayedJobs' })
@JsonApiDto({ type: "delayedJobs" })
export class DelayedJobDto extends JsonApiAttributes<DelayedJobDto> {
constructor(job: DelayedJob) {
const { status, statusCode, payload } = job;
super({ status, statusCode, payload });
}

@ApiProperty({
description: 'The current status of the job. If the status is not pending, the payload and statusCode will be provided.',
description:
"The current status of the job. If the status is not pending, the payload and statusCode will be provided.",
enum: STATUSES
})
status: Status;

@ApiProperty({
description: 'If the job is out of pending state, this is the HTTP status code for the completed process',
description: "If the job is out of pending state, this is the HTTP status code for the completed process",
nullable: true
})
statusCode: number | null;

@ApiProperty({
description: 'If the job is out of pending state, this is the JSON payload for the completed process',
description: "If the job is out of pending state, this is the JSON payload for the completed process",
nullable: true
})
payload: object | null;
Expand Down
28 changes: 13 additions & 15 deletions apps/job-service/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
import { Logger, ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { Logger, ValidationPipe } from "@nestjs/common";
import { NestFactory } from "@nestjs/core";

import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { TMLogService } from '@terramatch-microservices/common/util/tm-log.service';
import { AppModule } from './app.module';
import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger";
import { TMLogService } from "@terramatch-microservices/common/util/tm-log.service";
import { AppModule } from "./app.module";

async function bootstrap() {
const app = await NestFactory.create(AppModule);

if (process.env.NODE_ENV === 'development') {
if (process.env.NODE_ENV === "development") {
// CORS is handled by the Api Gateway in AWS
app.enableCors();
}

const config = new DocumentBuilder()
.setTitle('TerraMatch Job Service')
.setDescription('APIs related to delayed jobs')
.setVersion('1.0')
.addTag('job-service')
.setTitle("TerraMatch Job Service")
.setDescription("APIs related to delayed jobs")
.setVersion("1.0")
.addTag("job-service")
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('job-service/documentation/api', app, document);
SwaggerModule.setup("job-service/documentation/api", app, document);

app.useGlobalPipes(new ValidationPipe());
app.useGlobalPipes(new ValidationPipe({ transform: true, transformOptions: { enableImplicitConversion: true } }));
app.useLogger(app.get(TMLogService));

const port = process.env.NODE_ENV === 'production'
? 80
: process.env.JOB_SERVICE_PORT ?? 4020;
const port = process.env.NODE_ENV === "production" ? 80 : process.env.JOB_SERVICE_PORT ?? 4020;
await app.listen(port);

Logger.log(`TerraMatch Job Service is running on: http://localhost:${port}`);
Expand Down
18 changes: 18 additions & 0 deletions apps/research-service-e2e/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": ["../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
19 changes: 19 additions & 0 deletions apps/research-service-e2e/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* eslint-disable */
export default {
displayName: 'research-service-e2e',
preset: '../../jest.preset.js',
globalSetup: '<rootDir>/src/support/global-setup.ts',
globalTeardown: '<rootDir>/src/support/global-teardown.ts',
setupFiles: ['<rootDir>/src/support/test-setup.ts'],
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': [
'ts-jest',
{
tsconfig: '<rootDir>/tsconfig.spec.json',
},
],
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/research-service-e2e',
};
17 changes: 17 additions & 0 deletions apps/research-service-e2e/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "research-service-e2e",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"implicitDependencies": ["research-service"],
"targets": {
"e2e": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{e2eProjectRoot}"],
"options": {
"jestConfig": "apps/research-service-e2e/jest.config.ts",
"passWithNoTests": true
},
"dependsOn": ["research-service:build"]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import axios from 'axios';

describe('GET /api', () => {
it('should return a message', async () => {
const res = await axios.get(`/api`);

expect(res.status).toBe(200);
expect(res.data).toEqual({ message: 'Hello API' });
});
});
10 changes: 10 additions & 0 deletions apps/research-service-e2e/src/support/global-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* eslint-disable */
var __TEARDOWN_MESSAGE__: string;

module.exports = async function () {
// Start services that that the app needs to run (e.g. database, docker-compose, etc.).
console.log('\nSetting up...\n');

// Hint: Use `globalThis` to pass variables to global teardown.
globalThis.__TEARDOWN_MESSAGE__ = '\nTearing down...\n';
};
7 changes: 7 additions & 0 deletions apps/research-service-e2e/src/support/global-teardown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* eslint-disable */

module.exports = async function () {
// Put clean up logic here (e.g. stopping services, docker-compose, etc.).
// Hint: `globalThis` is shared between setup and teardown.
console.log(globalThis.__TEARDOWN_MESSAGE__);
};
10 changes: 10 additions & 0 deletions apps/research-service-e2e/src/support/test-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* eslint-disable */

import axios from 'axios';

module.exports = async function () {
// Configure axios for tests to use.
const host = process.env.HOST ?? 'localhost';
const port = process.env.PORT ?? '3000';
axios.defaults.baseURL = `http://${host}:${port}`;
};
13 changes: 13 additions & 0 deletions apps/research-service-e2e/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "../../tsconfig.base.json",
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.spec.json"
}
],
"compilerOptions": {
"esModuleInterop": true
}
}
9 changes: 9 additions & 0 deletions apps/research-service-e2e/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": ["jest.config.ts", "src/**/*.ts"]
}
18 changes: 18 additions & 0 deletions apps/research-service/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": ["../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
15 changes: 15 additions & 0 deletions apps/research-service/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM terramatch-microservices-base:nx-base AS builder

ARG BUILD_FLAG
WORKDIR /app/builder
COPY . .
RUN npx nx build research-service ${BUILD_FLAG}

FROM terramatch-microservices-base:nx-base

ARG NODE_ENV
WORKDIR /app
COPY --from=builder /app/builder ./
ENV NODE_ENV=${NODE_ENV}

CMD ["node", "./dist/apps/research-service/main.js"]
12 changes: 12 additions & 0 deletions apps/research-service/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* eslint-disable */
export default {
displayName: "research-service",
preset: "../../jest.preset.js",
testEnvironment: "node",
transform: {
"^.+\\.[tj]s$": ["ts-jest", { tsconfig: "<rootDir>/tsconfig.spec.json" }]
},
moduleFileExtensions: ["ts", "js", "html"],
coveragePathIgnorePatterns: [".dto.ts"],
coverageDirectory: "../../coverage/apps/research-service"
};
Loading

0 comments on commit 3b17b4e

Please sign in to comment.