Skip to content

Commit f6f1327

Browse files
author
DylanBulmer
committed
update file struct, readme, and ci/cd; add info api
1 parent 20713ac commit f6f1327

23 files changed

+171
-35
lines changed

.github/workflows/docker-image.yml

+11-3
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ jobs:
4646
tags: |
4747
type=ref,event=branch
4848
type=ref,event=pr
49-
type=semver,pattern=v{{version}}
50-
type=semver,pattern=v{{major}}.{{minor}}
51-
type=semver,pattern=v{{major}}
49+
type=semver,pattern={{version}}
50+
type=semver,pattern={{major}}.{{minor}}
51+
type=semver,pattern={{major}}
5252
type=sha
5353
type=raw,value=latest,enable={{is_default_branch}}
5454
@@ -73,9 +73,17 @@ jobs:
7373
uses: docker/build-push-action@v4
7474
with:
7575
context: .
76+
platforms: linux/amd64,linux/arm64
7677
push: ${{ github.event_name != 'pull_request' }}
7778
tags: ${{ steps.meta.outputs.tags }}
7879
labels: ${{ steps.meta.outputs.labels }}
80+
build-args: |
81+
VERSION=${{ github.event.release.tag_name }}
82+
GIT_REPO=${{ github.repository }}
83+
GIT_COMMIT=${{ github.sha }}
84+
GIT_BRANCH=${{ github.ref_name }}
85+
cache-from: type=registry,ref=${{ github.ref_name }}
86+
cache-to: type=inline
7987

8088
- name: Image digest
8189
run: echo ${{ steps.docker_build.outputs.digest }}

Dockerfile

+25-5
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,33 @@ RUN yarn build
1616
FROM node:16-alpine
1717
WORKDIR /usr/src
1818

19-
COPY --from=builder /usr/src/dist ./dist
20-
COPY --from=builder /usr/src/node_modules ./node_modules
21-
COPY --from=builder /usr/src/package.json ./package.json
19+
# Set up env vars
20+
ARG VERSION
21+
ARG GIT_BRANCH
22+
ARG GIT_COMMIT
23+
ARG GIT_REPO
2224

25+
ENV NODE_ENV="production"
26+
ENV VERSION=${VERSION}
27+
ENV GIT_BRANCH=${GIT_BRANCH}
28+
ENV GIT_COMMIT=${GIT_COMMIT}
29+
ENV GIT_REPO=${GIT_REPO}
30+
31+
# Set up user and group
2332
RUN addgroup -g 1001 -S nodejs
2433
RUN adduser -S service -u 1001
25-
RUN chown -R service:nodejs /usr/src/dist
34+
35+
# update owner
36+
RUN chown -R service:nodejs ./
37+
38+
# copy files
39+
COPY --chown=service:nodejs --from=builder /usr/src/dist ./dist
40+
COPY --from=builder /usr/src/node_modules ./node_modules
41+
COPY --from=builder /usr/src/package.json ./package.json
42+
43+
# use user and create logs dir
2644
USER service
45+
RUN mkdir /usr/src/logs
2746

28-
CMD ["yarn", "start"]
47+
EXPOSE 8000
48+
CMD ["yarn", "start"]

README.md

+31
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,37 @@ docker pull ghcr.io/codrjs/codr-user-user:latest
2323

2424
- [ ] None
2525

26+
## Environment
27+
28+
Necessary variables needed to run:
29+
30+
| Env var | Location | Required | Description |
31+
| ---------------------- | ---------------------- | -------- | --------------------------------------------------------------------------------------- |
32+
| `ENV` | `env` | `true` | Deployment envionment - `dev`, `qa`, `stage`, `prod` |
33+
| `EXPRESS_HOST` | `express.host` | `false` | Express server - listener host |
34+
| `EXPRESS_PORT` | `express.port` | `false` | Express server - listener port |
35+
| `MONGO_URI` | `mongo.uri` | `true` | MongoDB - server URL, please include username and password to this string |
36+
| `KAFKA_BROKERS` | `kafka.brokers` | `true` | Kafka server - comma seperated locations of the kafka brokers |
37+
| `KAFKA_CLIENT_ID` | `kafka.clientId` | `true` | Kafka server - name of the kafka cluster |
38+
| `KAFKA_CONSUMER_GROUP` | `kafka.consumer.group` | `true` | Kafka server - consumer group |
39+
| `JWT_SECRET` | `jwt.secret` | `false` | JWT - secret, key to decode jwt, must be the same across all services in an environment |
40+
| `JWT_ISSUER` | `jwt.issuer` | `false` | JWT - issuer, default `codrjs.com` |
41+
42+
Environment variables provided by CI/CD
43+
44+
| Env var | Location | Description |
45+
| ----------------- | ------------------ | --------------------------------------------------------- |
46+
| `HOSTNAME` | `hostname` | Deployment docker hostname |
47+
| Provided via npm | `name` | Deployment service name - example: codr-user-user |
48+
| Provided via npm | `version` | Deployment version - example: `1.0.0` |
49+
| `GIT_BRANCH` | `git.brach` | Git - branch |
50+
| `GIT_COMMIT` | `git.commit` | Git - commit sha |
51+
| `GIT_REPO` | `git.repo` | Git - repository |
52+
| `NODE_ENV` | `node.env` | Node environment - `development`, `production`, `testing` |
53+
| Provided via npm | `node.verison` | Node version - example: `16.19.1` |
54+
| Provided via npm | `node.modules` | Node modules - string array of all dependencies |
55+
| Provided via yarn | `node.yarnVersion` | Node - package manager version |
56+
2657
## Contributing
2758

2859
```bash

package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "codr-user-user",
33
"private": true,
4-
"version": "1.0.1",
4+
"version": "1.0.2",
55
"scripts": {
66
"start": "node dist/serve.js",
77
"build": "swc ./src -d dist",
@@ -27,11 +27,11 @@
2727
"dependencies": {
2828
"@casl/ability": "^6.3.3",
2929
"@casl/mongoose": "^7.1.2",
30-
"@codrjs/config": "^1.0.0",
30+
"@codrjs/config": "^1.0.4",
3131
"@codrjs/health": "^1.0.3",
3232
"@codrjs/kafka": "^1.0.2",
3333
"@codrjs/logger": "^1.0.0",
34-
"@codrjs/models": "^1.0.3",
34+
"@codrjs/models": "^1.0.6",
3535
"@dylanbulmer/openapi": "^1.0.7",
3636
"body-parser": "^1.20.1",
3737
"cors": "^2.8.5",

src/serve.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Kafka, Express, Mongo } from "./server";
2+
import "@codrjs/config";
23

34
Mongo.start();
45
// Kafka.start();

src/server/express/api/api-doc.ts src/server/express/api/v1/api-doc.ts

+11-9
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,25 @@ import {
1717
GenericSchema,
1818
HealthSchema,
1919
UserEntitySchema,
20+
MetadataSchema,
2021
} from "./schemas";
2122
import { BearerScheme } from "./schemes";
23+
import { OpenAPI } from "@codrjs/models";
24+
import Config from "@codrjs/config";
25+
26+
const OpenAPIConfig = new OpenAPI();
27+
console.log(Config.openapi);
2228

2329
const settings: OpenAPIV3_1.Document = {
2430
openapi: "3.1.0",
2531

2632
// The servers property breaks all apis for some reason
27-
servers: [
28-
{
29-
url: `http://localhost:8000/api/`,
30-
description: "Dev Server",
31-
},
32-
],
33+
servers: OpenAPIConfig.servers,
3334

3435
info: {
35-
version: "1.0.0",
36-
title: "User Entity API",
37-
description: "Preform CRUD operations on the user collection in Mongo.",
36+
version: Config.version ?? "Unknown",
37+
title: OpenAPIConfig.info.title,
38+
description: OpenAPIConfig.info.description,
3839
contact: {
3940
name: "Dylan Bulmer",
4041
url: "https://codrjs.com",
@@ -68,6 +69,7 @@ const settings: OpenAPIV3_1.Document = {
6869
GenericSchema,
6970
HealthSchema,
7071
UserEntitySchema,
72+
MetadataSchema,
7173
},
7274
securitySchemes: {
7375
Bearer: BearerScheme,
File renamed without changes.
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Operation } from "@dylanbulmer/openapi/types/Route";
2+
import { R200 } from "@dylanbulmer/openapi/classes/responses";
3+
import { Metadata } from "@codrjs/models";
4+
5+
export const GET: Operation =
6+
/* business middleware not expressible by OpenAPI documentation goes here */
7+
(_req, res) => {
8+
res.status(200).json(new Metadata());
9+
};
10+
11+
// 3.0 specification
12+
GET.apiDoc = {
13+
description: "Get the server deployment info",
14+
tags: ["System"],
15+
responses: {
16+
"200": {
17+
description: R200.description,
18+
content: {
19+
"application/json": {
20+
schema: {
21+
$ref: "#/components/schemas/MetadataSchema",
22+
},
23+
},
24+
},
25+
},
26+
},
27+
};

src/server/express/api/routes/user/[userId].ts src/server/express/api/v1/routes/user/[userId].ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Error } from "@codrjs/models";
22
import { Operation } from "@dylanbulmer/openapi/types/Route";
3-
import verifyJWT from "../../../middlewares/verifyJWT";
3+
import verifyJWT from "../../../../middlewares/verifyJWT";
44
import { UserUtility } from "@/utils/UserUtility";
55
import { R200, R401, R403, R500 } from "@dylanbulmer/openapi/classes/responses";
66

src/server/express/api/routes/user/index.ts src/server/express/api/v1/routes/user/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Error } from "@codrjs/models";
22
import { Operation } from "@dylanbulmer/openapi/types/Route";
3-
import verifyJWT from "../../../middlewares/verifyJWT";
4-
import { UserUtility } from "../../../../../utils/UserUtility";
3+
import verifyJWT from "../../../../middlewares/verifyJWT";
4+
import { UserUtility } from "../../../../../../utils/UserUtility";
55
import { R201, R401, R403, R500 } from "@dylanbulmer/openapi/classes/responses";
66

77
export const POST: Operation = [
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import type { OpenAPIV3_1 } from "openapi-types";
2+
3+
const HealthSchema: OpenAPIV3_1.SchemaObject = {
4+
title: "Metadata Schema",
5+
properties: {
6+
env: {
7+
type: "string",
8+
examples: ["dev", "qa", "stage", "prod"],
9+
default: "dev",
10+
},
11+
version: {
12+
type: "string",
13+
},
14+
name: {
15+
type: "string",
16+
},
17+
node: {
18+
type: "object",
19+
properties: {
20+
env: {
21+
type: "string",
22+
examples: ["development", "production", "testing"],
23+
default: "production",
24+
},
25+
version: {
26+
type: "string",
27+
},
28+
modules: {
29+
type: "object",
30+
},
31+
yarnVersion: {
32+
type: "string",
33+
},
34+
},
35+
},
36+
docker: {
37+
type: "object",
38+
properties: {
39+
hostname: { type: "string" },
40+
},
41+
},
42+
},
43+
};
44+
45+
export default HealthSchema;

src/server/express/api/schemas/index.ts src/server/express/api/v1/schemas/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ export { default as ErrorSchema } from "./Error";
33
export { default as GenericSchema } from "./Generic";
44
export { default as HealthSchema } from "./Health";
55
export { default as UserEntitySchema } from "./User";
6+
export { default as MetadataSchema } from "./Metadata";

src/server/express/index.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import express, { Express } from "express";
22
import bodyParser from "body-parser";
33
import cors from "cors";
44
import config from "@codrjs/config";
5-
import v1 from "./api";
5+
import v1 from "./api/v1";
66
import morgan from "./middlewares/morgan.middleware";
77
import { Error } from "@codrjs/models";
88
import ExpressLogger from "./utils/logger";
@@ -17,7 +17,7 @@ app.use(cors());
1717
app.use(bodyParser.json());
1818
app.use(morgan);
1919

20-
app.use("/api", v1);
20+
app.use("/v1", v1);
2121

2222
app.use(((err, req, res, next) => {
2323
// if headers are already sent, let express handler the error
@@ -26,7 +26,7 @@ app.use(((err, req, res, next) => {
2626
}
2727

2828
// if the path is for the API, have it handle the error
29-
if (req.path.startsWith("/api")) {
29+
if (req.path.startsWith("/v1")) {
3030
return v1.get("errorHandler")(err, req, res, next);
3131
}
3232

@@ -38,7 +38,7 @@ app.use((req, res, next) => {
3838
// catch 404 errors?
3939

4040
// if the path is for API v1, have v1 handler the error
41-
if (req.path.startsWith("/api")) {
41+
if (req.path.startsWith("/v1")) {
4242
const err = new Error({ status: 404, message: `not found: ${req.path}` });
4343
return v1.get("errorHandler")(err, req, res, next);
4444
}

yarn.lock

+9-8
Original file line numberDiff line numberDiff line change
@@ -311,10 +311,10 @@
311311
resolved "https://registry.yarnpkg.com/@casl/mongoose/-/mongoose-7.1.2.tgz#61e86839ee19df8443158f44b10cbbe5137ed1fb"
312312
integrity sha512-YiY5gQlr5J0jsn0ZbjtDJEhqKviPyPj0ErZ2bnOh7li+ENvFMnfp5ZeF2wN7ZVcqK9mn4MCqWH56EzafRF3i+g==
313313

314-
"@codrjs/config@^1.0.0":
315-
version "1.0.0"
316-
resolved "https://registry.yarnpkg.com/@codrjs/config/-/config-1.0.0.tgz#90dd9367da77976cc685cf82c344823115753ed5"
317-
integrity sha512-KWN7lzW7D7+ysyYYTh+TXf8RZVVMF46umyf19k/ytH3vInDSWSBDiLZ7UaUIIiT1kqAkILYd8FFYUNHBzgZOSg==
314+
"@codrjs/config@^1.0.4":
315+
version "1.0.4"
316+
resolved "https://registry.yarnpkg.com/@codrjs/config/-/config-1.0.4.tgz#1547da95a2e2f694687b42338f30b6a46f7951c2"
317+
integrity sha512-nMW36MvOES84lTjfWTmOCqRnXL+YQFH8fXCNCSjupKkC+3nonVL5GbTctuEHB/NPKiXQR093LEab/OEp2JVLtA==
318318
dependencies:
319319
dotenv "^16.0.3"
320320

@@ -340,12 +340,13 @@
340340
dependencies:
341341
winston "^3.8.2"
342342

343-
"@codrjs/models@^1.0.3":
344-
version "1.0.3"
345-
resolved "https://registry.yarnpkg.com/@codrjs/models/-/models-1.0.3.tgz#7be6a70c6f6b44e047d0afb32300d8340588dc23"
346-
integrity sha512-hD5yWR2GY1gXdHMMdzwt7xfnqPVr7IPNxrdUo0CArxGabXgeFRPkSboWd2Jyit9erU4BlMl6Gi/lhhgLgeLFCA==
343+
"@codrjs/models@^1.0.6":
344+
version "1.0.6"
345+
resolved "https://registry.yarnpkg.com/@codrjs/models/-/models-1.0.6.tgz#68d2a78b1a680fcecf21128570ebc0fa863100fa"
346+
integrity sha512-qqDwa6t//VM+p+j8x3XlKdnTGMN3JZrFmJnrT9jUjIRtV/kh6MTBee99LB31R+FWYimVULSAtXbOc5LF0bA7+Q==
347347
dependencies:
348348
"@casl/ability" "^6.3.3"
349+
"@codrjs/config" "^1.0.4"
349350
uuid "^9.0.0"
350351

351352

0 commit comments

Comments
 (0)