@ship.zone/szci 7.1.1 → 7.1.3
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/bin/szci-wrapper.js +11 -9
- package/changelog.md +19 -0
- package/deno.json +63 -0
- package/mod.ts +47 -0
- package/package.json +10 -9
- package/readme.md +2 -2
- package/scripts/install-binary.js +20 -9
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/connector.cloudly/cloudlyconnector.ts +31 -0
- package/ts/index.ts +9 -0
- package/ts/manager.docker/index.ts +78 -0
- package/ts/manager.git/index.ts +71 -0
- package/ts/manager.git/mod.plugins.ts +1 -0
- package/ts/manager.nodejs/index.ts +82 -0
- package/ts/manager.npm/index.ts +194 -0
- package/ts/manager.npm/mod.plugins.ts +1 -0
- package/ts/mod_ssh/index.ts +97 -0
- package/ts/mod_ssh/mod.plugins.ts +1 -0
- package/ts/szci.bash.ts +96 -0
- package/ts/szci.classes.szci.ts +58 -0
- package/ts/szci.classes.szcicli.ts +68 -0
- package/ts/szci.classes.szciconfig.ts +63 -0
- package/ts/szci.classes.szcienv.ts +25 -0
- package/ts/szci.classes.szciinfo.ts +18 -0
- package/ts/szci.logging.ts +14 -0
- package/ts/szci.paths.ts +31 -0
- package/ts/szci.plugins.ts +60 -0
package/bin/szci-wrapper.js
CHANGED
|
@@ -59,22 +59,24 @@ function executeBinary() {
|
|
|
59
59
|
const binaryName = getBinaryName();
|
|
60
60
|
const binaryPath = join(__dirname, '..', 'dist', 'binaries', binaryName);
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
const denoSourcePath = join(__dirname, '..', 'mod.ts');
|
|
63
|
+
const denoConfigPath = join(__dirname, '..', 'deno.json');
|
|
64
|
+
const command = existsSync(binaryPath) ? binaryPath : 'deno';
|
|
65
|
+
const args = existsSync(binaryPath)
|
|
66
|
+
? process.argv.slice(2)
|
|
67
|
+
: ['run', '--allow-all', '--config', denoConfigPath, denoSourcePath, ...process.argv.slice(2)];
|
|
68
|
+
|
|
69
|
+
if (!existsSync(binaryPath) && !existsSync(denoSourcePath)) {
|
|
64
70
|
console.error(`Error: Binary not found at ${binaryPath}`);
|
|
65
|
-
console.error(
|
|
66
|
-
console.error('1. The postinstall script failed to run');
|
|
67
|
-
console.error('2. The platform is not supported');
|
|
68
|
-
console.error('3. The package was not installed correctly');
|
|
69
|
-
console.error('');
|
|
71
|
+
console.error(`Error: Deno source fallback not found at ${denoSourcePath}`);
|
|
70
72
|
console.error('Try reinstalling the package:');
|
|
71
73
|
console.error(' npm uninstall -g @ship.zone/szci');
|
|
72
74
|
console.error(' npm install -g @ship.zone/szci');
|
|
73
75
|
process.exit(1);
|
|
74
76
|
}
|
|
75
77
|
|
|
76
|
-
// Spawn the binary with all arguments passed through
|
|
77
|
-
const child = spawn(
|
|
78
|
+
// Spawn the binary or the Deno source fallback with all arguments passed through.
|
|
79
|
+
const child = spawn(command, args, {
|
|
78
80
|
stdio: 'inherit',
|
|
79
81
|
shell: false
|
|
80
82
|
});
|
package/changelog.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Pending
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## 2026-05-20 - 7.1.3
|
|
7
|
+
|
|
8
|
+
### Fixes
|
|
9
|
+
|
|
10
|
+
- add Deno source fallback when platform binaries are unavailable (npm)
|
|
11
|
+
- run the packaged Deno entrypoint from the wrapper when no compiled binary is present
|
|
12
|
+
- include Deno source files in the npm package and compile binaries during build and prepublish
|
|
13
|
+
- make postinstall resolve the package version from package.json and continue installation if binary downloads fail
|
|
14
|
+
|
|
15
|
+
## 2026-02-08 - 7.1.2 - fix(readme)
|
|
16
|
+
Correct license link and fix markdown line break for company name in README
|
|
17
|
+
|
|
18
|
+
- Updated README link to the license file from ./license to ./LICENSE
|
|
19
|
+
- Added trailing spaces after 'Task Venture Capital GmbH' to preserve a Markdown line break
|
|
20
|
+
- Documentation-only change; no code modified
|
|
21
|
+
|
|
3
22
|
## 2026-02-07 - 7.1.1 - fix(workflows)
|
|
4
23
|
normalize default branch to 'main' across CI/release workflows and docs; update package metadata; clean .gitignore and fix readme license link
|
|
5
24
|
|
package/deno.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ship.zone/szci",
|
|
3
|
+
"version": "7.1.3",
|
|
4
|
+
"exports": "./mod.ts",
|
|
5
|
+
"nodeModulesDir": "auto",
|
|
6
|
+
"tasks": {
|
|
7
|
+
"dev": "deno run --allow-all mod.ts",
|
|
8
|
+
"compile": "deno task compile:all",
|
|
9
|
+
"compile:all": "bash scripts/compile-all.sh",
|
|
10
|
+
"test": "deno test --allow-all test/",
|
|
11
|
+
"test:watch": "deno test --allow-all --watch test/",
|
|
12
|
+
"check": "deno check mod.ts",
|
|
13
|
+
"fmt": "deno fmt",
|
|
14
|
+
"lint": "deno lint"
|
|
15
|
+
},
|
|
16
|
+
"lint": {
|
|
17
|
+
"rules": {
|
|
18
|
+
"tags": [
|
|
19
|
+
"recommended"
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"fmt": {
|
|
24
|
+
"useTabs": false,
|
|
25
|
+
"lineWidth": 100,
|
|
26
|
+
"indentWidth": 2,
|
|
27
|
+
"semiColons": true,
|
|
28
|
+
"singleQuote": true
|
|
29
|
+
},
|
|
30
|
+
"compilerOptions": {
|
|
31
|
+
"lib": [
|
|
32
|
+
"deno.window"
|
|
33
|
+
],
|
|
34
|
+
"strict": true
|
|
35
|
+
},
|
|
36
|
+
"imports": {
|
|
37
|
+
"@std/path": "jsr:@std/path@^1.0.0",
|
|
38
|
+
"@std/fmt": "jsr:@std/fmt@^1.0.0",
|
|
39
|
+
"@std/cli": "jsr:@std/cli@^1.0.0",
|
|
40
|
+
"@std/assert": "jsr:@std/assert@^1.0.0",
|
|
41
|
+
"@api.global/typedrequest": "npm:@api.global/typedrequest@^3.1.10",
|
|
42
|
+
"@push.rocks/npmextra": "npm:@push.rocks/npmextra@^5.1.2",
|
|
43
|
+
"@push.rocks/projectinfo": "npm:@push.rocks/projectinfo@^5.0.2",
|
|
44
|
+
"@push.rocks/qenv": "npm:@push.rocks/qenv@^6.0.2",
|
|
45
|
+
"@push.rocks/smartanalytics": "npm:@push.rocks/smartanalytics@^2.0.15",
|
|
46
|
+
"@push.rocks/smartcli": "npm:@push.rocks/smartcli@^4.0.11",
|
|
47
|
+
"@push.rocks/smartfile": "npm:@push.rocks/smartfile@^11.0.21",
|
|
48
|
+
"@push.rocks/smartgit": "npm:@push.rocks/smartgit@^3.1.1",
|
|
49
|
+
"@push.rocks/smartlog": "npm:@push.rocks/smartlog@^3.0.7",
|
|
50
|
+
"@push.rocks/smartlog-destination-local": "npm:@push.rocks/smartlog-destination-local@^9.0.0",
|
|
51
|
+
"@push.rocks/smartobject": "npm:@push.rocks/smartobject@^1.0.12",
|
|
52
|
+
"@push.rocks/smartpath": "npm:@push.rocks/smartpath@^5.0.11",
|
|
53
|
+
"@push.rocks/smartpromise": "npm:@push.rocks/smartpromise@^4.0.4",
|
|
54
|
+
"@push.rocks/smartrequest": "npm:@push.rocks/smartrequest@^2.0.23",
|
|
55
|
+
"@push.rocks/smartshell": "npm:@push.rocks/smartshell@^3.0.6",
|
|
56
|
+
"@push.rocks/smartsocket": "npm:@push.rocks/smartsocket@^2.0.22",
|
|
57
|
+
"@push.rocks/smartssh": "npm:@push.rocks/smartssh@^2.0.1",
|
|
58
|
+
"@push.rocks/smartstring": "npm:@push.rocks/smartstring@^4.0.8",
|
|
59
|
+
"@push.rocks/smartexpect": "npm:@push.rocks/smartexpect@^1.0.15",
|
|
60
|
+
"@serve.zone/api": "npm:@serve.zone/api@^4.3.11",
|
|
61
|
+
"@tsclass/tsclass": "npm:@tsclass/tsclass@^4.1.2"
|
|
62
|
+
}
|
|
63
|
+
}
|
package/mod.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env -S deno run --allow-all
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* SZCI - Serve Zone CI/CD Tool
|
|
5
|
+
*
|
|
6
|
+
* A command-line tool for streamlining Node.js and Docker workflows
|
|
7
|
+
* within CI environments, particularly GitLab CI, GitHub CI, and Gitea CI.
|
|
8
|
+
*
|
|
9
|
+
* Required Permissions:
|
|
10
|
+
* - --allow-net: Network access for Docker registries, npm, git operations
|
|
11
|
+
* - --allow-read: Read configuration files, Dockerfiles, package.json
|
|
12
|
+
* - --allow-write: Write configuration files, build artifacts
|
|
13
|
+
* - --allow-run: Execute system commands (docker, git, npm, ssh)
|
|
14
|
+
* - --allow-sys: Access system information (OS details)
|
|
15
|
+
* - --allow-env: Read/write environment variables
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { Szci } from './ts/szci.classes.szci.ts';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Main entry point for the SZCI application
|
|
24
|
+
* Parses command-line arguments and executes the requested command
|
|
25
|
+
*/
|
|
26
|
+
async function main(): Promise<void> {
|
|
27
|
+
// Create Szci instance
|
|
28
|
+
const szciInstance = new Szci();
|
|
29
|
+
|
|
30
|
+
// Start the CLI
|
|
31
|
+
// Deno.args is already 0-indexed (unlike Node's process.argv which starts at index 2)
|
|
32
|
+
// The smartcli library may expect process.argv format, so we might need to prepend placeholders
|
|
33
|
+
await szciInstance.start();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Execute main and handle errors
|
|
37
|
+
if (import.meta.main) {
|
|
38
|
+
try {
|
|
39
|
+
await main();
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
42
|
+
Deno.exit(1);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Export for programmatic use
|
|
47
|
+
export { Szci } from './ts/szci.classes.szci.ts';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ship.zone/szci",
|
|
3
|
-
"version": "7.1.
|
|
3
|
+
"version": "7.1.3",
|
|
4
4
|
"description": "Serve Zone CI - A tool to streamline Node.js and Docker workflows within CI environments, particularly GitLab CI, providing various CI/CD utilities. Powered by Deno with standalone executables.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Node.js",
|
|
@@ -34,14 +34,11 @@
|
|
|
34
34
|
"bin": {
|
|
35
35
|
"szci": "./bin/szci-wrapper.js"
|
|
36
36
|
},
|
|
37
|
-
"scripts": {
|
|
38
|
-
"postinstall": "node scripts/install-binary.js",
|
|
39
|
-
"prepublishOnly": "echo 'Publishing SZCI binaries to npm...'",
|
|
40
|
-
"test": "echo 'Tests are run with Deno: deno task test'",
|
|
41
|
-
"build": "echo 'no build needed'"
|
|
42
|
-
},
|
|
43
37
|
"files": [
|
|
44
38
|
"bin/",
|
|
39
|
+
"deno.json",
|
|
40
|
+
"mod.ts",
|
|
41
|
+
"ts/",
|
|
45
42
|
"scripts/install-binary.js",
|
|
46
43
|
"readme.md",
|
|
47
44
|
"license",
|
|
@@ -63,5 +60,9 @@
|
|
|
63
60
|
"access": "public",
|
|
64
61
|
"registry": "https://registry.npmjs.org/"
|
|
65
62
|
},
|
|
66
|
-
"
|
|
67
|
-
|
|
63
|
+
"scripts": {
|
|
64
|
+
"postinstall": "node scripts/install-binary.js",
|
|
65
|
+
"test": "echo 'Tests are run with Deno: deno task test'",
|
|
66
|
+
"build": "deno task compile"
|
|
67
|
+
}
|
|
68
|
+
}
|
package/readme.md
CHANGED
|
@@ -371,7 +371,7 @@ deno task lint
|
|
|
371
371
|
|
|
372
372
|
## License and Legal Information
|
|
373
373
|
|
|
374
|
-
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [
|
|
374
|
+
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./LICENSE) file.
|
|
375
375
|
|
|
376
376
|
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
|
|
377
377
|
|
|
@@ -383,7 +383,7 @@ Use of these trademarks must comply with Task Venture Capital GmbH's Trademark G
|
|
|
383
383
|
|
|
384
384
|
### Company Information
|
|
385
385
|
|
|
386
|
-
Task Venture Capital GmbH
|
|
386
|
+
Task Venture Capital GmbH
|
|
387
387
|
Registered at District Court Bremen HRB 35230 HB, Germany
|
|
388
388
|
|
|
389
389
|
For any legal inquiries or further information, please contact us via email at hello@task.vc.
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { platform, arch } from 'os';
|
|
9
|
-
import { existsSync, mkdirSync,
|
|
9
|
+
import { existsSync, mkdirSync, chmodSync, unlinkSync, readFileSync } from 'fs';
|
|
10
10
|
import { join, dirname } from 'path';
|
|
11
11
|
import { fileURLToPath } from 'url';
|
|
12
12
|
import https from 'https';
|
|
@@ -20,7 +20,21 @@ const streamPipeline = promisify(pipeline);
|
|
|
20
20
|
|
|
21
21
|
// Configuration
|
|
22
22
|
const REPO_BASE = 'https://code.foss.global/ship.zone/szci';
|
|
23
|
-
|
|
23
|
+
function getPackageVersion() {
|
|
24
|
+
if (process.env.npm_package_version) {
|
|
25
|
+
return process.env.npm_package_version;
|
|
26
|
+
}
|
|
27
|
+
const packageJsonPath = join(__dirname, '..', 'package.json');
|
|
28
|
+
if (existsSync(packageJsonPath)) {
|
|
29
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
30
|
+
if (packageJson.version) {
|
|
31
|
+
return packageJson.version;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return '0.0.0';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const VERSION = getPackageVersion();
|
|
24
38
|
|
|
25
39
|
function getBinaryInfo() {
|
|
26
40
|
const plat = platform();
|
|
@@ -156,7 +170,7 @@ async function main() {
|
|
|
156
170
|
// Construct download URL
|
|
157
171
|
// Try release URL first, fall back to raw branch if needed
|
|
158
172
|
const releaseUrl = `${REPO_BASE}/releases/download/v${VERSION}/${binaryInfo.binaryName}`;
|
|
159
|
-
const fallbackUrl = `${REPO_BASE}/raw/branch/
|
|
173
|
+
const fallbackUrl = `${REPO_BASE}/raw/branch/main/dist/binaries/${binaryInfo.binaryName}`;
|
|
160
174
|
|
|
161
175
|
console.log('Downloading platform-specific binary...');
|
|
162
176
|
console.log('This may take a moment depending on your connection speed.');
|
|
@@ -173,7 +187,7 @@ async function main() {
|
|
|
173
187
|
// Try fallback URL
|
|
174
188
|
await downloadFile(fallbackUrl, binaryPath);
|
|
175
189
|
} catch (fallbackErr) {
|
|
176
|
-
console.
|
|
190
|
+
console.warn(`⚠️ Warning: Failed to download binary`);
|
|
177
191
|
console.error(` Primary URL: ${releaseUrl}`);
|
|
178
192
|
console.error(` Fallback URL: ${fallbackUrl}`);
|
|
179
193
|
console.error('');
|
|
@@ -182,17 +196,14 @@ async function main() {
|
|
|
182
196
|
console.error('2. Network connectivity issues');
|
|
183
197
|
console.error('3. The version specified does not exist');
|
|
184
198
|
console.error('');
|
|
185
|
-
console.
|
|
186
|
-
console.error('1. Installing from source: https://code.foss.global/ship.zone/szci');
|
|
187
|
-
console.error('2. Downloading the binary manually from the releases page');
|
|
188
|
-
console.error('3. Building from source with: deno task compile');
|
|
199
|
+
console.warn('Continuing with the packaged Deno source fallback.');
|
|
189
200
|
|
|
190
201
|
// Clean up partial download
|
|
191
202
|
if (existsSync(binaryPath)) {
|
|
192
203
|
unlinkSync(binaryPath);
|
|
193
204
|
}
|
|
194
205
|
|
|
195
|
-
|
|
206
|
+
return;
|
|
196
207
|
}
|
|
197
208
|
}
|
|
198
209
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* autocreated commitinfo by @push.rocks/commitinfo
|
|
3
|
+
*/
|
|
4
|
+
export const commitinfo = {
|
|
5
|
+
name: '@ship.zone/szci',
|
|
6
|
+
version: '7.1.3',
|
|
7
|
+
description: 'Serve Zone CI - A tool to streamline Node.js and Docker workflows within CI environments, particularly GitLab CI, providing various CI/CD utilities. Powered by Deno with standalone executables.'
|
|
8
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as plugins from '../szci.plugins.ts';
|
|
2
|
+
|
|
3
|
+
import { Szci } from '../szci.classes.szci.ts';
|
|
4
|
+
import { logger } from '../szci.logging.ts';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* connects to cloudly
|
|
8
|
+
*/
|
|
9
|
+
export class CloudlyConnector {
|
|
10
|
+
public szciRef: Szci;
|
|
11
|
+
|
|
12
|
+
constructor(szciRefArg: Szci) {
|
|
13
|
+
this.szciRef = szciRefArg;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public async announceDockerContainer(
|
|
17
|
+
optionsArg: plugins.tsclass.container.IContainer,
|
|
18
|
+
testCloudlyUrlArg?: string
|
|
19
|
+
) {
|
|
20
|
+
const cloudlyUrl = testCloudlyUrlArg || this.szciRef.szciConfig.getConfig().urlCloudly;
|
|
21
|
+
if (!cloudlyUrl) {
|
|
22
|
+
logger.log(
|
|
23
|
+
'warn',
|
|
24
|
+
'no cloudly url provided. Thus we cannot announce the newly built Dockerimage!'
|
|
25
|
+
);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// lets push to cloudly here
|
|
30
|
+
}
|
|
31
|
+
}
|
package/ts/index.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { logger } from '../szci.logging.ts';
|
|
2
|
+
import { bash } from '../szci.bash.ts';
|
|
3
|
+
import { Szci } from '../szci.classes.szci.ts';
|
|
4
|
+
|
|
5
|
+
export class SzciDockerManager {
|
|
6
|
+
public szciRef: Szci;
|
|
7
|
+
|
|
8
|
+
constructor(szciArg: Szci) {
|
|
9
|
+
this.szciRef = szciArg;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Bridges SZCI_LOGIN_DOCKER* env vars to DOCKER_REGISTRY_N format for tsdocker,
|
|
14
|
+
* and handles GitLab CI registry auto-login.
|
|
15
|
+
*/
|
|
16
|
+
private bridgeEnvVars() {
|
|
17
|
+
const env = Deno.env.toObject();
|
|
18
|
+
|
|
19
|
+
// Bridge GitLab CI registry as DOCKER_REGISTRY_0
|
|
20
|
+
if (env['GITLAB_CI']) {
|
|
21
|
+
const ciJobToken = env['CI_JOB_TOKEN'];
|
|
22
|
+
if (!ciJobToken) {
|
|
23
|
+
logger.log('error', 'Running in GitLab CI, but no CI_JOB_TOKEN found!');
|
|
24
|
+
Deno.exit(1);
|
|
25
|
+
}
|
|
26
|
+
Deno.env.set('DOCKER_REGISTRY_0', `registry.gitlab.com|gitlab-ci-token|${ciJobToken}`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Bridge SZCI_LOGIN_DOCKER* → DOCKER_REGISTRY_N
|
|
30
|
+
let registryIndex = 1;
|
|
31
|
+
const sortedKeys = Object.keys(env)
|
|
32
|
+
.filter((key) => key.startsWith('SZCI_LOGIN_DOCKER'))
|
|
33
|
+
.sort();
|
|
34
|
+
for (const key of sortedKeys) {
|
|
35
|
+
Deno.env.set(`DOCKER_REGISTRY_${registryIndex}`, env[key]);
|
|
36
|
+
registryIndex++;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Handle cli input by bridging env vars and delegating to tsdocker.
|
|
42
|
+
*/
|
|
43
|
+
public handleCli = async (argvArg: any) => {
|
|
44
|
+
if (argvArg._.length < 2) {
|
|
45
|
+
logger.log(
|
|
46
|
+
'info',
|
|
47
|
+
`>>szci docker ...<< cli arguments invalid... Please read the documentation.`
|
|
48
|
+
);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
this.bridgeEnvVars();
|
|
53
|
+
|
|
54
|
+
const action: string = argvArg._[1];
|
|
55
|
+
const extraArgs = argvArg._.slice(2).join(' ');
|
|
56
|
+
|
|
57
|
+
switch (action) {
|
|
58
|
+
case 'build':
|
|
59
|
+
await bash(`npx @git.zone/tsdocker build ${extraArgs}`.trim());
|
|
60
|
+
break;
|
|
61
|
+
case 'login':
|
|
62
|
+
case 'prepare':
|
|
63
|
+
await bash(`npx @git.zone/tsdocker login ${extraArgs}`.trim());
|
|
64
|
+
break;
|
|
65
|
+
case 'test':
|
|
66
|
+
await bash(`npx @git.zone/tsdocker test ${extraArgs}`.trim());
|
|
67
|
+
break;
|
|
68
|
+
case 'push':
|
|
69
|
+
await bash(`npx @git.zone/tsdocker push ${extraArgs}`.trim());
|
|
70
|
+
break;
|
|
71
|
+
case 'pull':
|
|
72
|
+
await bash(`npx @git.zone/tsdocker pull ${extraArgs}`.trim());
|
|
73
|
+
break;
|
|
74
|
+
default:
|
|
75
|
+
logger.log('error', `>>szci docker ...<< action >>${action}<< not supported`);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { logger } from '../szci.logging.ts';
|
|
2
|
+
import * as plugins from './mod.plugins.ts';
|
|
3
|
+
import { bash, bashNoError } from '../szci.bash.ts';
|
|
4
|
+
import { Szci } from '../szci.classes.szci.ts';
|
|
5
|
+
|
|
6
|
+
export class SzciGitManager {
|
|
7
|
+
public szciRef: Szci;
|
|
8
|
+
|
|
9
|
+
constructor(szciRefArg: Szci) {
|
|
10
|
+
this.szciRef = szciRefArg;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* handle cli input
|
|
15
|
+
* @param argvArg
|
|
16
|
+
*/
|
|
17
|
+
public handleCli = async (argvArg: any) => {
|
|
18
|
+
if (argvArg._.length >= 2) {
|
|
19
|
+
const action: string = argvArg._[1];
|
|
20
|
+
switch (action) {
|
|
21
|
+
case 'mirror':
|
|
22
|
+
await this.mirror();
|
|
23
|
+
break;
|
|
24
|
+
default:
|
|
25
|
+
logger.log('error', `szci git -> action >>${action}<< not supported!`);
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
logger.log('info', `szci git -> cli arguments invalid! Please read the documentation.`);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
public mirror = async () => {
|
|
33
|
+
const githubToken = Deno.env.get("SZCI_GIT_GITHUBTOKEN");
|
|
34
|
+
const githubUser = Deno.env.get("SZCI_GIT_GITHUBGROUP") || this.szciRef.szciEnv.repo.user;
|
|
35
|
+
const githubRepo = Deno.env.get("SZCI_GIT_GITHUB") || this.szciRef.szciEnv.repo.repo;
|
|
36
|
+
if (
|
|
37
|
+
this.szciRef.szciConfig.getConfig().projectInfo.npm.packageJson.private === true ||
|
|
38
|
+
this.szciRef.szciConfig.getConfig().npmAccessLevel === 'private'
|
|
39
|
+
) {
|
|
40
|
+
logger.log(
|
|
41
|
+
'warn',
|
|
42
|
+
`refusing to mirror due to private property use a private mirror location instead`
|
|
43
|
+
);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (githubToken) {
|
|
47
|
+
logger.log('info', 'found github token.');
|
|
48
|
+
logger.log('info', 'attempting the mirror the repository to GitHub');
|
|
49
|
+
|
|
50
|
+
// remove old mirrors
|
|
51
|
+
await bashNoError('git remote rm mirror');
|
|
52
|
+
|
|
53
|
+
await bash(`git fetch`);
|
|
54
|
+
// add the mirror
|
|
55
|
+
await bashNoError(
|
|
56
|
+
`git remote add mirror https://${githubToken}@github.com/${githubUser}/${githubRepo}.git`
|
|
57
|
+
);
|
|
58
|
+
await bashNoError(`git push mirror --all`);
|
|
59
|
+
await bashNoError(`git checkout origin/master`);
|
|
60
|
+
await bashNoError(`git push mirror master`);
|
|
61
|
+
logger.log('ok', 'pushed all branches to mirror!');
|
|
62
|
+
await bashNoError(`git push mirror --tags`);
|
|
63
|
+
logger.log('ok', 'pushed all tags to mirror!');
|
|
64
|
+
// remove old mirrors
|
|
65
|
+
await bashNoError('git remote rm mirror');
|
|
66
|
+
} else {
|
|
67
|
+
logger.log('error', `cannot find SZCI_GIT_GITHUBTOKEN env var!`);
|
|
68
|
+
Deno.exit(1);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../szci.plugins.ts';
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import * as plugins from '../szci.plugins.ts';
|
|
2
|
+
import * as paths from '../szci.paths.ts';
|
|
3
|
+
|
|
4
|
+
import { logger } from '../szci.logging.ts';
|
|
5
|
+
import { bash, bashNoError, nvmAvailable } from '../szci.bash.ts';
|
|
6
|
+
import { Szci } from '../szci.classes.szci.ts';
|
|
7
|
+
|
|
8
|
+
export class SzciNodeJsManager {
|
|
9
|
+
public szciRef: Szci;
|
|
10
|
+
|
|
11
|
+
constructor(szciRefArg: Szci) {
|
|
12
|
+
this.szciRef = szciRefArg;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* handle cli input
|
|
17
|
+
* @param argvArg
|
|
18
|
+
*/
|
|
19
|
+
public async handleCli(argvArg: any) {
|
|
20
|
+
if (argvArg._.length >= 3) {
|
|
21
|
+
const action: string = argvArg._[1];
|
|
22
|
+
switch (action) {
|
|
23
|
+
case 'install':
|
|
24
|
+
await this.install(argvArg._[2]);
|
|
25
|
+
break;
|
|
26
|
+
default:
|
|
27
|
+
logger.log('error', `>>szci node ...<< action >>${action}<< not supported`);
|
|
28
|
+
Deno.exit(1);
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
31
|
+
logger.log(
|
|
32
|
+
'error',
|
|
33
|
+
`>>szci node ...<< cli arguments invalid... Please read the documentation.`
|
|
34
|
+
);
|
|
35
|
+
Deno.exit(1);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Install a specific version of node
|
|
41
|
+
* @param versionArg
|
|
42
|
+
*/
|
|
43
|
+
public async install(versionArg: any) {
|
|
44
|
+
logger.log('info', `now installing node version ${versionArg}`);
|
|
45
|
+
let version: string;
|
|
46
|
+
if (versionArg === 'stable') {
|
|
47
|
+
version = '22';
|
|
48
|
+
} else if (versionArg === 'lts') {
|
|
49
|
+
version = '20';
|
|
50
|
+
} else if (versionArg === 'legacy') {
|
|
51
|
+
version = '18';
|
|
52
|
+
} else {
|
|
53
|
+
version = versionArg;
|
|
54
|
+
}
|
|
55
|
+
if (await nvmAvailable.promise) {
|
|
56
|
+
await bash(`nvm install ${version} && nvm alias default ${version}`);
|
|
57
|
+
logger.log('success', `Node version ${version} successfully installed!`);
|
|
58
|
+
} else {
|
|
59
|
+
logger.log('warn', 'Nvm not in path so staying at installed node version!');
|
|
60
|
+
}
|
|
61
|
+
logger.log('info', 'now installing latest npm version');
|
|
62
|
+
await bash('npm install -g npm');
|
|
63
|
+
await bash('node -v');
|
|
64
|
+
await bash('npm -v');
|
|
65
|
+
|
|
66
|
+
// lets look for further config
|
|
67
|
+
const config = await this.szciRef.szciConfig.getConfig();
|
|
68
|
+
logger.log('info', 'Now checking for needed global npm tools...');
|
|
69
|
+
for (const npmTool of config.npmGlobalTools) {
|
|
70
|
+
logger.log('info', `Checking for global "${npmTool}"`);
|
|
71
|
+
const whichOutput: string = await bashNoError(`which ${npmTool}`);
|
|
72
|
+
const toolAvailable: boolean = !(/not\sfound/.test(whichOutput) || whichOutput === '');
|
|
73
|
+
if (toolAvailable) {
|
|
74
|
+
logger.log('info', `Tool ${npmTool} is available`);
|
|
75
|
+
} else {
|
|
76
|
+
logger.log('info', `globally installing ${npmTool} from npm`);
|
|
77
|
+
await bash(`npm install ${npmTool} -q -g`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
logger.log('success', 'all global npm tools specified in npmextra.json are now available!');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import * as plugins from './mod.plugins.ts';
|
|
2
|
+
import * as paths from '../szci.paths.ts';
|
|
3
|
+
|
|
4
|
+
import { logger } from '../szci.logging.ts';
|
|
5
|
+
import { bash, bashNoError, nvmAvailable } from '../szci.bash.ts';
|
|
6
|
+
import { Szci } from '../szci.classes.szci.ts';
|
|
7
|
+
|
|
8
|
+
export class SzciNpmManager {
|
|
9
|
+
public szciRef: Szci;
|
|
10
|
+
|
|
11
|
+
constructor(szciRefArg: Szci) {
|
|
12
|
+
this.szciRef = szciRefArg;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* handle cli input
|
|
17
|
+
* @param argvArg
|
|
18
|
+
*/
|
|
19
|
+
public async handleCli(argvArg: any) {
|
|
20
|
+
if (argvArg._.length >= 2) {
|
|
21
|
+
const action: string = argvArg._[1];
|
|
22
|
+
switch (action) {
|
|
23
|
+
case 'install':
|
|
24
|
+
await this.install();
|
|
25
|
+
break;
|
|
26
|
+
case 'build':
|
|
27
|
+
await this.build();
|
|
28
|
+
break;
|
|
29
|
+
case 'prepare':
|
|
30
|
+
await this.prepare();
|
|
31
|
+
break;
|
|
32
|
+
case 'test':
|
|
33
|
+
await this.test();
|
|
34
|
+
break;
|
|
35
|
+
case 'publish':
|
|
36
|
+
await this.publish();
|
|
37
|
+
break;
|
|
38
|
+
default:
|
|
39
|
+
logger.log('error', `>>szci npm ...<< action >>${action}<< not supported`);
|
|
40
|
+
Deno.exit(1);
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
logger.log(
|
|
44
|
+
'info',
|
|
45
|
+
`>>szci npm ...<< cli arguments invalid... Please read the documentation.`
|
|
46
|
+
);
|
|
47
|
+
Deno.exit(1);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* authenticates npm with token from env var
|
|
53
|
+
*/
|
|
54
|
+
public async prepare() {
|
|
55
|
+
logger.log('info', 'running >>npm prepare<<');
|
|
56
|
+
const config = this.szciRef.szciConfig.getConfig();
|
|
57
|
+
let npmrcFileString: string = '';
|
|
58
|
+
await plugins.smartobject.forEachMinimatch(
|
|
59
|
+
Deno.env.toObject(),
|
|
60
|
+
'SZCI_TOKEN_NPM*',
|
|
61
|
+
(npmEnvArg: string) => {
|
|
62
|
+
if (!npmEnvArg) {
|
|
63
|
+
logger.log('note','found empty token...');
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const npmRegistryUrl = npmEnvArg.split('|')[0];
|
|
67
|
+
logger.log('ok', `found token for ${npmRegistryUrl}`);
|
|
68
|
+
let npmToken = npmEnvArg.split('|')[1];
|
|
69
|
+
if (npmEnvArg.split('|')[2] && npmEnvArg.split('|')[2] === 'plain') {
|
|
70
|
+
logger.log('ok', 'npm token not base64 encoded.');
|
|
71
|
+
} else {
|
|
72
|
+
logger.log('ok', 'npm token base64 encoded.');
|
|
73
|
+
npmToken = plugins.smartstring.base64.decode(npmToken);
|
|
74
|
+
}
|
|
75
|
+
npmrcFileString += `//${npmRegistryUrl}/:_authToken="${npmToken}"\n`;
|
|
76
|
+
}
|
|
77
|
+
);
|
|
78
|
+
logger.log('info', `setting default npm registry to ${config.npmRegistryUrl}`);
|
|
79
|
+
npmrcFileString += `registry=https://${config.npmRegistryUrl}\n`;
|
|
80
|
+
|
|
81
|
+
// final check
|
|
82
|
+
if (npmrcFileString.length > 0) {
|
|
83
|
+
logger.log('info', 'found one or more access tokens');
|
|
84
|
+
} else {
|
|
85
|
+
logger.log('error', 'no access token found! Exiting!');
|
|
86
|
+
Deno.exit(1);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// lets save it to disk
|
|
90
|
+
plugins.smartfile.memory.toFsSync(npmrcFileString, '/root/.npmrc');
|
|
91
|
+
|
|
92
|
+
// lets set the cache directory
|
|
93
|
+
await bash(`npm config set cache ${paths.SzciCacheDir} --global `);
|
|
94
|
+
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* publish a package to npm
|
|
100
|
+
*/
|
|
101
|
+
public async publish() {
|
|
102
|
+
const buildPublishCommand = async () => {
|
|
103
|
+
let npmAccessCliString = ``;
|
|
104
|
+
let npmRegistryCliString = ``;
|
|
105
|
+
let publishVerdaccioAsWell = false;
|
|
106
|
+
const config = this.szciRef.szciConfig.getConfig();
|
|
107
|
+
const availableRegistries: string[] = [];
|
|
108
|
+
await plugins.smartobject.forEachMinimatch(
|
|
109
|
+
Deno.env.toObject(),
|
|
110
|
+
'SZCI_TOKEN_NPM*',
|
|
111
|
+
(npmEnvArg: string) => {
|
|
112
|
+
availableRegistries.push(npmEnvArg.split('|')[0]);
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
// -> configure package access level
|
|
117
|
+
if (config.npmAccessLevel) {
|
|
118
|
+
npmAccessCliString = `--access=${config.npmAccessLevel}`;
|
|
119
|
+
if (config.npmAccessLevel === 'public') {
|
|
120
|
+
publishVerdaccioAsWell = true;
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
throw new Error('You need to set a npmAccessLevel!!!');
|
|
124
|
+
}
|
|
125
|
+
// -> configure registry url
|
|
126
|
+
if (config.npmRegistryUrl) {
|
|
127
|
+
npmRegistryCliString = `--registry=https://${config.npmRegistryUrl}`;
|
|
128
|
+
} else {
|
|
129
|
+
logger.log('error', `no registry url specified. Can't publish!`);
|
|
130
|
+
Deno.exit(1);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
let publishCommand = `npm publish ${npmAccessCliString} ${npmRegistryCliString} `;
|
|
134
|
+
|
|
135
|
+
// publishEverywhere
|
|
136
|
+
if (publishVerdaccioAsWell) {
|
|
137
|
+
const verdaccioRegistry = availableRegistries.find((registryString) =>
|
|
138
|
+
registryString.startsWith('verdaccio')
|
|
139
|
+
);
|
|
140
|
+
if (verdaccioRegistry) {
|
|
141
|
+
logger.log(
|
|
142
|
+
'info',
|
|
143
|
+
`package is public and verdaccio registry is specified. Also publishing to Verdaccio!`
|
|
144
|
+
);
|
|
145
|
+
publishCommand = `${publishCommand} && npm publish ${npmAccessCliString} --registry=https://${verdaccioRegistry}`;
|
|
146
|
+
} else {
|
|
147
|
+
logger.log(
|
|
148
|
+
'error',
|
|
149
|
+
`This package should also be published to Verdaccio, however there is no Verdaccio registry data available!`
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return publishCommand;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
// -> preparing
|
|
157
|
+
logger.log('info', `now preparing environment:`);
|
|
158
|
+
this.prepare();
|
|
159
|
+
await bash(`npm -v`);
|
|
160
|
+
await bash(`pnpm -v`);
|
|
161
|
+
|
|
162
|
+
// -> build it
|
|
163
|
+
await this.install();
|
|
164
|
+
await this.build();
|
|
165
|
+
|
|
166
|
+
logger.log('success', `Nice!!! The build for the publication was successfull!`);
|
|
167
|
+
logger.log('info', `Lets clean up so we don't publish any packages that don't belong to us:`);
|
|
168
|
+
// -> clean up before we publish stuff
|
|
169
|
+
await bashNoError(`rm -r ./.szci_cache`);
|
|
170
|
+
await bash(`rm -r ./node_modules`);
|
|
171
|
+
|
|
172
|
+
logger.log('success', `Cleaned up!:`);
|
|
173
|
+
|
|
174
|
+
// -> publish it
|
|
175
|
+
logger.log('info', `now invoking npm to publish the package!`);
|
|
176
|
+
await bash(await buildPublishCommand());
|
|
177
|
+
logger.log('success', `Package was successfully published!`);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
public async install(): Promise<void> {
|
|
181
|
+
logger.log('info', 'now installing dependencies:');
|
|
182
|
+
await bash('pnpm install');
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
public async build(): Promise<void> {
|
|
186
|
+
logger.log('info', 'now building the project:');
|
|
187
|
+
await bash('pnpm run build');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
public async test(): Promise<void> {
|
|
191
|
+
logger.log('info', 'now starting tests:');
|
|
192
|
+
await bash('pnpm test');
|
|
193
|
+
}
|
|
194
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../szci.plugins.ts';
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { logger } from '../szci.logging.ts';
|
|
2
|
+
import * as plugins from './mod.plugins.ts';
|
|
3
|
+
|
|
4
|
+
let sshInstance: plugins.smartssh.SshInstance;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Interface for CLI arguments
|
|
8
|
+
*/
|
|
9
|
+
interface ICliArgs {
|
|
10
|
+
_: string[];
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Handle SSH CLI commands
|
|
16
|
+
*/
|
|
17
|
+
export const handleCli = async (argvArg: ICliArgs): Promise<void> => {
|
|
18
|
+
if (argvArg._.length >= 2) {
|
|
19
|
+
const action = argvArg._[1];
|
|
20
|
+
switch (action) {
|
|
21
|
+
case 'prepare':
|
|
22
|
+
await prepare();
|
|
23
|
+
break;
|
|
24
|
+
default:
|
|
25
|
+
logger.log('error', `action >>${action}<< not supported`);
|
|
26
|
+
Deno.exit(1);
|
|
27
|
+
}
|
|
28
|
+
} else {
|
|
29
|
+
logger.log('error', `>>szci ssh ...<< please specify an action!`);
|
|
30
|
+
Deno.exit(1);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Checks if a string value is defined and not a placeholder
|
|
36
|
+
*/
|
|
37
|
+
const isValidValue = (value: string | undefined): boolean => {
|
|
38
|
+
return Boolean(value && value !== 'undefined' && value !== '##');
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Checks for ENV vars in form of SZCI_SSHKEY_* and deploys any found ones
|
|
43
|
+
*/
|
|
44
|
+
export const prepare = async (): Promise<void> => {
|
|
45
|
+
sshInstance = new plugins.smartssh.SshInstance();
|
|
46
|
+
|
|
47
|
+
// Get all env vars and filter for SSH keys
|
|
48
|
+
const envVars = Deno.env.toObject();
|
|
49
|
+
const sshKeyEnvVars = Object.entries(envVars).filter(([key]) =>
|
|
50
|
+
key.startsWith('SZCI_SSHKEY_')
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
// Process each SSH key env var
|
|
54
|
+
for (const [key, value] of sshKeyEnvVars) {
|
|
55
|
+
logger.log('info', `Processing SSH key from ${key}`);
|
|
56
|
+
addSshKeyFromEnvVar(value);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Only write to disk if not in test mode
|
|
60
|
+
if (!Deno.env.get('SZCI_TEST')) {
|
|
61
|
+
try {
|
|
62
|
+
sshInstance.writeToDisk();
|
|
63
|
+
logger.log('ok', 'SSH keys written to disk');
|
|
64
|
+
} catch (error) {
|
|
65
|
+
logger.log('error', `Failed to write SSH keys: ${(error as Error).message}`);
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
logger.log('info', 'In test mode, so not storing SSH keys to disk!');
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Parses an SSH key env var and adds it to the SSH instance
|
|
75
|
+
* Format: host|privKeyBase64|pubKeyBase64
|
|
76
|
+
*/
|
|
77
|
+
const addSshKeyFromEnvVar = (sshkeyEnvVarArg: string): void => {
|
|
78
|
+
const [host, privKeyBase64, pubKeyBase64] = sshkeyEnvVarArg.split('|');
|
|
79
|
+
const sshKey = new plugins.smartssh.SshKey();
|
|
80
|
+
|
|
81
|
+
logger.log('info', `Found SSH identity for ${host || 'unknown host'}`);
|
|
82
|
+
|
|
83
|
+
if (isValidValue(host)) {
|
|
84
|
+
logger.log('info', '---> host defined!');
|
|
85
|
+
sshKey.host = host;
|
|
86
|
+
}
|
|
87
|
+
if (isValidValue(privKeyBase64)) {
|
|
88
|
+
logger.log('info', '---> privKey defined!');
|
|
89
|
+
sshKey.privKeyBase64 = privKeyBase64;
|
|
90
|
+
}
|
|
91
|
+
if (isValidValue(pubKeyBase64)) {
|
|
92
|
+
logger.log('info', '---> pubKey defined!');
|
|
93
|
+
sshKey.pubKeyBase64 = pubKeyBase64;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
sshInstance.addKey(sshKey);
|
|
97
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../szci.plugins.ts';
|
package/ts/szci.bash.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { logger } from './szci.logging.ts';
|
|
2
|
+
import * as plugins from './szci.plugins.ts';
|
|
3
|
+
import * as paths from './szci.paths.ts';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* wether nvm is available or not
|
|
7
|
+
*/
|
|
8
|
+
export let nvmAvailable = plugins.smartpromise.defer<boolean>();
|
|
9
|
+
/**
|
|
10
|
+
* the smartshell instance for szci
|
|
11
|
+
*/
|
|
12
|
+
const szciSmartshell = new plugins.smartshell.Smartshell({
|
|
13
|
+
executor: 'bash',
|
|
14
|
+
sourceFilePaths: [],
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* check for tools.
|
|
19
|
+
*/
|
|
20
|
+
const checkToolsAvailable = async () => {
|
|
21
|
+
// check for nvm
|
|
22
|
+
if (!Deno.env.get('SZCI_TEST')) {
|
|
23
|
+
if (
|
|
24
|
+
(await szciSmartshell.execSilent(`bash -c "source /usr/local/nvm/nvm.sh"`)).exitCode === 0
|
|
25
|
+
) {
|
|
26
|
+
szciSmartshell.shellEnv.addSourceFiles([`/usr/local/nvm/nvm.sh`]);
|
|
27
|
+
nvmAvailable.resolve(true);
|
|
28
|
+
} else if (
|
|
29
|
+
(await szciSmartshell.execSilent(`bash -c "source ~/.nvm/nvm.sh"`)).exitCode === 0
|
|
30
|
+
) {
|
|
31
|
+
szciSmartshell.shellEnv.addSourceFiles([`~/.nvm/nvm.sh`]);
|
|
32
|
+
nvmAvailable.resolve(true);
|
|
33
|
+
} else {
|
|
34
|
+
nvmAvailable.resolve(false);
|
|
35
|
+
}
|
|
36
|
+
} else {
|
|
37
|
+
nvmAvailable.resolve(true);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
checkToolsAvailable();
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* bash() allows using bash with nvm in path
|
|
44
|
+
* @param commandArg - The command to execute
|
|
45
|
+
* @param retryArg - The retryArg: 0 to any positive number will retry, -1 will always succeed, -2 will return undefined
|
|
46
|
+
*/
|
|
47
|
+
export let bash = async (commandArg: string, retryArg: number = 2): Promise<string> => {
|
|
48
|
+
await nvmAvailable.promise; // make sure nvm check has run
|
|
49
|
+
let execResult!: plugins.smartshell.IExecResult;
|
|
50
|
+
|
|
51
|
+
// determine if we fail
|
|
52
|
+
let failOnError: boolean = true;
|
|
53
|
+
if (retryArg === -1) {
|
|
54
|
+
failOnError = false;
|
|
55
|
+
retryArg = 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (!Deno.env.get('SZCI_TEST')) {
|
|
59
|
+
// SZCI_TEST is used during testing
|
|
60
|
+
for (let i = 0; i <= retryArg; i++) {
|
|
61
|
+
if (Deno.env.get('DEBUG_SZCI') === 'true') {
|
|
62
|
+
console.log(commandArg);
|
|
63
|
+
}
|
|
64
|
+
execResult = await szciSmartshell.exec(commandArg);
|
|
65
|
+
|
|
66
|
+
// determine how bash reacts to error and success
|
|
67
|
+
if (execResult.exitCode !== 0 && i === retryArg) {
|
|
68
|
+
// something went wrong and retries are exhausted
|
|
69
|
+
if (failOnError) {
|
|
70
|
+
logger.log('error', 'something went wrong and retries are exhausted');
|
|
71
|
+
Deno.exit(1);
|
|
72
|
+
}
|
|
73
|
+
} else if (execResult.exitCode === 0) {
|
|
74
|
+
// everything went fine, or no error wanted
|
|
75
|
+
i = retryArg + 1; // retry +1 breaks for loop, if everything works out ok retrials are not wanted
|
|
76
|
+
} else {
|
|
77
|
+
logger.log('warn', 'Something went wrong! Exit Code: ' + execResult.exitCode.toString());
|
|
78
|
+
logger.log('info', 'Retry ' + (i + 1).toString() + ' of ' + retryArg.toString());
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
logger.log('info', 'ShellExec would be: ' + commandArg);
|
|
83
|
+
execResult = {
|
|
84
|
+
exitCode: 0,
|
|
85
|
+
stdout: 'testOutput',
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return execResult.stdout;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* bashNoError allows executing stuff without throwing an error
|
|
93
|
+
*/
|
|
94
|
+
export let bashNoError = async (commandArg: string): Promise<string> => {
|
|
95
|
+
return await bash(commandArg, -1);
|
|
96
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as plugins from './szci.plugins.ts';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
// env
|
|
5
|
+
import { SzciEnv } from './szci.classes.szcienv.ts';
|
|
6
|
+
import { SzciInfo } from './szci.classes.szciinfo.ts';
|
|
7
|
+
import { SzciCli } from './szci.classes.szcicli.ts';
|
|
8
|
+
import { SzciConfig } from './szci.classes.szciconfig.ts';
|
|
9
|
+
|
|
10
|
+
// connectors
|
|
11
|
+
import { CloudlyConnector } from './connector.cloudly/cloudlyconnector.ts';
|
|
12
|
+
|
|
13
|
+
// managers
|
|
14
|
+
import { SzciDockerManager } from './manager.docker/index.ts';
|
|
15
|
+
import { SzciGitManager } from './manager.git/index.ts';
|
|
16
|
+
import { SzciNodeJsManager } from './manager.nodejs/index.ts';
|
|
17
|
+
import { SzciNpmManager } from './manager.npm/index.ts';
|
|
18
|
+
|
|
19
|
+
export class Szci {
|
|
20
|
+
public analytics: plugins.smartanalytics.Analytics;
|
|
21
|
+
public cloudlyConnector!: CloudlyConnector;
|
|
22
|
+
|
|
23
|
+
public szciEnv!: SzciEnv;
|
|
24
|
+
public szciInfo!: SzciInfo;
|
|
25
|
+
public szciConfig!: SzciConfig;
|
|
26
|
+
public szciCli!: SzciCli;
|
|
27
|
+
|
|
28
|
+
// managers
|
|
29
|
+
public dockerManager!: SzciDockerManager;
|
|
30
|
+
public gitManager!: SzciGitManager;
|
|
31
|
+
public nodejsManager!: SzciNodeJsManager;
|
|
32
|
+
public npmManager!: SzciNpmManager;
|
|
33
|
+
|
|
34
|
+
constructor() {
|
|
35
|
+
this.analytics = new plugins.smartanalytics.Analytics({
|
|
36
|
+
apiEndPoint: 'https://pubapi.lossless.one/analytics',
|
|
37
|
+
projectId: 'gitzone',
|
|
38
|
+
appName: 'szci',
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public async start() {
|
|
43
|
+
this.cloudlyConnector = new CloudlyConnector(this);
|
|
44
|
+
this.szciEnv = new SzciEnv(this);
|
|
45
|
+
this.szciInfo = new SzciInfo(this);
|
|
46
|
+
await this.szciInfo.printToConsole();
|
|
47
|
+
this.szciCli = new SzciCli(this);
|
|
48
|
+
this.szciConfig = new SzciConfig(this);
|
|
49
|
+
await this.szciConfig.init();
|
|
50
|
+
|
|
51
|
+
// managers
|
|
52
|
+
this.dockerManager = new SzciDockerManager(this);
|
|
53
|
+
this.gitManager = new SzciGitManager(this);
|
|
54
|
+
this.nodejsManager = new SzciNodeJsManager(this);
|
|
55
|
+
this.npmManager = new SzciNpmManager(this);
|
|
56
|
+
this.szciCli.startParse();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { logger } from './szci.logging.ts';
|
|
2
|
+
import * as plugins from './szci.plugins.ts';
|
|
3
|
+
import * as paths from './szci.paths.ts';
|
|
4
|
+
import { Szci } from './szci.classes.szci.ts';
|
|
5
|
+
|
|
6
|
+
export class SzciCli {
|
|
7
|
+
public szciRef: Szci;
|
|
8
|
+
public smartcli: plugins.smartcli.Smartcli;
|
|
9
|
+
|
|
10
|
+
constructor(szciArg: Szci) {
|
|
11
|
+
this.szciRef = szciArg;
|
|
12
|
+
this.smartcli = new plugins.smartcli.Smartcli();
|
|
13
|
+
this.smartcli.addVersion(this.szciRef.szciInfo.version);
|
|
14
|
+
|
|
15
|
+
// docker
|
|
16
|
+
this.smartcli.addCommand('docker').subscribe(
|
|
17
|
+
async (argvArg) => {
|
|
18
|
+
await this.szciRef.dockerManager.handleCli(argvArg);
|
|
19
|
+
},
|
|
20
|
+
(err) => {
|
|
21
|
+
console.log(err);
|
|
22
|
+
Deno.exit(1);
|
|
23
|
+
}
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
// git
|
|
27
|
+
this.smartcli.addCommand('git').subscribe(
|
|
28
|
+
async (argvArg) => {
|
|
29
|
+
await this.szciRef.gitManager.handleCli(argvArg);
|
|
30
|
+
},
|
|
31
|
+
(err) => {
|
|
32
|
+
console.log(err);
|
|
33
|
+
Deno.exit(1);
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
// node
|
|
38
|
+
this.smartcli.addCommand('node').subscribe(
|
|
39
|
+
async (argvArg) => {
|
|
40
|
+
await this.szciRef.nodejsManager.handleCli(argvArg);
|
|
41
|
+
},
|
|
42
|
+
(err) => {
|
|
43
|
+
console.log(err);
|
|
44
|
+
Deno.exit(1);
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
// npm
|
|
49
|
+
this.smartcli.addCommand('npm').subscribe(
|
|
50
|
+
async (argvArg) => {
|
|
51
|
+
await this.szciRef.npmManager.handleCli(argvArg);
|
|
52
|
+
},
|
|
53
|
+
(err) => {
|
|
54
|
+
console.log(err);
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
// ssh
|
|
59
|
+
this.smartcli.addCommand('ssh').subscribe(async (argvArg) => {
|
|
60
|
+
const modSsh = await import('./mod_ssh/index.ts');
|
|
61
|
+
await modSsh.handleCli(argvArg);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public startParse = () => {
|
|
66
|
+
this.smartcli.startParse();
|
|
67
|
+
};
|
|
68
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as plugins from './szci.plugins.ts';
|
|
2
|
+
import * as paths from './szci.paths.ts';
|
|
3
|
+
|
|
4
|
+
import { logger } from './szci.logging.ts';
|
|
5
|
+
import { Szci } from './szci.classes.szci.ts';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* the main config interface for szci
|
|
9
|
+
*/
|
|
10
|
+
export interface ISzciOptions {
|
|
11
|
+
projectInfo: plugins.projectinfo.ProjectInfo;
|
|
12
|
+
|
|
13
|
+
// npm
|
|
14
|
+
npmGlobalTools: string[];
|
|
15
|
+
npmAccessLevel?: 'private' | 'public';
|
|
16
|
+
npmRegistryUrl: string;
|
|
17
|
+
|
|
18
|
+
// urls
|
|
19
|
+
urlCloudly?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* a config class for Szci
|
|
24
|
+
*/
|
|
25
|
+
export class SzciConfig {
|
|
26
|
+
public szciRef: Szci;
|
|
27
|
+
|
|
28
|
+
public szciNpmextra!: plugins.npmextra.Npmextra;
|
|
29
|
+
public kvStorage!: plugins.npmextra.KeyValueStore;
|
|
30
|
+
public szciQenv!: plugins.qenv.Qenv;
|
|
31
|
+
|
|
32
|
+
private configObject!: ISzciOptions;
|
|
33
|
+
|
|
34
|
+
constructor(szciRefArg: Szci) {
|
|
35
|
+
this.szciRef = szciRefArg;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public async init() {
|
|
39
|
+
this.szciNpmextra = new plugins.npmextra.Npmextra(paths.cwd);
|
|
40
|
+
this.kvStorage = new plugins.npmextra.KeyValueStore({
|
|
41
|
+
typeArg: 'userHomeDir',
|
|
42
|
+
identityArg: `.szci_${this.szciRef.szciEnv.repo.user}_${this.szciRef.szciEnv.repo.repo}`,
|
|
43
|
+
});
|
|
44
|
+
this.szciQenv = new plugins.qenv.Qenv(
|
|
45
|
+
paths.SzciProjectDir,
|
|
46
|
+
paths.SzciProjectNogitDir,
|
|
47
|
+
false
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
this.configObject = {
|
|
51
|
+
projectInfo: new plugins.projectinfo.ProjectInfo(paths.cwd),
|
|
52
|
+
npmGlobalTools: [],
|
|
53
|
+
npmAccessLevel: 'private',
|
|
54
|
+
npmRegistryUrl: 'registry.npmjs.org',
|
|
55
|
+
urlCloudly: await this.szciQenv.getEnvVarOnDemand('SZCI_URL_CLOUDLY'),
|
|
56
|
+
};
|
|
57
|
+
this.configObject = this.szciNpmextra.dataFor<ISzciOptions>('@ship.zone/szci', this.configObject);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public getConfig(): ISzciOptions {
|
|
61
|
+
return this.configObject;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as plugins from './szci.plugins.ts';
|
|
2
|
+
import { Szci } from './szci.classes.szci.ts';
|
|
3
|
+
|
|
4
|
+
export class SzciEnv {
|
|
5
|
+
public szciRef: Szci;
|
|
6
|
+
|
|
7
|
+
public repoString: string;
|
|
8
|
+
public repo: plugins.smartstring.GitRepo;
|
|
9
|
+
|
|
10
|
+
constructor(szciRefArg: Szci) {
|
|
11
|
+
this.szciRef = szciRefArg;
|
|
12
|
+
|
|
13
|
+
// Determine repo string from environment
|
|
14
|
+
let repoUrl: string | undefined;
|
|
15
|
+
if (Deno.env.get("GITLAB_CI")) {
|
|
16
|
+
repoUrl = Deno.env.get("CI_REPOSITORY_URL");
|
|
17
|
+
}
|
|
18
|
+
if (!repoUrl && Deno.env.get("SZCI_COMPUTED_REPOURL")) {
|
|
19
|
+
repoUrl = Deno.env.get("SZCI_COMPUTED_REPOURL");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
this.repoString = repoUrl || 'https://undefined:undefined@github.com/undefined/undefined.git';
|
|
23
|
+
this.repo = new plugins.smartstring.GitRepo(this.repoString);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as plugins from './szci.plugins.ts';
|
|
2
|
+
import * as paths from './szci.paths.ts';
|
|
3
|
+
import { logger } from './szci.logging.ts';
|
|
4
|
+
import { Szci } from './szci.classes.szci.ts';
|
|
5
|
+
import denoConfig from '../deno.json' with { type: 'json' };
|
|
6
|
+
|
|
7
|
+
export class SzciInfo {
|
|
8
|
+
public szciRef: Szci;
|
|
9
|
+
public version = denoConfig.version;
|
|
10
|
+
|
|
11
|
+
constructor(szciArg: Szci) {
|
|
12
|
+
this.szciRef = szciArg;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public async printToConsole() {
|
|
16
|
+
await logger.log('info', `szci version: ${this.version}`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as plugins from './szci.plugins.ts';
|
|
2
|
+
|
|
3
|
+
export const logger = new plugins.smartlog.Smartlog({
|
|
4
|
+
logContext: {
|
|
5
|
+
company: 'Some Company',
|
|
6
|
+
companyunit: 'Some Unit',
|
|
7
|
+
containerName: 'Some ContainerName',
|
|
8
|
+
environment: 'test',
|
|
9
|
+
runtime: 'deno',
|
|
10
|
+
zone: 'Some Zone',
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
logger.addLogDestination(new plugins.smartlogDestinationLocal.DestinationLocal());
|
package/ts/szci.paths.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as plugins from './szci.plugins.ts';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Get current working directory (evaluated at call time, not module load time)
|
|
5
|
+
*/
|
|
6
|
+
export const getCwd = (): string => Deno.cwd();
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Current working directory - use getCwd() if you need the live value after chdir
|
|
10
|
+
* @deprecated Use getCwd() for dynamic cwd resolution
|
|
11
|
+
*/
|
|
12
|
+
export const cwd = Deno.cwd();
|
|
13
|
+
|
|
14
|
+
// package paths
|
|
15
|
+
export const SzciPackageRoot = plugins.path.join(
|
|
16
|
+
plugins.smartpath.get.dirnameFromImportMetaUrl(import.meta.url),
|
|
17
|
+
'../'
|
|
18
|
+
);
|
|
19
|
+
export const SzciPackageConfig = plugins.path.join(SzciPackageRoot, './config.json');
|
|
20
|
+
|
|
21
|
+
// project paths - use functions for dynamic resolution
|
|
22
|
+
export const getSzciProjectDir = (): string => getCwd();
|
|
23
|
+
export const getSzciProjectNogitDir = (): string => plugins.path.join(getCwd(), './.nogit');
|
|
24
|
+
export const getSzciTestDir = (): string => plugins.path.join(getCwd(), './test');
|
|
25
|
+
export const getSzciCacheDir = (): string => plugins.path.join(getCwd(), './.szci_cache');
|
|
26
|
+
|
|
27
|
+
// Static paths (for backwards compatibility - captured at module load)
|
|
28
|
+
export const SzciProjectDir = cwd;
|
|
29
|
+
export const SzciProjectNogitDir = plugins.path.join(SzciProjectDir, './.nogit');
|
|
30
|
+
export const SzciTestDir = plugins.path.join(cwd, './test');
|
|
31
|
+
export const SzciCacheDir = plugins.path.join(cwd, './.szci_cache');
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Deno std libraries
|
|
2
|
+
import * as path from '@std/path';
|
|
3
|
+
|
|
4
|
+
export { path };
|
|
5
|
+
|
|
6
|
+
// @apiglobal
|
|
7
|
+
import * as typedrequest from '@api.global/typedrequest';
|
|
8
|
+
|
|
9
|
+
export { typedrequest };
|
|
10
|
+
|
|
11
|
+
// @servezone
|
|
12
|
+
import * as servezoneApi from '@serve.zone/api';
|
|
13
|
+
|
|
14
|
+
export { servezoneApi };
|
|
15
|
+
|
|
16
|
+
// @push.rocks
|
|
17
|
+
import * as npmextra from '@push.rocks/npmextra';
|
|
18
|
+
import * as projectinfo from '@push.rocks/projectinfo';
|
|
19
|
+
import * as qenv from '@push.rocks/qenv';
|
|
20
|
+
import * as smartanalytics from '@push.rocks/smartanalytics';
|
|
21
|
+
import * as smartfile from '@push.rocks/smartfile';
|
|
22
|
+
import * as smartcli from '@push.rocks/smartcli';
|
|
23
|
+
import * as smartgit from '@push.rocks/smartgit';
|
|
24
|
+
import * as smartlog from '@push.rocks/smartlog';
|
|
25
|
+
import * as smartlogDestinationLocal from '@push.rocks/smartlog-destination-local';
|
|
26
|
+
import * as smartobject from '@push.rocks/smartobject';
|
|
27
|
+
import * as smartpath from '@push.rocks/smartpath';
|
|
28
|
+
import * as smartpromise from '@push.rocks/smartpromise';
|
|
29
|
+
import * as smartrequest from '@push.rocks/smartrequest';
|
|
30
|
+
import * as smartshell from '@push.rocks/smartshell';
|
|
31
|
+
import * as smartsocket from '@push.rocks/smartsocket';
|
|
32
|
+
import * as smartssh from '@push.rocks/smartssh';
|
|
33
|
+
import * as smartstring from '@push.rocks/smartstring';
|
|
34
|
+
|
|
35
|
+
export {
|
|
36
|
+
npmextra,
|
|
37
|
+
projectinfo,
|
|
38
|
+
qenv,
|
|
39
|
+
smartanalytics,
|
|
40
|
+
smartfile,
|
|
41
|
+
smartgit,
|
|
42
|
+
smartcli,
|
|
43
|
+
smartlog,
|
|
44
|
+
smartlogDestinationLocal,
|
|
45
|
+
smartobject,
|
|
46
|
+
smartpath,
|
|
47
|
+
smartpromise,
|
|
48
|
+
smartrequest,
|
|
49
|
+
smartshell,
|
|
50
|
+
smartsocket,
|
|
51
|
+
smartssh,
|
|
52
|
+
smartstring,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// @tsclass scope
|
|
56
|
+
import * as tsclass from '@tsclass/tsclass';
|
|
57
|
+
|
|
58
|
+
export { tsclass };
|
|
59
|
+
|
|
60
|
+
|