mirror of
https://github.com/logto-io/logto.git
synced 2024-12-30 20:33:54 -05:00
ci: add docker build to main workflow (#2184)
This commit is contained in:
parent
38f664c27c
commit
261c9153b0
6 changed files with 101 additions and 55 deletions
16
.github/workflows/main.yml
vendored
16
.github/workflows/main.yml
vendored
|
@ -70,3 +70,19 @@ jobs:
|
||||||
with:
|
with:
|
||||||
flags: ui
|
flags: ui
|
||||||
directory: ./packages/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: .
|
||||||
|
|
|
@ -14,8 +14,7 @@ RUN pnpm i
|
||||||
RUN pnpm -r build
|
RUN pnpm -r build
|
||||||
|
|
||||||
# Add official connectors
|
# Add official connectors
|
||||||
WORKDIR /etc/logto
|
RUN pnpm cli connector add --official -p .
|
||||||
RUN pnpm cli connector add --official
|
|
||||||
|
|
||||||
# Prune dependencies for production
|
# Prune dependencies for production
|
||||||
RUN rm -rf node_modules packages/*/node_modules
|
RUN rm -rf node_modules packages/*/node_modules
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { readFile, mkdir, unlink, readdir } from 'fs/promises';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { promisify } from 'util';
|
import { promisify } from 'util';
|
||||||
|
|
||||||
import { conditionalString } from '@silverhand/essentials';
|
import { assert, conditionalString } from '@silverhand/essentials';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import { ensureDir, remove } from 'fs-extra';
|
import { ensureDir, remove } from 'fs-extra';
|
||||||
import inquirer from 'inquirer';
|
import inquirer from 'inquirer';
|
||||||
|
@ -13,7 +13,7 @@ import tar from 'tar';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { connectorDirectory } from '../../constants';
|
import { connectorDirectory } from '../../constants';
|
||||||
import { log, oraPromise } from '../../utilities';
|
import { isTty, log, oraPromise } from '../../utilities';
|
||||||
import { defaultPath } from '../install/utils';
|
import { defaultPath } from '../install/utils';
|
||||||
|
|
||||||
const coreDirectory = 'packages/core';
|
const coreDirectory = 'packages/core';
|
||||||
|
@ -51,19 +51,29 @@ const validatePath = async (value: string) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const inquireInstancePath = async (initialPath?: string) => {
|
export const inquireInstancePath = async (initialPath?: string) => {
|
||||||
const { instancePath } = await inquirer.prompt<{ instancePath: string }>(
|
const inquire = async () => {
|
||||||
{
|
if (!isTty()) {
|
||||||
name: 'instancePath',
|
assert(initialPath, new Error('Path is missing'));
|
||||||
message: 'Where is your Logto instance?',
|
|
||||||
type: 'input',
|
|
||||||
default: defaultPath,
|
|
||||||
filter: (value: string) => value.trim(),
|
|
||||||
validate: validatePath,
|
|
||||||
},
|
|
||||||
{ instancePath: initialPath }
|
|
||||||
);
|
|
||||||
|
|
||||||
// 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);
|
const validated = await validatePath(instancePath);
|
||||||
|
|
||||||
if (validated !== true) {
|
if (validated !== true) {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { conditional } from '@silverhand/essentials';
|
import { assert, conditional } from '@silverhand/essentials';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import inquirer from 'inquirer';
|
import inquirer from 'inquirer';
|
||||||
import { SemVer, compare, eq, gt } from 'semver';
|
import { SemVer, compare, eq, gt } from 'semver';
|
||||||
|
|
||||||
import { findLastIndex, log } from '../../../utilities';
|
import { findLastIndex, isTty, log } from '../../../utilities';
|
||||||
import { AlterationFile } from './type';
|
import { AlterationFile } from './type';
|
||||||
|
|
||||||
const getVersionFromFilename = (filename: string) => {
|
const getVersionFromFilename = (filename: string) => {
|
||||||
|
@ -45,28 +45,42 @@ export const chooseAlterationsByVersion = async (
|
||||||
const initialSemVersion = conditional(
|
const initialSemVersion = conditional(
|
||||||
initialVersion && initialVersion !== latestTag && new SemVer(initialVersion)
|
initialVersion && initialVersion !== latestTag && new SemVer(initialVersion)
|
||||||
);
|
);
|
||||||
|
const firstVersion = versions[0];
|
||||||
|
|
||||||
if (!versions[0]) {
|
if (!firstVersion) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const { version: targetVersion } =
|
const getTargetVersion = async () => {
|
||||||
initialVersion === latestTag
|
if (initialVersion === latestTag) {
|
||||||
? { version: versions[0] }
|
return firstVersion;
|
||||||
: await inquirer.prompt<{ version: SemVer }>(
|
}
|
||||||
{
|
|
||||||
type: 'list',
|
if (!isTty()) {
|
||||||
message: 'Choose the alteration target version',
|
assert(initialSemVersion, new Error('Missing target version'));
|
||||||
name: 'version',
|
|
||||||
choices: versions.map((semVersion) => ({
|
return initialSemVersion;
|
||||||
name: semVersion.version,
|
}
|
||||||
value: semVersion,
|
|
||||||
})),
|
const { version } = await inquirer.prompt<{ version: SemVer }>(
|
||||||
},
|
{
|
||||||
{
|
type: 'list',
|
||||||
version: initialSemVersion,
|
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)}`);
|
log.info(`Deploy target ${chalk.green(targetVersion.version)}`);
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { mkdir } from 'fs/promises';
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
|
import { assert } from '@silverhand/essentials';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import { remove, writeFile } from 'fs-extra';
|
import { remove, writeFile } from 'fs-extra';
|
||||||
import inquirer from 'inquirer';
|
import inquirer from 'inquirer';
|
||||||
|
@ -11,7 +12,15 @@ import * as semver from 'semver';
|
||||||
import tar from 'tar';
|
import tar from 'tar';
|
||||||
|
|
||||||
import { createPoolAndDatabaseIfNeeded } from '../../database';
|
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';
|
import { seedByPool } from '../database/seed';
|
||||||
|
|
||||||
export const defaultPath = path.join(os.homedir(), 'logto');
|
export const defaultPath = path.join(os.homedir(), 'logto');
|
||||||
|
@ -38,6 +47,12 @@ const validatePath = (value: string) =>
|
||||||
: true;
|
: true;
|
||||||
|
|
||||||
export const inquireInstancePath = async (initialPath?: string) => {
|
export const inquireInstancePath = async (initialPath?: string) => {
|
||||||
|
if (!isTty()) {
|
||||||
|
assert(initialPath, new Error('Path is missing'));
|
||||||
|
|
||||||
|
return initialPath;
|
||||||
|
}
|
||||||
|
|
||||||
const { instancePath } = await inquirer.prompt<{ instancePath: string }>(
|
const { instancePath } = await inquirer.prompt<{ instancePath: string }>(
|
||||||
{
|
{
|
||||||
name: 'instancePath',
|
name: 'instancePath',
|
||||||
|
@ -61,7 +76,7 @@ export const inquireInstancePath = async (initialPath?: string) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const validateDatabase = async () => {
|
export const validateDatabase = async () => {
|
||||||
if (cliConfig.has(ConfigKey.DatabaseUrl)) {
|
if (cliConfig.has(ConfigKey.DatabaseUrl) || !isTty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,8 @@ export const oraPromise = async <T>(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const isTty = () => process.stdin.isTTY;
|
||||||
|
|
||||||
export enum ConfigKey {
|
export enum ConfigKey {
|
||||||
DatabaseUrl = 'DB_URL',
|
DatabaseUrl = 'DB_URL',
|
||||||
}
|
}
|
||||||
|
@ -127,26 +129,16 @@ export const getCliConfigWithPrompt = async ({
|
||||||
comments,
|
comments,
|
||||||
defaultValue,
|
defaultValue,
|
||||||
}: GetCliConfigWithPrompt) => {
|
}: GetCliConfigWithPrompt) => {
|
||||||
if (cliConfig.has(key)) {
|
if (cliConfig.has(key) || !isTty()) {
|
||||||
return cliConfig.get(key);
|
return cliConfig.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { input } = await inquirer
|
const { input } = await inquirer.prompt<{ input?: string }>({
|
||||||
.prompt<{ input?: string }>({
|
type: 'input',
|
||||||
type: 'input',
|
name: 'input',
|
||||||
name: 'input',
|
message: `Enter your ${readableKey}${conditionalString(comments && ' ' + comments)}`,
|
||||||
message: `Enter your ${readableKey}${conditionalString(comments && ' ' + comments)}`,
|
default: defaultValue,
|
||||||
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;
|
|
||||||
});
|
|
||||||
|
|
||||||
cliConfig.set(key, input);
|
cliConfig.set(key, input);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue