From 50409f0c481857c210a1efaff655455a46830e0c Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Wed, 3 Jul 2024 14:41:47 +0200 Subject: [PATCH] Feat: Standalone migration mode --- .github/workflows/build-binaries.yml | 10 ++++---- backend/src/lib/fn/argv.ts | 34 ++++++++++++++++++++++++++++ backend/src/lib/fn/index.ts | 1 + backend/src/main.ts | 22 +++++++++++++++++- 4 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 backend/src/lib/fn/argv.ts diff --git a/.github/workflows/build-binaries.yml b/.github/workflows/build-binaries.yml index 6e9f605b0..579532d24 100644 --- a/.github/workflows/build-binaries.yml +++ b/.github/workflows/build-binaries.yml @@ -6,8 +6,8 @@ on: # - daniel/infisical-binary push: - # branches: - # - daniel/infisical-binary + branches: + - daniel/infisical-binary # run for standalone releases tags: @@ -52,7 +52,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v3 with: - node-version: 18 + node-version: 20 - name: Install pkg run: npm install -g @yao-pkg/pkg @@ -69,8 +69,8 @@ jobs: run: npm run binary:build working-directory: ./backend - - name: Package into node binary - run: pkg --no-bytecode --public-packages "*" --public --compress Brotli --target ${{ matrix.target }}-${{ matrix.arch }} --output ./binary/infisical-${{ matrix.os }}-${{ matrix.arch }} . + - name: Package into node binary # --compress Brotli (Re-add before merging to main!) + run: pkg --no-bytecode --public-packages "*" --public --target ${{ matrix.target }}-${{ matrix.arch }} --output ./binary/infisical-${{ matrix.os }}-${{ matrix.arch }} . working-directory: ./backend - name: List files diff --git a/backend/src/lib/fn/argv.ts b/backend/src/lib/fn/argv.ts new file mode 100644 index 000000000..d9e245b11 --- /dev/null +++ b/backend/src/lib/fn/argv.ts @@ -0,0 +1,34 @@ +import { logger } from "../logger"; + +export const isMigrationMode = () => { + try { + const args = process.argv.slice(2); + const migrationFlag = args.find((arg) => arg.startsWith("--migration-mode")); + + if (!migrationFlag) { + return false; + } + + // Covers the case where the flag is --migration-mode [true|false|...] + if (migrationFlag === "--migration-mode") { + const nextArg = args[args.indexOf(migrationFlag) + 1]; + if (nextArg === "false") { + return false; + } + // --migration-mode without a value defaults to true + return nextArg === undefined || nextArg.toLowerCase() === "true"; + } + + // Covers the case where the flag is --migration-mode=[...] + const [, value] = migrationFlag.split("="); + if (value === undefined) { + const nextArg = args[args.indexOf(migrationFlag) + 1]; + return nextArg === "true"; + } + + return value.toLowerCase() === "true"; + } catch (err) { + logger.error(err, `Failed to check migration mode`); + return false; + } +}; diff --git a/backend/src/lib/fn/index.ts b/backend/src/lib/fn/index.ts index 0d0f07e45..381ecebf3 100644 --- a/backend/src/lib/fn/index.ts +++ b/backend/src/lib/fn/index.ts @@ -1,6 +1,7 @@ // Some of the functions are taken from https://github.com/rayepps/radash // Full credits goes to https://github.com/rayapps to those functions // Code taken to keep in in house and to adjust somethings for our needs +export * from "./argv"; export * from "./array"; export * from "./dates"; export * from "./object"; diff --git a/backend/src/main.ts b/backend/src/main.ts index dac189b87..79b974988 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -1,8 +1,10 @@ import dotenv from "dotenv"; +import path from "path"; import { initDbConnection } from "./db"; import { keyStoreFactory } from "./keystore/keystore"; -import { formatSmtpConfig, initEnvConfig } from "./lib/config/env"; +import { formatSmtpConfig, initEnvConfig, IS_PACKAGED } from "./lib/config/env"; +import { isMigrationMode } from "./lib/fn"; import { initLogger } from "./lib/logger"; import { queueServiceFactory } from "./queue"; import { main } from "./server/app"; @@ -10,6 +12,7 @@ import { bootstrapCheck } from "./server/boot-strap-check"; import { smtpServiceFactory } from "./services/smtp/smtp-service"; dotenv.config(); + const run = async () => { const logger = await initLogger(); const appCfg = initEnvConfig(logger); @@ -22,12 +25,29 @@ const run = async () => { })) }); + // Case: App is running in packaged mode (binary), and migration mode is enabled. + // Run the migrations and exit the process after completion. + if (IS_PACKAGED && isMigrationMode()) { + try { + logger.info("Running Postgres migrations.."); + await db.migrate.latest({ + directory: path.join(__dirname, "./db/migrations") + }); + logger.info("Postgres migrations completed"); + } catch (err) { + logger.error(err, "Failed to run migrations"); + } + + process.exit(0); + } + const smtp = smtpServiceFactory(formatSmtpConfig()); const queue = queueServiceFactory(appCfg.REDIS_URL); const keyStore = keyStoreFactory(appCfg.REDIS_URL); const server = await main({ db, smtp, logger, queue, keyStore }); const bootstrap = await bootstrapCheck({ db }); + // eslint-disable-next-line process.on("SIGINT", async () => { await server.close();