From 261c9153b035fc22f0b6c836ee9839ca9d60c0de Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Wed, 19 Oct 2022 11:35:39 +0800 Subject: [PATCH] ci: add docker build to main workflow (#2184) --- .github/workflows/main.yml | 16 ++++++ Dockerfile | 3 +- packages/cli/src/commands/connector/utils.ts | 38 ++++++++----- .../commands/database/alteration/version.ts | 54 ++++++++++++------- packages/cli/src/commands/install/utils.ts | 19 ++++++- packages/cli/src/utilities.ts | 26 ++++----- 6 files changed, 101 insertions(+), 55 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 96cec9aea..44d0150b9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -70,3 +70,19 @@ jobs: with: flags: ui directory: ./packages/ui + + main-dockerize: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build + uses: docker/build-push-action@v3 + with: + context: . diff --git a/Dockerfile b/Dockerfile index 4fa529bb3..81641a922 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,8 +14,7 @@ RUN pnpm i RUN pnpm -r build # Add official connectors -WORKDIR /etc/logto -RUN pnpm cli connector add --official +RUN pnpm cli connector add --official -p . # Prune dependencies for production RUN rm -rf node_modules packages/*/node_modules diff --git a/packages/cli/src/commands/connector/utils.ts b/packages/cli/src/commands/connector/utils.ts index 48e876c7c..1d1f2a476 100644 --- a/packages/cli/src/commands/connector/utils.ts +++ b/packages/cli/src/commands/connector/utils.ts @@ -4,7 +4,7 @@ import { readFile, mkdir, unlink, readdir } from 'fs/promises'; import path from 'path'; import { promisify } from 'util'; -import { conditionalString } from '@silverhand/essentials'; +import { assert, conditionalString } from '@silverhand/essentials'; import chalk from 'chalk'; import { ensureDir, remove } from 'fs-extra'; import inquirer from 'inquirer'; @@ -13,7 +13,7 @@ import tar from 'tar'; import { z } from 'zod'; import { connectorDirectory } from '../../constants'; -import { log, oraPromise } from '../../utilities'; +import { isTty, log, oraPromise } from '../../utilities'; import { defaultPath } from '../install/utils'; const coreDirectory = 'packages/core'; @@ -51,19 +51,29 @@ const validatePath = async (value: string) => { }; export const inquireInstancePath = async (initialPath?: string) => { - const { instancePath } = await inquirer.prompt<{ instancePath: string }>( - { - name: 'instancePath', - message: 'Where is your Logto instance?', - type: 'input', - default: defaultPath, - filter: (value: string) => value.trim(), - validate: validatePath, - }, - { instancePath: initialPath } - ); + const inquire = async () => { + if (!isTty()) { + assert(initialPath, new Error('Path is missing')); - // Validate for initialPath + return initialPath; + } + + const { instancePath } = await inquirer.prompt<{ instancePath: string }>( + { + name: 'instancePath', + message: 'Where is your Logto instance?', + type: 'input', + default: defaultPath, + filter: (value: string) => value.trim(), + validate: validatePath, + }, + { instancePath: initialPath } + ); + + return instancePath; + }; + + const instancePath = await inquire(); const validated = await validatePath(instancePath); if (validated !== true) { diff --git a/packages/cli/src/commands/database/alteration/version.ts b/packages/cli/src/commands/database/alteration/version.ts index befde14d0..ffc0b38ae 100644 --- a/packages/cli/src/commands/database/alteration/version.ts +++ b/packages/cli/src/commands/database/alteration/version.ts @@ -1,9 +1,9 @@ -import { conditional } from '@silverhand/essentials'; +import { assert, conditional } from '@silverhand/essentials'; import chalk from 'chalk'; import inquirer from 'inquirer'; import { SemVer, compare, eq, gt } from 'semver'; -import { findLastIndex, log } from '../../../utilities'; +import { findLastIndex, isTty, log } from '../../../utilities'; import { AlterationFile } from './type'; const getVersionFromFilename = (filename: string) => { @@ -45,28 +45,42 @@ export const chooseAlterationsByVersion = async ( const initialSemVersion = conditional( initialVersion && initialVersion !== latestTag && new SemVer(initialVersion) ); + const firstVersion = versions[0]; - if (!versions[0]) { + if (!firstVersion) { return []; } - const { version: targetVersion } = - initialVersion === latestTag - ? { version: versions[0] } - : await inquirer.prompt<{ version: SemVer }>( - { - type: 'list', - message: 'Choose the alteration target version', - name: 'version', - choices: versions.map((semVersion) => ({ - name: semVersion.version, - value: semVersion, - })), - }, - { - version: initialSemVersion, - } - ); + const getTargetVersion = async () => { + if (initialVersion === latestTag) { + return firstVersion; + } + + if (!isTty()) { + assert(initialSemVersion, new Error('Missing target version')); + + return initialSemVersion; + } + + const { version } = await inquirer.prompt<{ version: SemVer }>( + { + type: 'list', + message: 'Choose the alteration target version', + name: 'version', + choices: versions.map((semVersion) => ({ + name: semVersion.version, + value: semVersion, + })), + }, + { + version: initialSemVersion, + } + ); + + return version; + }; + + const targetVersion = await getTargetVersion(); log.info(`Deploy target ${chalk.green(targetVersion.version)}`); diff --git a/packages/cli/src/commands/install/utils.ts b/packages/cli/src/commands/install/utils.ts index 9776eec63..e21d7ee0e 100644 --- a/packages/cli/src/commands/install/utils.ts +++ b/packages/cli/src/commands/install/utils.ts @@ -4,6 +4,7 @@ import { mkdir } from 'fs/promises'; import os from 'os'; import path from 'path'; +import { assert } from '@silverhand/essentials'; import chalk from 'chalk'; import { remove, writeFile } from 'fs-extra'; import inquirer from 'inquirer'; @@ -11,7 +12,15 @@ import * as semver from 'semver'; import tar from 'tar'; import { createPoolAndDatabaseIfNeeded } from '../../database'; -import { cliConfig, ConfigKey, downloadFile, log, oraPromise, safeExecSync } from '../../utilities'; +import { + cliConfig, + ConfigKey, + downloadFile, + isTty, + log, + oraPromise, + safeExecSync, +} from '../../utilities'; import { seedByPool } from '../database/seed'; export const defaultPath = path.join(os.homedir(), 'logto'); @@ -38,6 +47,12 @@ const validatePath = (value: string) => : true; export const inquireInstancePath = async (initialPath?: string) => { + if (!isTty()) { + assert(initialPath, new Error('Path is missing')); + + return initialPath; + } + const { instancePath } = await inquirer.prompt<{ instancePath: string }>( { name: 'instancePath', @@ -61,7 +76,7 @@ export const inquireInstancePath = async (initialPath?: string) => { }; export const validateDatabase = async () => { - if (cliConfig.has(ConfigKey.DatabaseUrl)) { + if (cliConfig.has(ConfigKey.DatabaseUrl) || !isTty()) { return; } diff --git a/packages/cli/src/utilities.ts b/packages/cli/src/utilities.ts index 62b14efb7..d6196c408 100644 --- a/packages/cli/src/utilities.ts +++ b/packages/cli/src/utilities.ts @@ -108,6 +108,8 @@ export const oraPromise = async ( } }; +export const isTty = () => process.stdin.isTTY; + export enum ConfigKey { DatabaseUrl = 'DB_URL', } @@ -127,26 +129,16 @@ export const getCliConfigWithPrompt = async ({ comments, defaultValue, }: GetCliConfigWithPrompt) => { - if (cliConfig.has(key)) { + if (cliConfig.has(key) || !isTty()) { return cliConfig.get(key); } - const { input } = await inquirer - .prompt<{ input?: string }>({ - type: 'input', - name: 'input', - message: `Enter your ${readableKey}${conditionalString(comments && ' ' + comments)}`, - default: defaultValue, - }) - .catch(async (error) => { - if (error.isTtyError) { - log.error(`No ${readableKey} (${chalk.green(key)}) configured in option nor env`); - } - - // The type definition does not give us type except `any`, throw it directly will honor the original behavior. - // eslint-disable-next-line @typescript-eslint/no-throw-literal - throw error; - }); + const { input } = await inquirer.prompt<{ input?: string }>({ + type: 'input', + name: 'input', + message: `Enter your ${readableKey}${conditionalString(comments && ' ' + comments)}`, + default: defaultValue, + }); cliConfig.set(key, input);