From 9c7b3aca222a7458f012b8514c667ab6ba243aae Mon Sep 17 00:00:00 2001 From: "Kees C. Bakker" Date: Sat, 2 Sep 2023 10:17:52 +0200 Subject: [PATCH] Harmonize bot setup with internal projects --- Dockerfile | 41 ++++++++++++++++++++++++++++++++++------- package.json | 9 ++++++++- src/common/BotZero.ts | 19 ++++++++++++++++++- src/env.ts | 5 +++-- src/index.ts | 15 ++++++++++----- 5 files changed, 73 insertions(+), 16 deletions(-) diff --git a/Dockerfile b/Dockerfile index fad63bf..9d91235 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,40 @@ -FROM node:18-alpine +FROM node:20-alpine as base + +RUN echo "" \ + && echo "------------------------" \ + && echo "1/4 INSTALL DEPENDENCIES" \ + && echo "------------------------" WORKDIR /bot-zero -COPY package.json . -COPY package-lock.json . +COPY *.json ./ -RUN npm ci --omit=dev +FROM base as build + +RUN echo "" \ + && echo "--------------" \ + && echo "2/4 COPY FILES" \ + && echo "--------------" COPY src ./src -COPY *.json . -COPY external-scripts.json ./dist/external-scripts.json -CMD ["npm", "start"] \ No newline at end of file +RUN echo "" \ + && echo "-----------" \ + && echo "3/4 TESTING" \ + && echo "-----------" \ + && npm ci \ + && npm test \ + && npm run build + +FROM base as final + +COPY --from=build /bot-zero/dist ./dist + +RUN echo "" \ + && echo "---------------" \ + && echo "4/4 FINAL IMAGE" \ + && echo "---------------" + +ENV NODE_ENV=production +RUN npm ci --omit=dev + +ENTRYPOINT ["npm", "start"] diff --git a/package.json b/package.json index a7dd0b5..b35ae1a 100644 --- a/package.json +++ b/package.json @@ -16,10 +16,17 @@ "hubot": "^7.0.0", "hubot-command-mapper": "^8.0.1", "node-fetch": "^2.6.12", + "pino": "^8.15.0", + "pino-pretty": "^10.2.0", "remove-markdown": "^0.5.0", - "ts-node": "^10.9.1" + "source-map-support": "^0.5.21" }, "devDependencies": { + "@slack/bolt": "^3.13.3", + "@slack/web-api": "^6.9.0", + "@types/node": "^20.5.1", + "@types/node-fetch": "^3.0.2", + "@types/remove-markdown": "^0.3.1", "prettier": "^3.0.2", "ts-node-dev": "^2.0.0" }, diff --git a/src/common/BotZero.ts b/src/common/BotZero.ts index 0f91fcb..b8c525f 100644 --- a/src/common/BotZero.ts +++ b/src/common/BotZero.ts @@ -1,5 +1,6 @@ import fs from "fs" import path from "path" +import pino from "pino" import { createUpdatableMessage, UpdatableMessage } from "./UpdatableMessage" import { createWebClient, uploadByContext } from "./slack" import { IContext } from "hubot-command-mapper" @@ -40,13 +41,29 @@ class MyBotZero extends Robot { await bot.loadAdapter() + if (process.env.TS_NODE_DEV || process.env.ENVIRONMENT == "local") { + bot.logger = pino({ + name: bot.name, + level: process.env.HUBOT_LOG_LEVEL || "warn", + transport: { + target: "pino-pretty", + }, + }) + + Reflect.defineProperty(bot.logger, "warning", { + value: bot.logger.warn, + enumerable: true, + configurable: true, + }) + } + this.app = bot.adapter.socket this.client = bot.adapter.client.web // Read all files in the scripts directory let files = await fs.promises.readdir(scriptsDir) files - .filter(file => path.extname(file) == ".ts") + .filter(file => path.extname(file) == ".ts" || path.extname(file) == ".js") .sort() .map(file => path.resolve(scriptsDir, file)) .forEach(file => { diff --git a/src/env.ts b/src/env.ts index 1df3733..4cfdc82 100644 --- a/src/env.ts +++ b/src/env.ts @@ -1,13 +1,14 @@ import { chalker } from "chalk-with-markers" -export function validateConfg() { +export function validateConfig() { validateToken("HUBOT_SLACK_BOT_TOKEN", "xoxb-") validateToken("HUBOT_SLACK_APP_TOKEN", "xapp-") } function validateToken(name: string, format: "xoxb-" | "xapp-") { const envMsg = - "your environment variables (for production) or to your .env file (for local development). You can find your Slack apps here: https://api.slack.com/apps" + "your environment variables (for production) or to your .env file (for local development). " + + "You can find your Slack apps here: https://api.slack.com/apps" const token = process.env[name] diff --git a/src/index.ts b/src/index.ts index f2d257f..ca5f416 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,11 @@ import dotenv from "dotenv" -import { validateConfg } from "./env" +import { validateConfig } from "./env" dotenv.config() -validateConfg() +validateConfig() import path from "path" -import { asciiArtChalker, chalker } from "chalk-with-markers" import removeMarkDown from "remove-markdown" +import { asciiArtChalker, chalker } from "chalk-with-markers" import { removeTrailingBotWhitespaceCharactersFromIncomingMessages, removeTrailingWhitespaceCharactersFromIncomingMessages @@ -14,8 +14,13 @@ import { start } from "./common/BotZero" // start bot async ;(async () => { + process.on("SIGTERM", () => process.exit()) + let scriptsPath = path.join(__dirname, "scripts") - let externalScriptsJsonFile = path.join(__dirname, "..", "external-scripts.json") + let externalScriptsJsonFile = process.env.TS_NODE_DEV + ? path.join(__dirname, "..", "external-scripts.json") + : path.join(__dirname, "..", "..", "external-scripts.json") + let { info, robot } = await start(scriptsPath, externalScriptsJsonFile) // register middleware @@ -52,7 +57,7 @@ ccc \\/ c \\/ \\/ console.log("⚡ Powered with Slack Bolt + Hubot Command Mapper ⚡") } -export function removeMarkdownFromInput(robot: Hubot.Robot) { +function removeMarkdownFromInput(robot: Hubot.Robot) { if (!robot) throw "Argument 'robot' is empty." robot.receiveMiddleware((context, next, done) => {