Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3a4d510304 | |||
| b1f135a5f4 | |||
| 30a5749fab | |||
| 100f37b857 | |||
| 93cf2ee7bf | |||
| 8cf8e43e59 |
20
changelog.md
20
changelog.md
@@ -1,5 +1,25 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2026-03-24 - 2.2.2 - fix(config)
|
||||||
|
rename npmextra configuration file to .smartconfig.json
|
||||||
|
|
||||||
|
- Moves the existing project metadata and release configuration from npmextra.json to .smartconfig.json without changing its contents.
|
||||||
|
|
||||||
|
## 2026-03-24 - 2.2.1 - fix(config)
|
||||||
|
switch configuration loading from npmextra to smartconfig
|
||||||
|
|
||||||
|
- replace the @push.rocks/npmextra dependency with @push.rocks/smartconfig
|
||||||
|
- update config initialization to use Smartconfig for the @git.zone/tsdocker settings
|
||||||
|
- refresh CLI help text to reference smartconfig.json instead of npmextra.json
|
||||||
|
|
||||||
|
## 2026-03-19 - 2.2.0 - feat(cli/buildx)
|
||||||
|
add pull control for builds and isolate buildx builders per project
|
||||||
|
|
||||||
|
- adds a new pull build option with --no-pull CLI support and defaults builds to refreshing base images with --pull
|
||||||
|
- passes the selected buildx builder explicitly into build commands instead of relying on global docker buildx use state
|
||||||
|
- generates project-hashed builder suffixes so concurrent runs from different project directories do not share the same local builder
|
||||||
|
- updates session logging to include project hash and builder suffix for easier build diagnostics
|
||||||
|
|
||||||
## 2026-03-15 - 2.1.0 - feat(cli)
|
## 2026-03-15 - 2.1.0 - feat(cli)
|
||||||
add global remote builder configuration and native SSH buildx nodes for multi-platform builds
|
add global remote builder configuration and native SSH buildx nodes for multi-platform builds
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@git.zone/tsdocker",
|
"name": "@git.zone/tsdocker",
|
||||||
"version": "2.1.0",
|
"version": "2.2.2",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "develop npm modules cross platform with docker",
|
"description": "develop npm modules cross platform with docker",
|
||||||
"main": "dist_ts/index.js",
|
"main": "dist_ts/index.js",
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@push.rocks/lik": "^6.3.1",
|
"@push.rocks/lik": "^6.3.1",
|
||||||
"@push.rocks/npmextra": "^5.3.3",
|
"@push.rocks/smartconfig": "^6.0.0",
|
||||||
"@push.rocks/projectinfo": "^5.0.2",
|
"@push.rocks/projectinfo": "^5.0.2",
|
||||||
"@push.rocks/smartcli": "^4.0.20",
|
"@push.rocks/smartcli": "^4.0.20",
|
||||||
"@push.rocks/smartfs": "^1.5.0",
|
"@push.rocks/smartfs": "^1.5.0",
|
||||||
|
|||||||
26
pnpm-lock.yaml
generated
26
pnpm-lock.yaml
generated
@@ -11,15 +11,15 @@ importers:
|
|||||||
'@push.rocks/lik':
|
'@push.rocks/lik':
|
||||||
specifier: ^6.3.1
|
specifier: ^6.3.1
|
||||||
version: 6.3.1
|
version: 6.3.1
|
||||||
'@push.rocks/npmextra':
|
|
||||||
specifier: ^5.3.3
|
|
||||||
version: 5.3.3
|
|
||||||
'@push.rocks/projectinfo':
|
'@push.rocks/projectinfo':
|
||||||
specifier: ^5.0.2
|
specifier: ^5.0.2
|
||||||
version: 5.0.2
|
version: 5.0.2
|
||||||
'@push.rocks/smartcli':
|
'@push.rocks/smartcli':
|
||||||
specifier: ^4.0.20
|
specifier: ^4.0.20
|
||||||
version: 4.0.20
|
version: 4.0.20
|
||||||
|
'@push.rocks/smartconfig':
|
||||||
|
specifier: ^6.0.0
|
||||||
|
version: 6.0.0
|
||||||
'@push.rocks/smartfs':
|
'@push.rocks/smartfs':
|
||||||
specifier: ^1.5.0
|
specifier: ^1.5.0
|
||||||
version: 1.5.0
|
version: 1.5.0
|
||||||
@@ -897,6 +897,9 @@ packages:
|
|||||||
'@push.rocks/smartclickhouse@2.2.0':
|
'@push.rocks/smartclickhouse@2.2.0':
|
||||||
resolution: {integrity: sha512-eTzKiREIPSzL1kPkVyD6vEbn+WV/DvQqDjP67VlhNlQGbRcemnJG/eLrUUR1ytmdIqnsZGEK6UYBgyj5nhzLNQ==}
|
resolution: {integrity: sha512-eTzKiREIPSzL1kPkVyD6vEbn+WV/DvQqDjP67VlhNlQGbRcemnJG/eLrUUR1ytmdIqnsZGEK6UYBgyj5nhzLNQ==}
|
||||||
|
|
||||||
|
'@push.rocks/smartconfig@6.0.0':
|
||||||
|
resolution: {integrity: sha512-ohXwJdbDXV2budErnZKWBOz01YkjP6gJsZ7QM9+6Wsh+r7O1CVT3JpV+mD8xJWy5tZRHI+3B9L8z0+WkIDtKzw==}
|
||||||
|
|
||||||
'@push.rocks/smartcrypto@2.0.4':
|
'@push.rocks/smartcrypto@2.0.4':
|
||||||
resolution: {integrity: sha512-1+/5bsjyataf5uUkUNnnVXGRAt+gHVk1KDzozjTqgqJxHvQk1d9fVDohL6CxUhUucTPtu5VR5xNBiV8YCDuGyw==}
|
resolution: {integrity: sha512-1+/5bsjyataf5uUkUNnnVXGRAt+gHVk1KDzozjTqgqJxHvQk1d9fVDohL6CxUhUucTPtu5VR5xNBiV8YCDuGyw==}
|
||||||
|
|
||||||
@@ -4970,6 +4973,23 @@ snapshots:
|
|||||||
'@push.rocks/smarturl': 3.1.0
|
'@push.rocks/smarturl': 3.1.0
|
||||||
'@push.rocks/webrequest': 4.0.5
|
'@push.rocks/webrequest': 4.0.5
|
||||||
|
|
||||||
|
'@push.rocks/smartconfig@6.0.0':
|
||||||
|
dependencies:
|
||||||
|
'@push.rocks/qenv': 6.1.3
|
||||||
|
'@push.rocks/smartfile': 11.2.7
|
||||||
|
'@push.rocks/smartjson': 5.2.0
|
||||||
|
'@push.rocks/smartlog': 3.2.1
|
||||||
|
'@push.rocks/smartpath': 6.0.0
|
||||||
|
'@push.rocks/smartpromise': 4.2.3
|
||||||
|
'@push.rocks/smartrx': 3.0.10
|
||||||
|
'@push.rocks/taskbuffer': 3.5.0
|
||||||
|
'@tsclass/tsclass': 9.3.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@nuxt/kit'
|
||||||
|
- react
|
||||||
|
- supports-color
|
||||||
|
- vue
|
||||||
|
|
||||||
'@push.rocks/smartcrypto@2.0.4':
|
'@push.rocks/smartcrypto@2.0.4':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@push.rocks/smartpromise': 4.2.3
|
'@push.rocks/smartpromise': 4.2.3
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@git.zone/tsdocker',
|
name: '@git.zone/tsdocker',
|
||||||
version: '2.1.0',
|
version: '2.2.2',
|
||||||
description: 'develop npm modules cross platform with docker'
|
description: 'develop npm modules cross platform with docker'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ export class Dockerfile {
|
|||||||
public static async buildDockerfiles(
|
public static async buildDockerfiles(
|
||||||
sortedArrayArg: Dockerfile[],
|
sortedArrayArg: Dockerfile[],
|
||||||
session: TsDockerSession,
|
session: TsDockerSession,
|
||||||
options?: { platform?: string; timeout?: number; noCache?: boolean; verbose?: boolean; isRootless?: boolean; parallel?: boolean; parallelConcurrency?: number; onRegistryStarted?: () => Promise<void>; onBeforeRegistryStop?: () => Promise<void> },
|
options?: { platform?: string; timeout?: number; noCache?: boolean; pull?: boolean; verbose?: boolean; isRootless?: boolean; parallel?: boolean; parallelConcurrency?: number; onRegistryStarted?: () => Promise<void>; onBeforeRegistryStop?: () => Promise<void> },
|
||||||
): Promise<Dockerfile[]> {
|
): Promise<Dockerfile[]> {
|
||||||
const total = sortedArrayArg.length;
|
const total = sortedArrayArg.length;
|
||||||
const overallStart = Date.now();
|
const overallStart = Date.now();
|
||||||
@@ -668,13 +668,14 @@ export class Dockerfile {
|
|||||||
/**
|
/**
|
||||||
* Builds the Dockerfile
|
* Builds the Dockerfile
|
||||||
*/
|
*/
|
||||||
public async build(options?: { platform?: string; timeout?: number; noCache?: boolean; verbose?: boolean }): Promise<number> {
|
public async build(options?: { platform?: string; timeout?: number; noCache?: boolean; pull?: boolean; verbose?: boolean }): Promise<number> {
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
const buildArgsString = await Dockerfile.getDockerBuildArgs(this.managerRef);
|
const buildArgsString = await Dockerfile.getDockerBuildArgs(this.managerRef);
|
||||||
const config = this.managerRef.config;
|
const config = this.managerRef.config;
|
||||||
const platformOverride = options?.platform;
|
const platformOverride = options?.platform;
|
||||||
const timeout = options?.timeout;
|
const timeout = options?.timeout;
|
||||||
const noCacheFlag = options?.noCache ? ' --no-cache' : '';
|
const noCacheFlag = options?.noCache ? ' --no-cache' : '';
|
||||||
|
const pullFlag = options?.pull !== false ? ' --pull' : '';
|
||||||
const verbose = options?.verbose ?? false;
|
const verbose = options?.verbose ?? false;
|
||||||
|
|
||||||
let buildContextFlag = '';
|
let buildContextFlag = '';
|
||||||
@@ -689,23 +690,24 @@ export class Dockerfile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let buildCommand: string;
|
let buildCommand: string;
|
||||||
|
const builderFlag = this.managerRef.currentBuilderName ? ` --builder ${this.managerRef.currentBuilderName}` : '';
|
||||||
|
|
||||||
if (platformOverride) {
|
if (platformOverride) {
|
||||||
// Single platform override via buildx
|
// Single platform override via buildx
|
||||||
buildCommand = `docker buildx build --progress=plain --platform ${platformOverride}${noCacheFlag}${buildContextFlag} --load -t ${this.buildTag} -f ${this.filePath} ${buildArgsString} .`;
|
buildCommand = `docker buildx build${builderFlag} --progress=plain --platform ${platformOverride}${noCacheFlag}${pullFlag}${buildContextFlag} --load -t ${this.buildTag} -f ${this.filePath} ${buildArgsString} .`;
|
||||||
logger.log('info', `Build: buildx --platform ${platformOverride} --load`);
|
logger.log('info', `Build: buildx --platform ${platformOverride} --load`);
|
||||||
} else if (config.platforms && config.platforms.length > 1) {
|
} else if (config.platforms && config.platforms.length > 1) {
|
||||||
// Multi-platform build using buildx — always push to local registry
|
// Multi-platform build using buildx — always push to local registry
|
||||||
const platformString = config.platforms.join(',');
|
const platformString = config.platforms.join(',');
|
||||||
const registryHost = this.session?.config.registryHost || 'localhost:5234';
|
const registryHost = this.session?.config.registryHost || 'localhost:5234';
|
||||||
const localTag = `${registryHost}/${this.buildTag}`;
|
const localTag = `${registryHost}/${this.buildTag}`;
|
||||||
buildCommand = `docker buildx build --progress=plain --platform ${platformString}${noCacheFlag}${buildContextFlag} -t ${localTag} -f ${this.filePath} ${buildArgsString} --push .`;
|
buildCommand = `docker buildx build${builderFlag} --progress=plain --platform ${platformString}${noCacheFlag}${pullFlag}${buildContextFlag} -t ${localTag} -f ${this.filePath} ${buildArgsString} --push .`;
|
||||||
this.localRegistryTag = localTag;
|
this.localRegistryTag = localTag;
|
||||||
logger.log('info', `Build: buildx --platform ${platformString} --push to local registry`);
|
logger.log('info', `Build: buildx --platform ${platformString} --push to local registry`);
|
||||||
} else {
|
} else {
|
||||||
// Standard build
|
// Standard build
|
||||||
const versionLabel = this.managerRef.projectInfo?.npm?.version || 'unknown';
|
const versionLabel = this.managerRef.projectInfo?.npm?.version || 'unknown';
|
||||||
buildCommand = `docker build --progress=plain --label="version=${versionLabel}"${noCacheFlag} -t ${this.buildTag} -f ${this.filePath} ${buildArgsString} .`;
|
buildCommand = `docker build --progress=plain --label="version=${versionLabel}"${noCacheFlag}${pullFlag} -t ${this.buildTag} -f ${this.filePath} ${buildArgsString} .`;
|
||||||
logger.log('info', 'Build: docker build (standard)');
|
logger.log('info', 'Build: docker build (standard)');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export class TsDockerManager {
|
|||||||
public projectInfo: any;
|
public projectInfo: any;
|
||||||
public dockerContext: DockerContext;
|
public dockerContext: DockerContext;
|
||||||
public session!: TsDockerSession;
|
public session!: TsDockerSession;
|
||||||
|
public currentBuilderName?: string;
|
||||||
private dockerfiles: Dockerfile[] = [];
|
private dockerfiles: Dockerfile[] = [];
|
||||||
private activeRemoteBuilders: IRemoteBuilder[] = [];
|
private activeRemoteBuilders: IRemoteBuilder[] = [];
|
||||||
private sshTunnelManager?: SshTunnelManager;
|
private sshTunnelManager?: SshTunnelManager;
|
||||||
@@ -266,6 +267,7 @@ export class TsDockerManager {
|
|||||||
platform: options?.platform,
|
platform: options?.platform,
|
||||||
timeout: options?.timeout,
|
timeout: options?.timeout,
|
||||||
noCache: options?.noCache,
|
noCache: options?.noCache,
|
||||||
|
pull: options?.pull,
|
||||||
verbose: options?.verbose,
|
verbose: options?.verbose,
|
||||||
});
|
});
|
||||||
logger.log('ok', `${progress} Built ${df.cleanTag} in ${formatDuration(elapsed)}`);
|
logger.log('ok', `${progress} Built ${df.cleanTag} in ${formatDuration(elapsed)}`);
|
||||||
@@ -311,6 +313,7 @@ export class TsDockerManager {
|
|||||||
platform: options?.platform,
|
platform: options?.platform,
|
||||||
timeout: options?.timeout,
|
timeout: options?.timeout,
|
||||||
noCache: options?.noCache,
|
noCache: options?.noCache,
|
||||||
|
pull: options?.pull,
|
||||||
verbose: options?.verbose,
|
verbose: options?.verbose,
|
||||||
});
|
});
|
||||||
logger.log('ok', `${progress} Built ${dockerfileArg.cleanTag} in ${formatDuration(elapsed)}`);
|
logger.log('ok', `${progress} Built ${dockerfileArg.cleanTag} in ${formatDuration(elapsed)}`);
|
||||||
@@ -349,6 +352,7 @@ export class TsDockerManager {
|
|||||||
platform: options?.platform,
|
platform: options?.platform,
|
||||||
timeout: options?.timeout,
|
timeout: options?.timeout,
|
||||||
noCache: options?.noCache,
|
noCache: options?.noCache,
|
||||||
|
pull: options?.pull,
|
||||||
verbose: options?.verbose,
|
verbose: options?.verbose,
|
||||||
isRootless: this.dockerContext.contextInfo?.isRootless,
|
isRootless: this.dockerContext.contextInfo?.isRootless,
|
||||||
parallel: options?.parallel,
|
parallel: options?.parallel,
|
||||||
@@ -401,6 +405,7 @@ export class TsDockerManager {
|
|||||||
await this.ensureBuildxLocal(builderName);
|
await this.ensureBuildxLocal(builderName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.currentBuilderName = builderName;
|
||||||
logger.log('ok', `Docker buildx ready (builder: ${builderName}, platforms: ${platforms})`);
|
logger.log('ok', `Docker buildx ready (builder: ${builderName}, platforms: ${platforms})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,7 +431,7 @@ export class TsDockerManager {
|
|||||||
// Create the local node
|
// Create the local node
|
||||||
const localPlatformFlag = localPlatforms.length > 0 ? ` --platform ${localPlatforms.join(',')}` : '';
|
const localPlatformFlag = localPlatforms.length > 0 ? ` --platform ${localPlatforms.join(',')}` : '';
|
||||||
await smartshellInstance.exec(
|
await smartshellInstance.exec(
|
||||||
`docker buildx create --name ${builderName} --driver docker-container --driver-opt network=host${localPlatformFlag} --use`
|
`docker buildx create --name ${builderName} --driver docker-container --driver-opt network=host${localPlatformFlag}`
|
||||||
);
|
);
|
||||||
|
|
||||||
// Append remote nodes
|
// Append remote nodes
|
||||||
@@ -441,7 +446,7 @@ export class TsDockerManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Bootstrap all nodes
|
// Bootstrap all nodes
|
||||||
await smartshellInstance.exec('docker buildx inspect --bootstrap');
|
await smartshellInstance.exec(`docker buildx inspect --builder ${builderName} --bootstrap`);
|
||||||
|
|
||||||
// Store active remote builders for SSH tunnel setup during build
|
// Store active remote builders for SSH tunnel setup during build
|
||||||
this.activeRemoteBuilders = remoteBuilders;
|
this.activeRemoteBuilders = remoteBuilders;
|
||||||
@@ -456,20 +461,18 @@ export class TsDockerManager {
|
|||||||
if (inspectResult.exitCode !== 0) {
|
if (inspectResult.exitCode !== 0) {
|
||||||
logger.log('info', 'Creating new buildx builder with host network...');
|
logger.log('info', 'Creating new buildx builder with host network...');
|
||||||
await smartshellInstance.exec(
|
await smartshellInstance.exec(
|
||||||
`docker buildx create --name ${builderName} --driver docker-container --driver-opt network=host --use`
|
`docker buildx create --name ${builderName} --driver docker-container --driver-opt network=host`
|
||||||
);
|
);
|
||||||
await smartshellInstance.exec('docker buildx inspect --bootstrap');
|
await smartshellInstance.exec(`docker buildx inspect --builder ${builderName} --bootstrap`);
|
||||||
} else {
|
} else {
|
||||||
const inspectOutput = inspectResult.stdout || '';
|
const inspectOutput = inspectResult.stdout || '';
|
||||||
if (!inspectOutput.includes('network=host')) {
|
if (!inspectOutput.includes('network=host')) {
|
||||||
logger.log('info', 'Recreating buildx builder with host network (migration)...');
|
logger.log('info', 'Recreating buildx builder with host network (migration)...');
|
||||||
await smartshellInstance.exec(`docker buildx rm ${builderName} 2>/dev/null`);
|
await smartshellInstance.exec(`docker buildx rm ${builderName} 2>/dev/null`);
|
||||||
await smartshellInstance.exec(
|
await smartshellInstance.exec(
|
||||||
`docker buildx create --name ${builderName} --driver docker-container --driver-opt network=host --use`
|
`docker buildx create --name ${builderName} --driver docker-container --driver-opt network=host`
|
||||||
);
|
);
|
||||||
await smartshellInstance.exec('docker buildx inspect --bootstrap');
|
await smartshellInstance.exec(`docker buildx inspect --builder ${builderName} --bootstrap`);
|
||||||
} else {
|
|
||||||
await smartshellInstance.exec(`docker buildx use ${builderName}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.activeRemoteBuilders = [];
|
this.activeRemoteBuilders = [];
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { logger } from './tsdocker.logging.js';
|
|||||||
|
|
||||||
export interface ISessionConfig {
|
export interface ISessionConfig {
|
||||||
sessionId: string;
|
sessionId: string;
|
||||||
|
projectHash: string;
|
||||||
registryPort: number;
|
registryPort: number;
|
||||||
registryHost: string;
|
registryHost: string;
|
||||||
registryContainerName: string;
|
registryContainerName: string;
|
||||||
@@ -17,8 +18,8 @@ export interface ISessionConfig {
|
|||||||
* Generates unique ports, container names, and builder names so that
|
* Generates unique ports, container names, and builder names so that
|
||||||
* concurrent CI jobs on the same Docker host don't collide.
|
* concurrent CI jobs on the same Docker host don't collide.
|
||||||
*
|
*
|
||||||
* In local (non-CI) dev the builder suffix is empty, preserving the
|
* In local (non-CI) dev the builder suffix contains a project hash so
|
||||||
* persistent builder behavior.
|
* that concurrent runs in different project directories use separate builders.
|
||||||
*/
|
*/
|
||||||
export class TsDockerSession {
|
export class TsDockerSession {
|
||||||
public config: ISessionConfig;
|
public config: ISessionConfig;
|
||||||
@@ -34,16 +35,18 @@ export class TsDockerSession {
|
|||||||
public static async create(): Promise<TsDockerSession> {
|
public static async create(): Promise<TsDockerSession> {
|
||||||
const sessionId =
|
const sessionId =
|
||||||
process.env.TSDOCKER_SESSION_ID || crypto.randomBytes(4).toString('hex');
|
process.env.TSDOCKER_SESSION_ID || crypto.randomBytes(4).toString('hex');
|
||||||
|
const projectHash = crypto.createHash('sha256').update(process.cwd()).digest('hex').substring(0, 8);
|
||||||
|
|
||||||
const registryPort = await TsDockerSession.allocatePort();
|
const registryPort = await TsDockerSession.allocatePort();
|
||||||
const registryHost = `localhost:${registryPort}`;
|
const registryHost = `localhost:${registryPort}`;
|
||||||
const registryContainerName = `tsdocker-registry-${sessionId}`;
|
const registryContainerName = `tsdocker-registry-${sessionId}`;
|
||||||
|
|
||||||
const { isCI, ciSystem } = TsDockerSession.detectCI();
|
const { isCI, ciSystem } = TsDockerSession.detectCI();
|
||||||
const builderSuffix = isCI ? `-${sessionId}` : '';
|
const builderSuffix = isCI ? `-${projectHash}-${sessionId}` : `-${projectHash}`;
|
||||||
|
|
||||||
const config: ISessionConfig = {
|
const config: ISessionConfig = {
|
||||||
sessionId,
|
sessionId,
|
||||||
|
projectHash,
|
||||||
registryPort,
|
registryPort,
|
||||||
registryHost,
|
registryHost,
|
||||||
registryContainerName,
|
registryContainerName,
|
||||||
@@ -99,9 +102,10 @@ export class TsDockerSession {
|
|||||||
logger.log('info', '=== TSDOCKER SESSION ===');
|
logger.log('info', '=== TSDOCKER SESSION ===');
|
||||||
logger.log('info', `Session ID: ${c.sessionId}`);
|
logger.log('info', `Session ID: ${c.sessionId}`);
|
||||||
logger.log('info', `Registry: ${c.registryHost} (container: ${c.registryContainerName})`);
|
logger.log('info', `Registry: ${c.registryHost} (container: ${c.registryContainerName})`);
|
||||||
|
logger.log('info', `Project hash: ${c.projectHash}`);
|
||||||
|
logger.log('info', `Builder suffix: ${c.builderSuffix}`);
|
||||||
if (c.isCI) {
|
if (c.isCI) {
|
||||||
logger.log('info', `CI detected: ${c.ciSystem}`);
|
logger.log('info', `CI detected: ${c.ciSystem}`);
|
||||||
logger.log('info', `Builder suffix: ${c.builderSuffix}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ export interface IBuildCommandOptions {
|
|||||||
platform?: string; // Single platform override (e.g., 'linux/arm64')
|
platform?: string; // Single platform override (e.g., 'linux/arm64')
|
||||||
timeout?: number; // Build timeout in seconds
|
timeout?: number; // Build timeout in seconds
|
||||||
noCache?: boolean; // Force rebuild without Docker layer cache (--no-cache)
|
noCache?: boolean; // Force rebuild without Docker layer cache (--no-cache)
|
||||||
|
pull?: boolean; // Pull fresh base images before building (default: true)
|
||||||
cached?: boolean; // Skip builds when Dockerfile content hasn't changed
|
cached?: boolean; // Skip builds when Dockerfile content hasn't changed
|
||||||
verbose?: boolean; // Stream raw docker build output (default: silent)
|
verbose?: boolean; // Stream raw docker build output (default: silent)
|
||||||
context?: string; // Explicit Docker context name (--context flag)
|
context?: string; // Explicit Docker context name (--context flag)
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ BUILD / PUSH OPTIONS
|
|||||||
--platform=<p> Target platform (e.g. linux/arm64)
|
--platform=<p> Target platform (e.g. linux/arm64)
|
||||||
--timeout=<s> Build timeout in seconds
|
--timeout=<s> Build timeout in seconds
|
||||||
--no-cache Rebuild without Docker layer cache
|
--no-cache Rebuild without Docker layer cache
|
||||||
|
--no-pull Skip pulling latest base images (use cached)
|
||||||
--cached Skip builds when Dockerfile is unchanged
|
--cached Skip builds when Dockerfile is unchanged
|
||||||
--verbose Stream raw docker build output
|
--verbose Stream raw docker build output
|
||||||
--parallel[=<n>] Parallel builds (optional concurrency limit)
|
--parallel[=<n>] Parallel builds (optional concurrency limit)
|
||||||
@@ -66,7 +67,7 @@ CONFIG SUBCOMMANDS
|
|||||||
show Show full global config
|
show Show full global config
|
||||||
|
|
||||||
CONFIGURATION
|
CONFIGURATION
|
||||||
Configure via npmextra.json under the "@git.zone/tsdocker" key:
|
Configure via smartconfig.json under the "@git.zone/tsdocker" key:
|
||||||
|
|
||||||
registries Array of registry URLs to push to
|
registries Array of registry URLs to push to
|
||||||
registryRepoMap Map of registry URL to repo path overrides
|
registryRepoMap Map of registry URL to repo path overrides
|
||||||
@@ -120,6 +121,8 @@ export let run = () => {
|
|||||||
if (argvArg.cache === false) {
|
if (argvArg.cache === false) {
|
||||||
buildOptions.noCache = true;
|
buildOptions.noCache = true;
|
||||||
}
|
}
|
||||||
|
// --pull is default true; --no-pull sets pull=false
|
||||||
|
buildOptions.pull = argvArg.pull !== false;
|
||||||
if (argvArg.cached) {
|
if (argvArg.cached) {
|
||||||
buildOptions.cached = true;
|
buildOptions.cached = true;
|
||||||
}
|
}
|
||||||
@@ -170,6 +173,7 @@ export let run = () => {
|
|||||||
if (argvArg.cache === false) {
|
if (argvArg.cache === false) {
|
||||||
buildOptions.noCache = true;
|
buildOptions.noCache = true;
|
||||||
}
|
}
|
||||||
|
buildOptions.pull = argvArg.pull !== false;
|
||||||
if (argvArg.verbose) {
|
if (argvArg.verbose) {
|
||||||
buildOptions.verbose = true;
|
buildOptions.verbose = true;
|
||||||
}
|
}
|
||||||
@@ -243,6 +247,7 @@ export let run = () => {
|
|||||||
if (argvArg.cache === false) {
|
if (argvArg.cache === false) {
|
||||||
buildOptions.noCache = true;
|
buildOptions.noCache = true;
|
||||||
}
|
}
|
||||||
|
buildOptions.pull = argvArg.pull !== false;
|
||||||
if (argvArg.cached) {
|
if (argvArg.cached) {
|
||||||
buildOptions.cached = true;
|
buildOptions.cached = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import * as paths from './tsdocker.paths.js';
|
|||||||
import type { ITsDockerConfig } from './interfaces/index.js';
|
import type { ITsDockerConfig } from './interfaces/index.js';
|
||||||
|
|
||||||
const buildConfig = async (): Promise<ITsDockerConfig> => {
|
const buildConfig = async (): Promise<ITsDockerConfig> => {
|
||||||
const npmextra = new plugins.npmextra.Npmextra(paths.cwd);
|
const npmextra = new plugins.npmextra.Smartconfig(paths.cwd);
|
||||||
const config = npmextra.dataFor<ITsDockerConfig>('@git.zone/tsdocker', {
|
const config = npmextra.dataFor<ITsDockerConfig>('@git.zone/tsdocker', {
|
||||||
registries: [],
|
registries: [],
|
||||||
registryRepoMap: {},
|
registryRepoMap: {},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// push.rocks scope
|
// push.rocks scope
|
||||||
import * as lik from '@push.rocks/lik';
|
import * as lik from '@push.rocks/lik';
|
||||||
import * as npmextra from '@push.rocks/npmextra';
|
import * as npmextra from '@push.rocks/smartconfig';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as projectinfo from '@push.rocks/projectinfo';
|
import * as projectinfo from '@push.rocks/projectinfo';
|
||||||
import * as smartcli from '@push.rocks/smartcli';
|
import * as smartcli from '@push.rocks/smartcli';
|
||||||
|
|||||||
Reference in New Issue
Block a user