@git.zone/tsdocker 1.15.0 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.dockercontext.js +13 -3
- package/dist_ts/classes.dockerfile.d.ts +24 -10
- package/dist_ts/classes.dockerfile.js +163 -77
- package/dist_ts/classes.registrycopy.d.ts +70 -0
- package/dist_ts/classes.registrycopy.js +359 -0
- package/dist_ts/classes.tsdockermanager.d.ts +9 -1
- package/dist_ts/classes.tsdockermanager.js +51 -22
- package/dist_ts/classes.tsdockersession.d.ts +35 -0
- package/dist_ts/classes.tsdockersession.js +92 -0
- package/dist_ts/interfaces/index.d.ts +1 -0
- package/dist_ts/tsdocker.cli.js +4 -1
- package/package.json +1 -1
- package/readme.hints.md +12 -0
- package/readme.md +186 -111
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.dockercontext.ts +12 -2
- package/ts/classes.dockerfile.ts +188 -86
- package/ts/classes.registrycopy.ts +511 -0
- package/ts/classes.tsdockermanager.ts +52 -22
- package/ts/classes.tsdockersession.ts +107 -0
- package/ts/interfaces/index.ts +1 -0
- package/ts/tsdocker.cli.ts +3 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import * as crypto from 'crypto';
|
|
2
|
+
import * as net from 'net';
|
|
3
|
+
import { logger } from './tsdocker.logging.js';
|
|
4
|
+
|
|
5
|
+
export interface ISessionConfig {
|
|
6
|
+
sessionId: string;
|
|
7
|
+
registryPort: number;
|
|
8
|
+
registryHost: string;
|
|
9
|
+
registryContainerName: string;
|
|
10
|
+
isCI: boolean;
|
|
11
|
+
ciSystem: string | null;
|
|
12
|
+
builderSuffix: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Per-invocation session identity for tsdocker.
|
|
17
|
+
* Generates unique ports, container names, and builder names so that
|
|
18
|
+
* concurrent CI jobs on the same Docker host don't collide.
|
|
19
|
+
*
|
|
20
|
+
* In local (non-CI) dev the builder suffix is empty, preserving the
|
|
21
|
+
* persistent builder behavior.
|
|
22
|
+
*/
|
|
23
|
+
export class TsDockerSession {
|
|
24
|
+
public config: ISessionConfig;
|
|
25
|
+
|
|
26
|
+
private constructor(config: ISessionConfig) {
|
|
27
|
+
this.config = config;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Creates a new session. Allocates a dynamic port unless overridden
|
|
32
|
+
* via `TSDOCKER_REGISTRY_PORT`.
|
|
33
|
+
*/
|
|
34
|
+
public static async create(): Promise<TsDockerSession> {
|
|
35
|
+
const sessionId =
|
|
36
|
+
process.env.TSDOCKER_SESSION_ID || crypto.randomBytes(4).toString('hex');
|
|
37
|
+
|
|
38
|
+
const registryPort = await TsDockerSession.allocatePort();
|
|
39
|
+
const registryHost = `localhost:${registryPort}`;
|
|
40
|
+
const registryContainerName = `tsdocker-registry-${sessionId}`;
|
|
41
|
+
|
|
42
|
+
const { isCI, ciSystem } = TsDockerSession.detectCI();
|
|
43
|
+
const builderSuffix = isCI ? `-${sessionId}` : '';
|
|
44
|
+
|
|
45
|
+
const config: ISessionConfig = {
|
|
46
|
+
sessionId,
|
|
47
|
+
registryPort,
|
|
48
|
+
registryHost,
|
|
49
|
+
registryContainerName,
|
|
50
|
+
isCI,
|
|
51
|
+
ciSystem,
|
|
52
|
+
builderSuffix,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const session = new TsDockerSession(config);
|
|
56
|
+
session.logInfo();
|
|
57
|
+
return session;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Allocates a free TCP port. Respects `TSDOCKER_REGISTRY_PORT` override.
|
|
62
|
+
*/
|
|
63
|
+
public static async allocatePort(): Promise<number> {
|
|
64
|
+
const envPort = process.env.TSDOCKER_REGISTRY_PORT;
|
|
65
|
+
if (envPort) {
|
|
66
|
+
const parsed = parseInt(envPort, 10);
|
|
67
|
+
if (!isNaN(parsed) && parsed > 0) {
|
|
68
|
+
return parsed;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return new Promise<number>((resolve, reject) => {
|
|
73
|
+
const srv = net.createServer();
|
|
74
|
+
srv.listen(0, '127.0.0.1', () => {
|
|
75
|
+
const addr = srv.address() as net.AddressInfo;
|
|
76
|
+
const port = addr.port;
|
|
77
|
+
srv.close((err) => {
|
|
78
|
+
if (err) reject(err);
|
|
79
|
+
else resolve(port);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
srv.on('error', reject);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Detects whether we're running inside a CI system.
|
|
88
|
+
*/
|
|
89
|
+
private static detectCI(): { isCI: boolean; ciSystem: string | null } {
|
|
90
|
+
if (process.env.GITEA_ACTIONS) return { isCI: true, ciSystem: 'gitea-actions' };
|
|
91
|
+
if (process.env.GITHUB_ACTIONS) return { isCI: true, ciSystem: 'github-actions' };
|
|
92
|
+
if (process.env.GITLAB_CI) return { isCI: true, ciSystem: 'gitlab-ci' };
|
|
93
|
+
if (process.env.CI) return { isCI: true, ciSystem: 'generic' };
|
|
94
|
+
return { isCI: false, ciSystem: null };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private logInfo(): void {
|
|
98
|
+
const c = this.config;
|
|
99
|
+
logger.log('info', '=== TSDOCKER SESSION ===');
|
|
100
|
+
logger.log('info', `Session ID: ${c.sessionId}`);
|
|
101
|
+
logger.log('info', `Registry: ${c.registryHost} (container: ${c.registryContainerName})`);
|
|
102
|
+
if (c.isCI) {
|
|
103
|
+
logger.log('info', `CI detected: ${c.ciSystem}`);
|
|
104
|
+
logger.log('info', `Builder suffix: ${c.builderSuffix}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
package/ts/interfaces/index.ts
CHANGED
package/ts/tsdocker.cli.ts
CHANGED
|
@@ -64,6 +64,7 @@ export let run = () => {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
await manager.build(buildOptions);
|
|
67
|
+
await manager.cleanup();
|
|
67
68
|
logger.log('success', 'Build completed successfully');
|
|
68
69
|
} catch (err) {
|
|
69
70
|
logger.log('error', `Build failed: ${(err as Error).message}`);
|
|
@@ -117,6 +118,7 @@ export let run = () => {
|
|
|
117
118
|
const registries = registryArg ? [registryArg] : undefined;
|
|
118
119
|
|
|
119
120
|
await manager.push(registries);
|
|
121
|
+
await manager.cleanup();
|
|
120
122
|
logger.log('success', 'Push completed successfully');
|
|
121
123
|
} catch (err) {
|
|
122
124
|
logger.log('error', `Push failed: ${(err as Error).message}`);
|
|
@@ -180,6 +182,7 @@ export let run = () => {
|
|
|
180
182
|
|
|
181
183
|
// Run tests
|
|
182
184
|
await manager.test();
|
|
185
|
+
await manager.cleanup();
|
|
183
186
|
logger.log('success', 'Tests completed successfully');
|
|
184
187
|
} catch (err) {
|
|
185
188
|
logger.log('error', `Tests failed: ${(err as Error).message}`);
|