fix(core): update
This commit is contained in:
parent
9a4611b70f
commit
7191b172a4
@ -1,9 +1,4 @@
|
|||||||
{
|
{
|
||||||
"npmts": {
|
|
||||||
"mode": "default",
|
|
||||||
"coverageTreshold": "70",
|
|
||||||
"cli": true
|
|
||||||
},
|
|
||||||
"npmci": {
|
"npmci": {
|
||||||
"npmGlobalTools": [],
|
"npmGlobalTools": [],
|
||||||
"npmAccessLevel": "public",
|
"npmAccessLevel": "public",
|
||||||
|
15
package-lock.json
generated
15
package-lock.json
generated
@ -151,6 +151,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@pushrocks/qenv": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://verdaccio.lossless.one/@pushrocks%2fqenv/-/qenv-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-ip/yN8etdy4lOTeNjU7dyKB8oN9eEZG3P/DhFYXDAgqEo0oDUUckEjGZadTLhjLw4wb/oQZqrZ/RjXwlCrBciQ==",
|
||||||
|
"requires": {
|
||||||
|
"@pushrocks/smartfile": "^7.0.4",
|
||||||
|
"@pushrocks/smartlog": "^2.0.19"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@pushrocks/smartanalytics": {
|
"@pushrocks/smartanalytics": {
|
||||||
"version": "2.0.15",
|
"version": "2.0.15",
|
||||||
"resolved": "https://verdaccio.lossless.one/@pushrocks%2fsmartanalytics/-/smartanalytics-2.0.15.tgz",
|
"resolved": "https://verdaccio.lossless.one/@pushrocks%2fsmartanalytics/-/smartanalytics-2.0.15.tgz",
|
||||||
@ -261,9 +270,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@pushrocks/smartgit": {
|
"@pushrocks/smartgit": {
|
||||||
"version": "1.0.12",
|
"version": "1.0.13",
|
||||||
"resolved": "https://registry.npmjs.org/@pushrocks/smartgit/-/smartgit-1.0.12.tgz",
|
"resolved": "https://verdaccio.lossless.one/@pushrocks%2fsmartgit/-/smartgit-1.0.13.tgz",
|
||||||
"integrity": "sha512-RTEj2OA1twzkoNeSpOpI4rKyJGpeaKYKakRf8S72YAd8RfsNBObFeVk7rNniSH6cIbtLkGjL31wuvFUiQz8Spg==",
|
"integrity": "sha512-NHI9Umo5bzUVsrSb9RZSA+t9LFsXzeoFmTjIK/LtUd/4oyvbArPRs97tYe1ueufViW1HZh0vXZKigrHxlWvypA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@pushrocks/smartfile": "^7.0.4",
|
"@pushrocks/smartfile": "^7.0.4",
|
||||||
"@pushrocks/smartpath": "^4.0.1",
|
"@pushrocks/smartpath": "^4.0.1",
|
||||||
|
@ -36,11 +36,12 @@
|
|||||||
"@pushrocks/lik": "^3.0.11",
|
"@pushrocks/lik": "^3.0.11",
|
||||||
"@pushrocks/npmextra": "^3.0.5",
|
"@pushrocks/npmextra": "^3.0.5",
|
||||||
"@pushrocks/projectinfo": "^4.0.2",
|
"@pushrocks/projectinfo": "^4.0.2",
|
||||||
|
"@pushrocks/qenv": "^4.0.2",
|
||||||
"@pushrocks/smartanalytics": "^2.0.15",
|
"@pushrocks/smartanalytics": "^2.0.15",
|
||||||
"@pushrocks/smartcli": "^3.0.7",
|
"@pushrocks/smartcli": "^3.0.7",
|
||||||
"@pushrocks/smartdelay": "^2.0.3",
|
"@pushrocks/smartdelay": "^2.0.3",
|
||||||
"@pushrocks/smartfile": "^7.0.2",
|
"@pushrocks/smartfile": "^7.0.2",
|
||||||
"@pushrocks/smartgit": "^1.0.12",
|
"@pushrocks/smartgit": "^1.0.13",
|
||||||
"@pushrocks/smartlog": "^2.0.19",
|
"@pushrocks/smartlog": "^2.0.19",
|
||||||
"@pushrocks/smartlog-destination-local": "^8.0.2",
|
"@pushrocks/smartlog-destination-local": "^8.0.2",
|
||||||
"@pushrocks/smartparam": "^1.0.4",
|
"@pushrocks/smartparam": "^1.0.4",
|
||||||
|
51
test/test.ts
51
test/test.ts
@ -1,7 +1,6 @@
|
|||||||
import { tap, expect } from '@pushrocks/tapbundle';
|
import { tap, expect } from '@pushrocks/tapbundle';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
// Setup test
|
|
||||||
process.env.NPMTS_TEST = 'true';
|
process.env.NPMTS_TEST = 'true';
|
||||||
|
|
||||||
// set up environment
|
// set up environment
|
||||||
@ -18,66 +17,66 @@ process.cwd = () => {
|
|||||||
return path.join(__dirname, 'assets/');
|
return path.join(__dirname, 'assets/');
|
||||||
};
|
};
|
||||||
|
|
||||||
// require NPMCI files
|
import * as npmci from '../ts';
|
||||||
import '../ts/index';
|
|
||||||
import npmciModDocker = require('../ts/mod_docker/index');
|
|
||||||
import npmciModNpm = require('../ts/mod_npm/index');
|
|
||||||
import npmciModNode = require('../ts/mod_node/index');
|
|
||||||
import npmciModSsh = require('../ts/mod_ssh/index');
|
|
||||||
import npmciEnv = require('../ts/npmci.env');
|
|
||||||
|
|
||||||
// ======
|
// ======
|
||||||
// Docker
|
// Docker
|
||||||
// ======
|
// ======
|
||||||
|
|
||||||
let dockerfile1: npmciModDocker.Dockerfile;
|
let dockerfile1: npmci.Dockerfile;
|
||||||
let dockerfile2: npmciModDocker.Dockerfile;
|
let dockerfile2: npmci.Dockerfile;
|
||||||
let sortableArray: npmciModDocker.Dockerfile[];
|
let sortableArray: npmci.Dockerfile[];
|
||||||
|
|
||||||
tap.test('should return valid Dockerfiles', async () => {
|
tap.test('should return valid Dockerfiles', async () => {
|
||||||
dockerfile1 = new npmciModDocker.Dockerfile({ filePath: './Dockerfile', read: true });
|
const npmciInstance = new npmci.Npmci();
|
||||||
dockerfile2 = new npmciModDocker.Dockerfile({ filePath: './Dockerfile_sometag1', read: true });
|
dockerfile1 = new npmci.Dockerfile(npmciInstance.dockerManager, { filePath: './Dockerfile', read: true });
|
||||||
|
dockerfile2 = new npmci.Dockerfile(npmciInstance.dockerManager, { filePath: './Dockerfile_sometag1', read: true });
|
||||||
expect(dockerfile1.version).to.equal('latest');
|
expect(dockerfile1.version).to.equal('latest');
|
||||||
return expect(dockerfile2.version).to.equal('sometag1');
|
return expect(dockerfile2.version).to.equal('sometag1');
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should read a directory of Dockerfiles', async () => {
|
tap.test('should read a directory of Dockerfiles', async () => {
|
||||||
return npmciModDocker.helpers
|
const npmciInstance = new npmci.Npmci();
|
||||||
.readDockerfiles()
|
return npmci.Dockerfile
|
||||||
.then(async (readDockerfilesArrayArg: npmciModDocker.Dockerfile[]) => {
|
.readDockerfiles(npmciInstance.dockerManager)
|
||||||
|
.then(async (readDockerfilesArrayArg: npmci.Dockerfile[]) => {
|
||||||
sortableArray = readDockerfilesArrayArg;
|
sortableArray = readDockerfilesArrayArg;
|
||||||
return expect(readDockerfilesArrayArg[1].version).to.equal('sometag1');
|
return expect(readDockerfilesArrayArg[1].version).to.equal('sometag1');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should sort an array of Dockerfiles', async () => {
|
tap.test('should sort an array of Dockerfiles', async () => {
|
||||||
return npmciModDocker.helpers
|
return npmci.Dockerfile
|
||||||
.sortDockerfiles(sortableArray)
|
.sortDockerfiles(sortableArray)
|
||||||
.then(async (sortedArrayArg: npmciModDocker.Dockerfile[]) => {
|
.then(async (sortedArrayArg: npmci.Dockerfile[]) => {
|
||||||
console.log(sortedArrayArg);
|
console.log(sortedArrayArg);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should build all Dockerfiles', async () => {
|
tap.test('should build all Dockerfiles', async () => {
|
||||||
return npmciModDocker.handleCli({
|
const npmciInstance = new npmci.Npmci();
|
||||||
|
return npmciInstance.dockerManager.handleCli({
|
||||||
_: ['docker', 'build']
|
_: ['docker', 'build']
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should test all Dockerfiles', async () => {
|
tap.test('should test all Dockerfiles', async () => {
|
||||||
return await npmciModDocker.handleCli({
|
const npmciInstance = new npmci.Npmci();
|
||||||
|
return npmciInstance.dockerManager.handleCli({
|
||||||
_: ['docker', 'test']
|
_: ['docker', 'test']
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should test dockerfiles', async () => {
|
tap.test('should test dockerfiles', async () => {
|
||||||
return await npmciModDocker.handleCli({
|
const npmciInstance = new npmci.Npmci();
|
||||||
|
return npmciInstance.dockerManager.handleCli({
|
||||||
_: ['docker', 'test']
|
_: ['docker', 'test']
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should login docker daemon', async () => {
|
tap.test('should login docker daemon', async () => {
|
||||||
return await npmciModDocker.handleCli({
|
const npmciInstance = new npmci.Npmci();
|
||||||
|
return npmciInstance.dockerManager.handleCli({
|
||||||
_: ['docker', 'login']
|
_: ['docker', 'login']
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -86,6 +85,7 @@ tap.test('should login docker daemon', async () => {
|
|||||||
// SSH
|
// SSH
|
||||||
// ===
|
// ===
|
||||||
tap.test('should prepare SSH keys', async () => {
|
tap.test('should prepare SSH keys', async () => {
|
||||||
|
const npmciModSsh = await import('../ts/mod_ssh');
|
||||||
return await npmciModSsh.handleCli({
|
return await npmciModSsh.handleCli({
|
||||||
_: ['ssh', 'prepare']
|
_: ['ssh', 'prepare']
|
||||||
});
|
});
|
||||||
@ -95,13 +95,14 @@ tap.test('should prepare SSH keys', async () => {
|
|||||||
// node
|
// node
|
||||||
// ====
|
// ====
|
||||||
tap.test('should install a certain version of node', async () => {
|
tap.test('should install a certain version of node', async () => {
|
||||||
await npmciModNode.handleCli({
|
const npmciInstance = new npmci.Npmci();
|
||||||
|
await npmciInstance.nodejsManager.handleCli({
|
||||||
_: ['node', 'install', 'stable']
|
_: ['node', 'install', 'stable']
|
||||||
});
|
});
|
||||||
await npmciModNode.handleCli({
|
await npmciInstance.nodejsManager.handleCli({
|
||||||
_: ['node', 'install', 'lts']
|
_: ['node', 'install', 'lts']
|
||||||
});
|
});
|
||||||
await npmciModNode.handleCli({
|
await npmciInstance.nodejsManager.handleCli({
|
||||||
_: ['node', 'install', 'legacy']
|
_: ['node', 'install', 'legacy']
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
8
ts/connector.cloudly/cloudlyconnector.ts
Normal file
8
ts/connector.cloudly/cloudlyconnector.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import * as plugins from '../npmci.plugins';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export class CloudlyConnector {
|
||||||
|
|
||||||
|
}
|
11
ts/index.ts
11
ts/index.ts
@ -1 +1,10 @@
|
|||||||
import './npmci.cli';
|
import { Npmci } from './npmci.classes.npmci';
|
||||||
|
import { Dockerfile } from './manager.docker/mod.classes.dockerfile';
|
||||||
|
|
||||||
|
export const npmciInstance = new Npmci();
|
||||||
|
|
||||||
|
export { Dockerfile, Npmci };
|
||||||
|
|
||||||
|
if (process.env.CLI_CALL) {
|
||||||
|
npmciInstance.start();
|
||||||
|
}
|
||||||
|
177
ts/manager.docker/index.ts
Normal file
177
ts/manager.docker/index.ts
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
import { logger } from '../npmci.logging';
|
||||||
|
import * as plugins from './mod.plugins';
|
||||||
|
import * as paths from '../npmci.paths';
|
||||||
|
import { bash } from '../npmci.bash';
|
||||||
|
|
||||||
|
// classes
|
||||||
|
import { Npmci } from '../npmci.classes.npmci';
|
||||||
|
import { Dockerfile } from './mod.classes.dockerfile';
|
||||||
|
import { DockerRegistry } from './mod.classes.dockerregistry';
|
||||||
|
import { RegistryStorage } from './mod.classes.registrystorage';
|
||||||
|
|
||||||
|
export class NpmciDockerManager {
|
||||||
|
public npmciRef: Npmci;
|
||||||
|
public npmciRegistryStorage = new RegistryStorage();
|
||||||
|
|
||||||
|
constructor(npmciArg: Npmci) {
|
||||||
|
this.npmciRef = npmciArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle cli input
|
||||||
|
* @param argvArg
|
||||||
|
*/
|
||||||
|
public handleCli = async argvArg => {
|
||||||
|
if (argvArg._.length >= 2) {
|
||||||
|
const action: string = argvArg._[1];
|
||||||
|
switch (action) {
|
||||||
|
case 'build':
|
||||||
|
await this.build();
|
||||||
|
break;
|
||||||
|
case 'login':
|
||||||
|
case 'prepare':
|
||||||
|
await this.login();
|
||||||
|
break;
|
||||||
|
case 'test':
|
||||||
|
await this.test();
|
||||||
|
break;
|
||||||
|
case 'push':
|
||||||
|
await this.push(argvArg);
|
||||||
|
break;
|
||||||
|
case 'pull':
|
||||||
|
await this.pull(argvArg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logger.log('error', `>>npmci docker ...<< action >>${action}<< not supported`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.log(
|
||||||
|
'info',
|
||||||
|
`>>npmci docker ...<< cli arguments invalid... Please read the documentation.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* builds a cwd of Dockerfiles by triggering a promisechain
|
||||||
|
*/
|
||||||
|
public build = async () => {
|
||||||
|
await this.prepare();
|
||||||
|
logger.log('info', 'now building Dockerfiles...');
|
||||||
|
await Dockerfile.readDockerfiles(this)
|
||||||
|
.then(Dockerfile.sortDockerfiles)
|
||||||
|
.then(Dockerfile.mapDockerfiles)
|
||||||
|
.then(Dockerfile.buildDockerfiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* login to the DockerRegistries
|
||||||
|
*/
|
||||||
|
public login = async () => {
|
||||||
|
await this.prepare();
|
||||||
|
await this.npmciRegistryStorage.loginAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* logs in docker
|
||||||
|
*/
|
||||||
|
public prepare = async () => {
|
||||||
|
// Always login to GitLab Registry
|
||||||
|
if (!process.env.CI_BUILD_TOKEN || process.env.CI_BUILD_TOKEN === '') {
|
||||||
|
logger.log('error', 'No registry token specified by gitlab!');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
this.npmciRegistryStorage.addRegistry(
|
||||||
|
new DockerRegistry({
|
||||||
|
registryUrl: 'registry.gitlab.com',
|
||||||
|
username: 'gitlab-ci-token',
|
||||||
|
password: process.env.CI_BUILD_TOKEN
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// handle registries
|
||||||
|
await plugins.smartparam.forEachMinimatch(
|
||||||
|
process.env,
|
||||||
|
'NPMCI_LOGIN_DOCKER*',
|
||||||
|
async envString => {
|
||||||
|
this.npmciRegistryStorage.addRegistry(DockerRegistry.fromEnvString(envString));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pushes an image towards a registry
|
||||||
|
* @param argvArg
|
||||||
|
*/
|
||||||
|
public push = async argvArg => {
|
||||||
|
await this.prepare();
|
||||||
|
let dockerRegistryUrls: string[] = [];
|
||||||
|
|
||||||
|
// lets parse the input of cli and npmextra
|
||||||
|
if (argvArg._.length >= 3 && argvArg._[2] !== 'npmextra') {
|
||||||
|
dockerRegistryUrls.push(argvArg._[2]);
|
||||||
|
} else {
|
||||||
|
if (this.npmciRef.npmciConfig.getConfig().dockerRegistries.length === 0) {
|
||||||
|
logger.log(
|
||||||
|
'warn',
|
||||||
|
`There are no docker registries listed in npmextra.json! This is strange!`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
dockerRegistryUrls = dockerRegistryUrls.concat(
|
||||||
|
this.npmciRef.npmciConfig.getConfig().dockerRegistries
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// lets determine the suffix
|
||||||
|
let suffix = null;
|
||||||
|
if (argvArg._.length >= 4) {
|
||||||
|
suffix = argvArg._[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
// lets push to the registries
|
||||||
|
for (const dockerRegistryUrl of dockerRegistryUrls) {
|
||||||
|
const dockerfileArray = await Dockerfile.readDockerfiles(this)
|
||||||
|
.then(Dockerfile.sortDockerfiles)
|
||||||
|
.then(Dockerfile.mapDockerfiles);
|
||||||
|
const dockerRegistryToPushTo = this.npmciRegistryStorage.getRegistryByUrl(dockerRegistryUrl);
|
||||||
|
if (!dockerRegistryToPushTo) {
|
||||||
|
logger.log(
|
||||||
|
'error',
|
||||||
|
`Cannot push to registry ${dockerRegistryUrl}, because it was not found in the authenticated registry list.`
|
||||||
|
);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
for (const dockerfile of dockerfileArray) {
|
||||||
|
await dockerfile.push(dockerRegistryToPushTo, suffix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pulls an image
|
||||||
|
*/
|
||||||
|
public pull = async argvArg => {
|
||||||
|
await this.prepare();
|
||||||
|
const registryUrlArg = argvArg._[2];
|
||||||
|
let suffix = null;
|
||||||
|
if (argvArg._.length >= 4) {
|
||||||
|
suffix = argvArg._[3];
|
||||||
|
}
|
||||||
|
const localDockerRegistry = this.npmciRegistryStorage.getRegistryByUrl(registryUrlArg);
|
||||||
|
const dockerfileArray = await Dockerfile.readDockerfiles(this)
|
||||||
|
.then(Dockerfile.sortDockerfiles)
|
||||||
|
.then(Dockerfile.mapDockerfiles);
|
||||||
|
for (const dockerfile of dockerfileArray) {
|
||||||
|
await dockerfile.pull(localDockerRegistry, suffix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tests docker files
|
||||||
|
*/
|
||||||
|
public test = async () => {
|
||||||
|
await this.prepare();
|
||||||
|
return await Dockerfile.readDockerfiles(this).then(Dockerfile.testDockerfiles);
|
||||||
|
}
|
||||||
|
}
|
316
ts/manager.docker/mod.classes.dockerfile.ts
Normal file
316
ts/manager.docker/mod.classes.dockerfile.ts
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
import * as plugins from './mod.plugins';
|
||||||
|
import * as paths from '../npmci.paths';
|
||||||
|
|
||||||
|
import { logger } from '../npmci.logging';
|
||||||
|
import { bash } from '../npmci.bash';
|
||||||
|
|
||||||
|
import { DockerRegistry } from './mod.classes.dockerregistry';
|
||||||
|
import * as helpers from './mod.helpers';
|
||||||
|
import { NpmciDockerManager } from '.';
|
||||||
|
import { Npmci } from '../npmci.classes.npmci';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* class Dockerfile represents a Dockerfile on disk in npmci
|
||||||
|
*/
|
||||||
|
export class Dockerfile {
|
||||||
|
// STATIC
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates instance of class Dockerfile for all Dockerfiles in cwd
|
||||||
|
* @returns Promise<Dockerfile[]>
|
||||||
|
*/
|
||||||
|
public static async readDockerfiles(
|
||||||
|
npmciDockerManagerRefArg: NpmciDockerManager
|
||||||
|
): Promise<Dockerfile[]> {
|
||||||
|
const fileTree = await plugins.smartfile.fs.listFileTree(paths.cwd, 'Dockerfile*');
|
||||||
|
|
||||||
|
// create the Dockerfile array
|
||||||
|
const readDockerfilesArray: Dockerfile[] = [];
|
||||||
|
logger.log('info', `found ${fileTree.length} Dockerfiles:`);
|
||||||
|
console.log(fileTree);
|
||||||
|
for (const dockerfilePath of fileTree) {
|
||||||
|
const myDockerfile = new Dockerfile(npmciDockerManagerRefArg, {
|
||||||
|
filePath: dockerfilePath,
|
||||||
|
read: true
|
||||||
|
});
|
||||||
|
readDockerfilesArray.push(myDockerfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
return readDockerfilesArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sorts Dockerfiles into a dependency chain
|
||||||
|
* @param sortableArrayArg an array of instances of class Dockerfile
|
||||||
|
* @returns Promise<Dockerfile[]>
|
||||||
|
*/
|
||||||
|
public static async sortDockerfiles(sortableArrayArg: Dockerfile[]): Promise<Dockerfile[]> {
|
||||||
|
const done = plugins.smartpromise.defer<Dockerfile[]>();
|
||||||
|
logger.log('info', 'sorting Dockerfiles:');
|
||||||
|
const sortedArray: Dockerfile[] = [];
|
||||||
|
const cleanTagsOriginal = Dockerfile.cleanTagsArrayFunction(sortableArrayArg, sortedArray);
|
||||||
|
let sorterFunctionCounter: number = 0;
|
||||||
|
const sorterFunction = () => {
|
||||||
|
sortableArrayArg.forEach(dockerfileArg => {
|
||||||
|
const cleanTags = Dockerfile.cleanTagsArrayFunction(sortableArrayArg, sortedArray);
|
||||||
|
if (
|
||||||
|
cleanTags.indexOf(dockerfileArg.baseImage) === -1 &&
|
||||||
|
sortedArray.indexOf(dockerfileArg) === -1
|
||||||
|
) {
|
||||||
|
sortedArray.push(dockerfileArg);
|
||||||
|
}
|
||||||
|
if (cleanTagsOriginal.indexOf(dockerfileArg.baseImage) !== -1) {
|
||||||
|
dockerfileArg.localBaseImageDependent = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (sortableArrayArg.length === sortedArray.length) {
|
||||||
|
let counter = 1;
|
||||||
|
for (const dockerfile of sortedArray) {
|
||||||
|
logger.log('info', `tag ${counter}: -> ${dockerfile.cleanTag}`);
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
done.resolve(sortedArray);
|
||||||
|
} else if (sorterFunctionCounter < 10) {
|
||||||
|
sorterFunctionCounter++;
|
||||||
|
sorterFunction();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
sorterFunction();
|
||||||
|
return done.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* maps local Dockerfiles dependencies to the correspoding Dockerfile class instances
|
||||||
|
*/
|
||||||
|
public static async mapDockerfiles(sortedDockerfileArray: Dockerfile[]): Promise<Dockerfile[]> {
|
||||||
|
sortedDockerfileArray.forEach(dockerfileArg => {
|
||||||
|
if (dockerfileArg.localBaseImageDependent) {
|
||||||
|
sortedDockerfileArray.forEach((dockfile2: Dockerfile) => {
|
||||||
|
if (dockfile2.cleanTag === dockerfileArg.baseImage) {
|
||||||
|
dockerfileArg.localBaseDockerfile = dockfile2;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return sortedDockerfileArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* builds the correspoding real docker image for each Dockerfile class instance
|
||||||
|
*/
|
||||||
|
public static async buildDockerfiles(sortedArrayArg: Dockerfile[]) {
|
||||||
|
for (const dockerfileArg of sortedArrayArg) {
|
||||||
|
await dockerfileArg.build();
|
||||||
|
}
|
||||||
|
return sortedArrayArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tests all Dockerfiles in by calling class Dockerfile.test();
|
||||||
|
* @param sortedArrayArg Dockerfile[] that contains all Dockerfiles in cwd
|
||||||
|
*/
|
||||||
|
public static async testDockerfiles(sortedArrayArg: Dockerfile[]) {
|
||||||
|
for (const dockerfileArg of sortedArrayArg) {
|
||||||
|
await dockerfileArg.test();
|
||||||
|
}
|
||||||
|
return sortedArrayArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns a version for a docker file
|
||||||
|
* @execution SYNC
|
||||||
|
*/
|
||||||
|
public static dockerFileVersion(dockerfileNameArg: string): string {
|
||||||
|
let versionString: string;
|
||||||
|
const versionRegex = /Dockerfile_([a-zA-Z0-9\.]*)$/;
|
||||||
|
const regexResultArray = versionRegex.exec(dockerfileNameArg);
|
||||||
|
if (regexResultArray && regexResultArray.length === 2) {
|
||||||
|
versionString = regexResultArray[1];
|
||||||
|
} else {
|
||||||
|
versionString = 'latest';
|
||||||
|
}
|
||||||
|
return versionString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the docker base image for a Dockerfile
|
||||||
|
*/
|
||||||
|
public static dockerBaseImage(dockerfileContentArg: string): string {
|
||||||
|
const baseImageRegex = /FROM\s([a-zA-z0-9\/\-\:]*)\n?/;
|
||||||
|
const regexResultArray = baseImageRegex.exec(dockerfileContentArg);
|
||||||
|
return regexResultArray[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the docker tag
|
||||||
|
*/
|
||||||
|
public static getDockerTagString(
|
||||||
|
npmciDockerManagerRef: NpmciDockerManager,
|
||||||
|
registryArg: string,
|
||||||
|
repoArg: string,
|
||||||
|
versionArg: string,
|
||||||
|
suffixArg?: string
|
||||||
|
): string {
|
||||||
|
// determine wether the repo should be mapped accordingly to the registry
|
||||||
|
const mappedRepo = npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().dockerRegistryRepoMap[
|
||||||
|
registryArg
|
||||||
|
];
|
||||||
|
const repo = (() => {
|
||||||
|
if (mappedRepo) {
|
||||||
|
return mappedRepo;
|
||||||
|
} else {
|
||||||
|
return repoArg;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
// determine wether the version contais a suffix
|
||||||
|
let version = versionArg;
|
||||||
|
if (suffixArg) {
|
||||||
|
version = versionArg + '_' + suffixArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tagString = `${registryArg}/${repo}:${version}`;
|
||||||
|
return tagString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async getDockerBuildArgs(
|
||||||
|
npmciDockerManagerRef: NpmciDockerManager
|
||||||
|
): Promise<string> {
|
||||||
|
logger.log('info', 'checking for env vars to be supplied to the docker build');
|
||||||
|
let buildArgsString: string = '';
|
||||||
|
for (const key of Object.keys(
|
||||||
|
npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().dockerBuildargEnvMap
|
||||||
|
)) {
|
||||||
|
const targetValue =
|
||||||
|
process.env[
|
||||||
|
npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().dockerBuildargEnvMap[key]
|
||||||
|
];
|
||||||
|
buildArgsString = `${buildArgsString} --build-arg ${key}="${targetValue}"`;
|
||||||
|
}
|
||||||
|
return buildArgsString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static cleanTagsArrayFunction(
|
||||||
|
dockerfileArrayArg: Dockerfile[],
|
||||||
|
trackingArrayArg: Dockerfile[]
|
||||||
|
): string[] {
|
||||||
|
const cleanTagsArray: string[] = [];
|
||||||
|
dockerfileArrayArg.forEach(dockerfileArg => {
|
||||||
|
if (trackingArrayArg.indexOf(dockerfileArg) === -1) {
|
||||||
|
cleanTagsArray.push(dockerfileArg.cleanTag);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return cleanTagsArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
// INSTANCE
|
||||||
|
public npmciDockerManagerRef: NpmciDockerManager;
|
||||||
|
|
||||||
|
public filePath: string;
|
||||||
|
public repo: string;
|
||||||
|
public version: string;
|
||||||
|
public cleanTag: string;
|
||||||
|
public buildTag: string;
|
||||||
|
public containerName: string;
|
||||||
|
public content: string;
|
||||||
|
public baseImage: string;
|
||||||
|
public localBaseImageDependent: boolean;
|
||||||
|
public localBaseDockerfile: Dockerfile;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
dockerManagerRefArg: NpmciDockerManager,
|
||||||
|
options: { filePath?: string; fileContents?: string | Buffer; read?: boolean }
|
||||||
|
) {
|
||||||
|
this.npmciDockerManagerRef = dockerManagerRefArg;
|
||||||
|
this.filePath = options.filePath;
|
||||||
|
this.repo =
|
||||||
|
this.npmciDockerManagerRef.npmciRef.npmciEnv.repo.user +
|
||||||
|
'/' +
|
||||||
|
this.npmciDockerManagerRef.npmciRef.npmciEnv.repo.repo;
|
||||||
|
this.version = Dockerfile.dockerFileVersion(plugins.path.parse(options.filePath).base);
|
||||||
|
this.cleanTag = this.repo + ':' + this.version;
|
||||||
|
this.buildTag = this.cleanTag;
|
||||||
|
|
||||||
|
this.containerName = 'dockerfile-' + this.version;
|
||||||
|
if (options.filePath && options.read) {
|
||||||
|
this.content = plugins.smartfile.fs.toStringSync(plugins.path.resolve(options.filePath));
|
||||||
|
}
|
||||||
|
this.baseImage = Dockerfile.dockerBaseImage(this.content);
|
||||||
|
this.localBaseImageDependent = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* builds the Dockerfile
|
||||||
|
*/
|
||||||
|
public async build() {
|
||||||
|
logger.log('info', 'now building Dockerfile for ' + this.cleanTag);
|
||||||
|
const buildArgsString = await Dockerfile.getDockerBuildArgs(this.npmciDockerManagerRef);
|
||||||
|
const buildCommand = `docker build -t ${this.buildTag} -f ${this.filePath} ${buildArgsString} .`;
|
||||||
|
await bash(buildCommand);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pushes the Dockerfile to a registry
|
||||||
|
*/
|
||||||
|
public async push(dockerRegistryArg: DockerRegistry, versionSuffix: string = null) {
|
||||||
|
const pushTag = Dockerfile.getDockerTagString(
|
||||||
|
this.npmciDockerManagerRef,
|
||||||
|
dockerRegistryArg.registryUrl,
|
||||||
|
this.repo,
|
||||||
|
this.version,
|
||||||
|
versionSuffix
|
||||||
|
);
|
||||||
|
await bash(`docker tag ${this.buildTag} ${pushTag}`);
|
||||||
|
await bash(`docker push ${pushTag}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pulls the Dockerfile from a registry
|
||||||
|
*/
|
||||||
|
public async pull(registryArg: DockerRegistry, versionSuffixArg: string = null) {
|
||||||
|
const pullTag = Dockerfile.getDockerTagString(
|
||||||
|
this.npmciDockerManagerRef,
|
||||||
|
registryArg.registryUrl,
|
||||||
|
this.repo,
|
||||||
|
this.version,
|
||||||
|
versionSuffixArg
|
||||||
|
);
|
||||||
|
await bash(`docker pull ${pullTag}`);
|
||||||
|
await bash(`docker tag ${pullTag} ${this.buildTag}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tests the Dockerfile;
|
||||||
|
*/
|
||||||
|
public async test() {
|
||||||
|
const testFile: string = plugins.path.join(paths.NpmciTestDir, 'test_' + this.version + '.sh');
|
||||||
|
const testFileExists: boolean = plugins.smartfile.fs.fileExistsSync(testFile);
|
||||||
|
if (testFileExists) {
|
||||||
|
// run tests
|
||||||
|
await bash(
|
||||||
|
`docker run --name npmci_test_container --entrypoint="bash" ${this.buildTag} -c "mkdir /npmci_test"`
|
||||||
|
);
|
||||||
|
await bash(`docker cp ${testFile} npmci_test_container:/npmci_test/test.sh`);
|
||||||
|
await bash(`docker commit npmci_test_container npmci_test_image`);
|
||||||
|
await bash(`docker run --entrypoint="bash" npmci_test_image -x /npmci_test/test.sh`);
|
||||||
|
await bash(`docker rm npmci_test_container`);
|
||||||
|
await bash(`docker rmi --force npmci_test_image`);
|
||||||
|
} else {
|
||||||
|
logger.log('warn', 'skipping tests for ' + this.cleanTag + ' because no testfile was found!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gets the id of a Dockerfile
|
||||||
|
*/
|
||||||
|
public async getId() {
|
||||||
|
const containerId = await bash(
|
||||||
|
'docker inspect --type=image --format="{{.Id}}" ' + this.buildTag
|
||||||
|
);
|
||||||
|
return containerId;
|
||||||
|
}
|
||||||
|
}
|
6
ts/manager.docker/mod.helpers.ts
Normal file
6
ts/manager.docker/mod.helpers.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { logger } from '../npmci.logging';
|
||||||
|
import * as plugins from './mod.plugins';
|
||||||
|
import * as paths from '../npmci.paths';
|
||||||
|
|
||||||
|
import { Dockerfile } from './mod.classes.dockerfile';
|
||||||
|
|
65
ts/manager.git/index.ts
Normal file
65
ts/manager.git/index.ts
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import { logger } from '../npmci.logging';
|
||||||
|
import * as plugins from './mod.plugins';
|
||||||
|
import { bash } from '../npmci.bash';
|
||||||
|
import { Npmci } from '../npmci.classes.npmci';
|
||||||
|
|
||||||
|
export class NpmciGitManager {
|
||||||
|
public npmciRef: Npmci;
|
||||||
|
|
||||||
|
constructor(npmciRefArg: Npmci) {
|
||||||
|
this.npmciRef = npmciRefArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle cli input
|
||||||
|
* @param argvArg
|
||||||
|
*/
|
||||||
|
public handleCli = async argvArg => {
|
||||||
|
if (argvArg._.length >= 2) {
|
||||||
|
const action: string = argvArg._[1];
|
||||||
|
switch (action) {
|
||||||
|
case 'mirror':
|
||||||
|
await this.mirror();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logger.log('error', `npmci git -> action >>${action}<< not supported!`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.log('info', `npmci git -> cli arguments invalid! Please read the documentation.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public mirror = async () => {
|
||||||
|
const githubToken = process.env.NPMCI_GIT_GITHUBTOKEN;
|
||||||
|
const githubUser = process.env.NPMCI_GIT_GITHUBGROUP || this.npmciRef.npmciEnv.repo.user;
|
||||||
|
const githubRepo = process.env.NPMCI_GIT_GITHUB || this.npmciRef.npmciEnv.repo;
|
||||||
|
if (
|
||||||
|
this.npmciRef.npmciConfig.getConfig().projectInfo.npm.packageJson.private === true ||
|
||||||
|
this.npmciRef.npmciConfig.getConfig().npmAccessLevel === 'private'
|
||||||
|
) {
|
||||||
|
logger.log(
|
||||||
|
'warn',
|
||||||
|
`refusing to mirror due to private property use a private mirror location instead`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (githubToken) {
|
||||||
|
logger.log('info', 'found github token.');
|
||||||
|
logger.log('info', 'attempting the mirror the repository to GitHub');
|
||||||
|
|
||||||
|
// plugins.smartgit.GitRepo;
|
||||||
|
|
||||||
|
// add the mirror
|
||||||
|
await bash(
|
||||||
|
`git remote add mirror https://${githubToken}@github.com/${githubUser}/${githubRepo}.git`
|
||||||
|
);
|
||||||
|
await bash(`git push mirror --all`);
|
||||||
|
logger.log('ok', 'pushed all branches to mirror!');
|
||||||
|
await bash(`git push mirror --tags`);
|
||||||
|
logger.log('ok', 'pushed all tags to mirror!');
|
||||||
|
} else {
|
||||||
|
logger.log('error', `cannot find NPMCI_GIT_GITHUBTOKEN env var!`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
83
ts/manager.nodejs/index.ts
Normal file
83
ts/manager.nodejs/index.ts
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import * as plugins from '../npmci.plugins';
|
||||||
|
import * as paths from '../npmci.paths';
|
||||||
|
|
||||||
|
import { logger } from '../npmci.logging';
|
||||||
|
import { bash, bashNoError, nvmAvailable } from '../npmci.bash';
|
||||||
|
import { Npmci } from '../npmci.classes.npmci';
|
||||||
|
|
||||||
|
export class NpmciNodeJsManager {
|
||||||
|
public npmciRef: Npmci;
|
||||||
|
|
||||||
|
constructor(npmciRefArg: Npmci) {
|
||||||
|
this.npmciRef = npmciRefArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle cli input
|
||||||
|
* @param argvArg
|
||||||
|
*/
|
||||||
|
public async handleCli(argvArg) {
|
||||||
|
if (argvArg._.length >= 3) {
|
||||||
|
const action: string = argvArg._[1];
|
||||||
|
switch (action) {
|
||||||
|
case 'install':
|
||||||
|
await this.install(argvArg._[2]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logger.log('error', `>>npmci node ...<< action >>${action}<< not supported`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.log(
|
||||||
|
'error',
|
||||||
|
`>>npmci node ...<< cli arguments invalid... Please read the documentation.`
|
||||||
|
);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install a specific version of node
|
||||||
|
* @param versionArg
|
||||||
|
*/
|
||||||
|
public async install(versionArg) {
|
||||||
|
logger.log('info', `now installing node version ${versionArg}`);
|
||||||
|
let version: string;
|
||||||
|
if (versionArg === 'stable') {
|
||||||
|
version = '12';
|
||||||
|
} else if (versionArg === 'lts') {
|
||||||
|
version = '10';
|
||||||
|
} else if (versionArg === 'legacy') {
|
||||||
|
version = '8';
|
||||||
|
} else {
|
||||||
|
version = versionArg;
|
||||||
|
}
|
||||||
|
if (await nvmAvailable.promise) {
|
||||||
|
await bash(`nvm install ${version} && nvm alias default ${version}`);
|
||||||
|
logger.log('success', `Node version ${version} successfully installed!`);
|
||||||
|
} else {
|
||||||
|
logger.log('warn', 'Nvm not in path so staying at installed node version!');
|
||||||
|
}
|
||||||
|
logger.log('info', 'now installing latest npm version');
|
||||||
|
await bash('npm install -g npm');
|
||||||
|
await bash('node -v');
|
||||||
|
await bash('npm -v');
|
||||||
|
await bash(`npm config set cache ${paths.NpmciCacheDir} --global `);
|
||||||
|
|
||||||
|
// lets look for further config
|
||||||
|
const config = await this.npmciRef.npmciConfig.getConfig();
|
||||||
|
logger.log('info', 'Now checking for needed global npm tools...');
|
||||||
|
for (const npmTool of config.npmGlobalTools) {
|
||||||
|
logger.log('info', `Checking for global "${npmTool}"`);
|
||||||
|
const whichOutput: string = await bashNoError(`which ${npmTool}`);
|
||||||
|
const toolAvailable: boolean = !(/not\sfound/.test(whichOutput) || whichOutput === '');
|
||||||
|
if (toolAvailable) {
|
||||||
|
logger.log('info', `Tool ${npmTool} is available`);
|
||||||
|
} else {
|
||||||
|
logger.log('info', `globally installing ${npmTool} from npm`);
|
||||||
|
await bash(`npm install ${npmTool} -q -g`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.log('success', 'all global npm tools specified in npmextra.json are now available!');
|
||||||
|
}
|
||||||
|
}
|
162
ts/manager.npm/index.ts
Normal file
162
ts/manager.npm/index.ts
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
import * as plugins from './mod.plugins';
|
||||||
|
|
||||||
|
import { logger } from '../npmci.logging';
|
||||||
|
import { bash, bashNoError, nvmAvailable } from '../npmci.bash';
|
||||||
|
import { Npmci } from '../npmci.classes.npmci';
|
||||||
|
|
||||||
|
export class NpmciNpmManager {
|
||||||
|
public npmciRef: Npmci;
|
||||||
|
|
||||||
|
constructor(npmciRefArg) {
|
||||||
|
this.npmciRef = npmciRefArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle cli input
|
||||||
|
* @param argvArg
|
||||||
|
*/
|
||||||
|
public async handleCli(argvArg) {
|
||||||
|
if (argvArg._.length >= 2) {
|
||||||
|
const action: string = argvArg._[1];
|
||||||
|
switch (action) {
|
||||||
|
case 'install':
|
||||||
|
await this.install();
|
||||||
|
break;
|
||||||
|
case 'prepare':
|
||||||
|
await this.prepare();
|
||||||
|
break;
|
||||||
|
case 'test':
|
||||||
|
await this.test();
|
||||||
|
break;
|
||||||
|
case 'publish':
|
||||||
|
await this.publish();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logger.log('error', `>>npmci npm ...<< action >>${action}<< not supported`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.log(
|
||||||
|
'info',
|
||||||
|
`>>npmci npm ...<< cli arguments invalid... Please read the documentation.`
|
||||||
|
);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* authenticates npm with token from env var
|
||||||
|
*/
|
||||||
|
public async prepare() {
|
||||||
|
const config = this.npmciRef.npmciConfig.getConfig();
|
||||||
|
let npmrcFileString: string = '';
|
||||||
|
await plugins.smartparam.forEachMinimatch(process.env, 'NPMCI_TOKEN_NPM*', npmEnvArg => {
|
||||||
|
const npmRegistryUrl = npmEnvArg.split('|')[0];
|
||||||
|
const npmToken = npmEnvArg.split('|')[1];
|
||||||
|
npmrcFileString += `//${npmRegistryUrl}/:_authToken="${plugins.smartstring.base64.decode(
|
||||||
|
npmToken
|
||||||
|
)}"\n`;
|
||||||
|
});
|
||||||
|
logger.log('info', `setting default npm registry to ${config.npmRegistryUrl}`);
|
||||||
|
npmrcFileString += `registry=https://${config.npmRegistryUrl}\n`;
|
||||||
|
|
||||||
|
// final check
|
||||||
|
if (npmrcFileString.length > 0) {
|
||||||
|
logger.log('info', 'found one or more access tokens');
|
||||||
|
} else {
|
||||||
|
logger.log('error', 'no access token found! Exiting!');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// lets save it to disk
|
||||||
|
plugins.smartfile.memory.toFsSync(npmrcFileString, '/root/.npmrc');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* publish a package to npm
|
||||||
|
*/
|
||||||
|
public async publish() {
|
||||||
|
const buildPublishCommand = async () => {
|
||||||
|
let npmAccessCliString = ``;
|
||||||
|
let npmRegistryCliString = ``;
|
||||||
|
let publishVerdaccioAsWell = false;
|
||||||
|
const config = this.npmciRef.npmciConfig.getConfig();
|
||||||
|
const availableRegistries: string[] = [];
|
||||||
|
await plugins.smartparam.forEachMinimatch(process.env, 'NPMCI_TOKEN_NPM*', npmEnvArg => {
|
||||||
|
availableRegistries.push(npmEnvArg.split('|')[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// -> configure package access level
|
||||||
|
if (config.npmAccessLevel) {
|
||||||
|
npmAccessCliString = `--access=${config.npmAccessLevel}`;
|
||||||
|
if (config.npmAccessLevel === 'public') {
|
||||||
|
publishVerdaccioAsWell = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error('You need to set a npmAccessLevel!!!');
|
||||||
|
}
|
||||||
|
// -> configure registry url
|
||||||
|
if (config.npmRegistryUrl) {
|
||||||
|
npmRegistryCliString = `--registry=https://${config.npmRegistryUrl}`;
|
||||||
|
} else {
|
||||||
|
logger.log('error', `no registry url specified. Can't publish!`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let publishCommand = `npm publish ${npmAccessCliString} ${npmRegistryCliString} `;
|
||||||
|
|
||||||
|
// publishEverywhere
|
||||||
|
if (publishVerdaccioAsWell) {
|
||||||
|
const verdaccioRegistry = availableRegistries.find(registryString =>
|
||||||
|
registryString.startsWith('verdaccio')
|
||||||
|
);
|
||||||
|
if (verdaccioRegistry) {
|
||||||
|
logger.log(
|
||||||
|
'info',
|
||||||
|
`package is public and verdaccio registry is specified. Also publishing to Verdaccio!`
|
||||||
|
);
|
||||||
|
publishCommand = `${publishCommand} && npm publish ${npmAccessCliString} --registry=https://${verdaccioRegistry}`;
|
||||||
|
} else {
|
||||||
|
logger.log(
|
||||||
|
'error',
|
||||||
|
`This package should also be published to Verdaccio, however there is no Verdaccio registry data available!`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return publishCommand;
|
||||||
|
};
|
||||||
|
|
||||||
|
// -> preparing
|
||||||
|
logger.log('info', `now preparing environment:`);
|
||||||
|
this.prepare();
|
||||||
|
await bash(`npm -v`);
|
||||||
|
|
||||||
|
// -> build it
|
||||||
|
await bash(`npm install`);
|
||||||
|
await bash(`npm run build`);
|
||||||
|
|
||||||
|
logger.log('success', `Nice!!! The build for the publication was successfull!`);
|
||||||
|
logger.log('info', `Lets clean up so we don't publish any packages that don't belong to us:`);
|
||||||
|
// -> clean up before we publish stuff
|
||||||
|
await bashNoError(`rm -r ./.npmci_cache`);
|
||||||
|
await bash(`rm -r ./node_modules`);
|
||||||
|
|
||||||
|
logger.log('success', `Cleaned up!:`);
|
||||||
|
|
||||||
|
// -> publish it
|
||||||
|
logger.log('info', `now invoking npm to publish the package!`);
|
||||||
|
await bash(await buildPublishCommand());
|
||||||
|
logger.log('success', `Package was successfully published!`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async install(): Promise<void> {
|
||||||
|
logger.log('info', 'now installing dependencies:');
|
||||||
|
await bash('npm install');
|
||||||
|
}
|
||||||
|
|
||||||
|
public async test(): Promise<void> {
|
||||||
|
logger.log('info', 'now starting tests:');
|
||||||
|
await bash('npm test');
|
||||||
|
}
|
||||||
|
}
|
@ -1,174 +0,0 @@
|
|||||||
import { logger } from '../npmci.logging';
|
|
||||||
import * as plugins from './mod.plugins';
|
|
||||||
import * as paths from '../npmci.paths';
|
|
||||||
import { bash } from '../npmci.bash';
|
|
||||||
|
|
||||||
import * as helpers from './mod.helpers';
|
|
||||||
|
|
||||||
// classes
|
|
||||||
import { Dockerfile } from './mod.classes.dockerfile';
|
|
||||||
import { DockerRegistry } from './mod.classes.dockerregistry';
|
|
||||||
import { RegistryStorage } from './mod.classes.registrystorage';
|
|
||||||
|
|
||||||
// config
|
|
||||||
import { configObject } from '../npmci.config';
|
|
||||||
|
|
||||||
// instances
|
|
||||||
const npmciRegistryStorage = new RegistryStorage();
|
|
||||||
|
|
||||||
export { Dockerfile, helpers };
|
|
||||||
|
|
||||||
export let modArgvArg; // will be set through the build command
|
|
||||||
|
|
||||||
/**
|
|
||||||
* handle cli input
|
|
||||||
* @param argvArg
|
|
||||||
*/
|
|
||||||
export const handleCli = async argvArg => {
|
|
||||||
modArgvArg = argvArg;
|
|
||||||
if (argvArg._.length >= 2) {
|
|
||||||
const action: string = argvArg._[1];
|
|
||||||
switch (action) {
|
|
||||||
case 'build':
|
|
||||||
await build();
|
|
||||||
break;
|
|
||||||
case 'login':
|
|
||||||
case 'prepare':
|
|
||||||
await login();
|
|
||||||
break;
|
|
||||||
case 'test':
|
|
||||||
await test();
|
|
||||||
break;
|
|
||||||
case 'push':
|
|
||||||
await push(argvArg);
|
|
||||||
break;
|
|
||||||
case 'pull':
|
|
||||||
await pull(argvArg);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
logger.log('error', `>>npmci docker ...<< action >>${action}<< not supported`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.log(
|
|
||||||
'info',
|
|
||||||
`>>npmci docker ...<< cli arguments invalid... Please read the documentation.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* builds a cwd of Dockerfiles by triggering a promisechain
|
|
||||||
*/
|
|
||||||
export const build = async () => {
|
|
||||||
await prepare();
|
|
||||||
logger.log('info', 'now building Dockerfiles...');
|
|
||||||
await helpers
|
|
||||||
.readDockerfiles()
|
|
||||||
.then(helpers.sortDockerfiles)
|
|
||||||
.then(helpers.mapDockerfiles)
|
|
||||||
.then(helpers.buildDockerfiles);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* login to the DockerRegistries
|
|
||||||
*/
|
|
||||||
export const login = async () => {
|
|
||||||
await prepare();
|
|
||||||
await npmciRegistryStorage.loginAll();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* logs in docker
|
|
||||||
*/
|
|
||||||
export const prepare = async () => {
|
|
||||||
// Always login to GitLab Registry
|
|
||||||
if (!process.env.CI_BUILD_TOKEN || process.env.CI_BUILD_TOKEN === '') {
|
|
||||||
logger.log('error', 'No registry token specified by gitlab!');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
npmciRegistryStorage.addRegistry(
|
|
||||||
new DockerRegistry({
|
|
||||||
registryUrl: 'registry.gitlab.com',
|
|
||||||
username: 'gitlab-ci-token',
|
|
||||||
password: process.env.CI_BUILD_TOKEN
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// handle registries
|
|
||||||
await plugins.smartparam.forEachMinimatch(process.env, 'NPMCI_LOGIN_DOCKER*', async envString => {
|
|
||||||
npmciRegistryStorage.addRegistry(DockerRegistry.fromEnvString(envString));
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pushes an image towards a registry
|
|
||||||
* @param argvArg
|
|
||||||
*/
|
|
||||||
export const push = async argvArg => {
|
|
||||||
await prepare();
|
|
||||||
let dockerRegistryUrls: string[] = [];
|
|
||||||
|
|
||||||
// lets parse the input of cli and npmextra
|
|
||||||
if (argvArg._.length >= 3 && argvArg._[2] !== 'npmextra') {
|
|
||||||
dockerRegistryUrls.push(argvArg._[2]);
|
|
||||||
} else {
|
|
||||||
if (configObject.dockerRegistries.length === 0) {
|
|
||||||
logger.log(
|
|
||||||
'warn',
|
|
||||||
`There are no docker registries listed in npmextra.json! This is strange!`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
dockerRegistryUrls = dockerRegistryUrls.concat(configObject.dockerRegistries);
|
|
||||||
}
|
|
||||||
|
|
||||||
// lets determine the suffix
|
|
||||||
let suffix = null;
|
|
||||||
if (argvArg._.length >= 4) {
|
|
||||||
suffix = argvArg._[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
// lets push to the registries
|
|
||||||
for (const dockerRegistryUrl of dockerRegistryUrls) {
|
|
||||||
const dockerfileArray = await helpers
|
|
||||||
.readDockerfiles()
|
|
||||||
.then(helpers.sortDockerfiles)
|
|
||||||
.then(helpers.mapDockerfiles);
|
|
||||||
const dockerRegistryToPushTo = npmciRegistryStorage.getRegistryByUrl(dockerRegistryUrl);
|
|
||||||
if (!dockerRegistryToPushTo) {
|
|
||||||
logger.log(
|
|
||||||
'error',
|
|
||||||
`Cannot push to registry ${dockerRegistryUrl}, because it was not found in the authenticated registry list.`
|
|
||||||
);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
for (const dockerfile of dockerfileArray) {
|
|
||||||
await dockerfile.push(dockerRegistryToPushTo, suffix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const pull = async argvArg => {
|
|
||||||
await prepare();
|
|
||||||
const registryUrlArg = argvArg._[2];
|
|
||||||
let suffix = null;
|
|
||||||
if (argvArg._.length >= 4) {
|
|
||||||
suffix = argvArg._[3];
|
|
||||||
}
|
|
||||||
const localDockerRegistry = npmciRegistryStorage.getRegistryByUrl(registryUrlArg);
|
|
||||||
const dockerfileArray = await helpers
|
|
||||||
.readDockerfiles()
|
|
||||||
.then(helpers.sortDockerfiles)
|
|
||||||
.then(helpers.mapDockerfiles);
|
|
||||||
for (const dockerfile of dockerfileArray) {
|
|
||||||
await dockerfile.pull(localDockerRegistry, suffix);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* tests docker files
|
|
||||||
*/
|
|
||||||
export const test = async () => {
|
|
||||||
await prepare();
|
|
||||||
return await helpers.readDockerfiles().then(helpers.testDockerfiles);
|
|
||||||
};
|
|
@ -1,108 +0,0 @@
|
|||||||
import { logger } from '../npmci.logging';
|
|
||||||
import * as plugins from './mod.plugins';
|
|
||||||
import * as NpmciEnv from '../npmci.env';
|
|
||||||
import { bash } from '../npmci.bash';
|
|
||||||
import * as paths from '../npmci.paths';
|
|
||||||
|
|
||||||
import { DockerRegistry } from './mod.classes.dockerregistry';
|
|
||||||
import * as helpers from './mod.helpers';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class Dockerfile represents a Dockerfile on disk in npmci
|
|
||||||
*/
|
|
||||||
export class Dockerfile {
|
|
||||||
public filePath: string;
|
|
||||||
public repo: string;
|
|
||||||
public version: string;
|
|
||||||
public cleanTag: string;
|
|
||||||
public buildTag: string;
|
|
||||||
public containerName: string;
|
|
||||||
public content: string;
|
|
||||||
public baseImage: string;
|
|
||||||
public localBaseImageDependent: boolean;
|
|
||||||
public localBaseDockerfile: Dockerfile;
|
|
||||||
constructor(options: { filePath?: string; fileContents?: string | Buffer; read?: boolean }) {
|
|
||||||
this.filePath = options.filePath;
|
|
||||||
this.repo = NpmciEnv.repo.user + '/' + NpmciEnv.repo.repo;
|
|
||||||
this.version = helpers.dockerFileVersion(plugins.path.parse(options.filePath).base);
|
|
||||||
this.cleanTag = this.repo + ':' + this.version;
|
|
||||||
this.buildTag = this.cleanTag;
|
|
||||||
|
|
||||||
this.containerName = 'dockerfile-' + this.version;
|
|
||||||
if (options.filePath && options.read) {
|
|
||||||
this.content = plugins.smartfile.fs.toStringSync(plugins.path.resolve(options.filePath));
|
|
||||||
}
|
|
||||||
this.baseImage = helpers.dockerBaseImage(this.content);
|
|
||||||
this.localBaseImageDependent = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* builds the Dockerfile
|
|
||||||
*/
|
|
||||||
public async build() {
|
|
||||||
logger.log('info', 'now building Dockerfile for ' + this.cleanTag);
|
|
||||||
const buildArgsString = await helpers.getDockerBuildArgs();
|
|
||||||
const buildCommand = `docker build -t ${this.buildTag} -f ${this.filePath} ${buildArgsString} .`;
|
|
||||||
await bash(buildCommand);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pushes the Dockerfile to a registry
|
|
||||||
*/
|
|
||||||
public async push(dockerRegistryArg: DockerRegistry, versionSuffix: string = null) {
|
|
||||||
const pushTag = helpers.getDockerTagString(
|
|
||||||
dockerRegistryArg.registryUrl,
|
|
||||||
this.repo,
|
|
||||||
this.version,
|
|
||||||
versionSuffix
|
|
||||||
);
|
|
||||||
await bash(`docker tag ${this.buildTag} ${pushTag}`);
|
|
||||||
await bash(`docker push ${pushTag}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pulls the Dockerfile from a registry
|
|
||||||
*/
|
|
||||||
public async pull(registryArg: DockerRegistry, versionSuffixArg: string = null) {
|
|
||||||
const pullTag = helpers.getDockerTagString(
|
|
||||||
registryArg.registryUrl,
|
|
||||||
this.repo,
|
|
||||||
this.version,
|
|
||||||
versionSuffixArg
|
|
||||||
);
|
|
||||||
await bash(`docker pull ${pullTag}`);
|
|
||||||
await bash(`docker tag ${pullTag} ${this.buildTag}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* tests the Dockerfile;
|
|
||||||
*/
|
|
||||||
public async test() {
|
|
||||||
const testFile: string = plugins.path.join(paths.NpmciTestDir, 'test_' + this.version + '.sh');
|
|
||||||
const testFileExists: boolean = plugins.smartfile.fs.fileExistsSync(testFile);
|
|
||||||
if (testFileExists) {
|
|
||||||
// run tests
|
|
||||||
await bash(
|
|
||||||
`docker run --name npmci_test_container --entrypoint="bash" ${this.buildTag} -c "mkdir /npmci_test"`
|
|
||||||
);
|
|
||||||
await bash(`docker cp ${testFile} npmci_test_container:/npmci_test/test.sh`);
|
|
||||||
await bash(`docker commit npmci_test_container npmci_test_image`);
|
|
||||||
await bash(`docker run --entrypoint="bash" npmci_test_image -x /npmci_test/test.sh`);
|
|
||||||
await bash(`docker rm npmci_test_container`);
|
|
||||||
await bash(`docker rmi --force npmci_test_image`);
|
|
||||||
} else {
|
|
||||||
logger.log('warn', 'skipping tests for ' + this.cleanTag + ' because no testfile was found!');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gets the id of a Dockerfile
|
|
||||||
*/
|
|
||||||
public async getId() {
|
|
||||||
const containerId = await bash(
|
|
||||||
'docker inspect --type=image --format="{{.Id}}" ' + this.buildTag
|
|
||||||
);
|
|
||||||
return containerId;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,187 +0,0 @@
|
|||||||
import { logger } from '../npmci.logging';
|
|
||||||
import * as plugins from './mod.plugins';
|
|
||||||
import * as paths from '../npmci.paths';
|
|
||||||
import * as NpmciEnv from '../npmci.env';
|
|
||||||
import * as NpmciConfig from '../npmci.config';
|
|
||||||
import { bash } from '../npmci.bash';
|
|
||||||
|
|
||||||
import { Dockerfile } from './mod.classes.dockerfile';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* creates instance of class Dockerfile for all Dockerfiles in cwd
|
|
||||||
* @returns Promise<Dockerfile[]>
|
|
||||||
*/
|
|
||||||
export let readDockerfiles = async (): Promise<Dockerfile[]> => {
|
|
||||||
const fileTree = await plugins.smartfile.fs.listFileTree(paths.cwd, 'Dockerfile*');
|
|
||||||
|
|
||||||
// create the Dockerfile array
|
|
||||||
const readDockerfilesArray: Dockerfile[] = [];
|
|
||||||
logger.log('info', `found ${fileTree.length} Dockerfiles:`);
|
|
||||||
console.log(fileTree);
|
|
||||||
for (const dockerfilePath of fileTree) {
|
|
||||||
const myDockerfile = new Dockerfile({
|
|
||||||
filePath: dockerfilePath,
|
|
||||||
read: true
|
|
||||||
});
|
|
||||||
readDockerfilesArray.push(myDockerfile);
|
|
||||||
}
|
|
||||||
|
|
||||||
return readDockerfilesArray;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* sorts Dockerfiles into a dependency chain
|
|
||||||
* @param sortableArrayArg an array of instances of class Dockerfile
|
|
||||||
* @returns Promise<Dockerfile[]>
|
|
||||||
*/
|
|
||||||
export let sortDockerfiles = (sortableArrayArg: Dockerfile[]): Promise<Dockerfile[]> => {
|
|
||||||
const done = plugins.smartpromise.defer<Dockerfile[]>();
|
|
||||||
logger.log('info', 'sorting Dockerfiles:');
|
|
||||||
const sortedArray: Dockerfile[] = [];
|
|
||||||
const cleanTagsOriginal = cleanTagsArrayFunction(sortableArrayArg, sortedArray);
|
|
||||||
let sorterFunctionCounter: number = 0;
|
|
||||||
const sorterFunction = () => {
|
|
||||||
sortableArrayArg.forEach(dockerfileArg => {
|
|
||||||
const cleanTags = cleanTagsArrayFunction(sortableArrayArg, sortedArray);
|
|
||||||
if (
|
|
||||||
cleanTags.indexOf(dockerfileArg.baseImage) === -1 &&
|
|
||||||
sortedArray.indexOf(dockerfileArg) === -1
|
|
||||||
) {
|
|
||||||
sortedArray.push(dockerfileArg);
|
|
||||||
}
|
|
||||||
if (cleanTagsOriginal.indexOf(dockerfileArg.baseImage) !== -1) {
|
|
||||||
dockerfileArg.localBaseImageDependent = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (sortableArrayArg.length === sortedArray.length) {
|
|
||||||
let counter = 1;
|
|
||||||
for (const dockerfile of sortedArray) {
|
|
||||||
logger.log('info', `tag ${counter}: -> ${dockerfile.cleanTag}`);
|
|
||||||
counter++;
|
|
||||||
}
|
|
||||||
done.resolve(sortedArray);
|
|
||||||
} else if (sorterFunctionCounter < 10) {
|
|
||||||
sorterFunctionCounter++;
|
|
||||||
sorterFunction();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
sorterFunction();
|
|
||||||
return done.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* maps local Dockerfiles dependencies to the correspoding Dockerfile class instances
|
|
||||||
*/
|
|
||||||
export let mapDockerfiles = async (sortedArray: Dockerfile[]): Promise<Dockerfile[]> => {
|
|
||||||
sortedArray.forEach(dockerfileArg => {
|
|
||||||
if (dockerfileArg.localBaseImageDependent) {
|
|
||||||
sortedArray.forEach((dockfile2: Dockerfile) => {
|
|
||||||
if (dockfile2.cleanTag === dockerfileArg.baseImage) {
|
|
||||||
dockerfileArg.localBaseDockerfile = dockfile2;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return sortedArray;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* builds the correspoding real docker image for each Dockerfile class instance
|
|
||||||
*/
|
|
||||||
export let buildDockerfiles = async (sortedArrayArg: Dockerfile[]) => {
|
|
||||||
for (const dockerfileArg of sortedArrayArg) {
|
|
||||||
await dockerfileArg.build();
|
|
||||||
}
|
|
||||||
return sortedArrayArg;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* tests all Dockerfiles in by calling class Dockerfile.test();
|
|
||||||
* @param sortedArrayArg Dockerfile[] that contains all Dockerfiles in cwd
|
|
||||||
*/
|
|
||||||
export let testDockerfiles = async (sortedArrayArg: Dockerfile[]) => {
|
|
||||||
for (const dockerfileArg of sortedArrayArg) {
|
|
||||||
await dockerfileArg.test();
|
|
||||||
}
|
|
||||||
return sortedArrayArg;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns a version for a docker file
|
|
||||||
* @execution SYNC
|
|
||||||
*/
|
|
||||||
export let dockerFileVersion = (dockerfileNameArg: string): string => {
|
|
||||||
let versionString: string;
|
|
||||||
const versionRegex = /Dockerfile_([a-zA-Z0-9\.]*)$/;
|
|
||||||
const regexResultArray = versionRegex.exec(dockerfileNameArg);
|
|
||||||
if (regexResultArray && regexResultArray.length === 2) {
|
|
||||||
versionString = regexResultArray[1];
|
|
||||||
} else {
|
|
||||||
versionString = 'latest';
|
|
||||||
}
|
|
||||||
return versionString;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the docker base image for a Dockerfile
|
|
||||||
*/
|
|
||||||
export let dockerBaseImage = (dockerfileContentArg: string) => {
|
|
||||||
const baseImageRegex = /FROM\s([a-zA-z0-9\/\-\:]*)\n?/;
|
|
||||||
const regexResultArray = baseImageRegex.exec(dockerfileContentArg);
|
|
||||||
return regexResultArray[1];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the docker tag
|
|
||||||
*/
|
|
||||||
export let getDockerTagString = (
|
|
||||||
registryArg: string,
|
|
||||||
repoArg: string,
|
|
||||||
versionArg: string,
|
|
||||||
suffixArg?: string
|
|
||||||
): string => {
|
|
||||||
// determine wether the repo should be mapped accordingly to the registry
|
|
||||||
const mappedRepo = NpmciConfig.configObject.dockerRegistryRepoMap[registryArg];
|
|
||||||
const repo = (() => {
|
|
||||||
if (mappedRepo) {
|
|
||||||
return mappedRepo;
|
|
||||||
} else {
|
|
||||||
return repoArg;
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
// determine wether the version contais a suffix
|
|
||||||
let version = versionArg;
|
|
||||||
if (suffixArg) {
|
|
||||||
version = versionArg + '_' + suffixArg;
|
|
||||||
}
|
|
||||||
|
|
||||||
const tagString = `${registryArg}/${repo}:${version}`;
|
|
||||||
return tagString;
|
|
||||||
};
|
|
||||||
|
|
||||||
export let getDockerBuildArgs = async (): Promise<string> => {
|
|
||||||
logger.log('info', 'checking for env vars to be supplied to the docker build');
|
|
||||||
let buildArgsString: string = '';
|
|
||||||
for (const key in NpmciConfig.configObject.dockerBuildargEnvMap) {
|
|
||||||
const targetValue = process.env[NpmciConfig.configObject.dockerBuildargEnvMap[key]];
|
|
||||||
buildArgsString = `${buildArgsString} --build-arg ${key}="${targetValue}"`;
|
|
||||||
}
|
|
||||||
return buildArgsString;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export let cleanTagsArrayFunction = (
|
|
||||||
dockerfileArrayArg: Dockerfile[],
|
|
||||||
trackingArrayArg: Dockerfile[]
|
|
||||||
): string[] => {
|
|
||||||
const cleanTagsArray: string[] = [];
|
|
||||||
dockerfileArrayArg.forEach(dockerfileArg => {
|
|
||||||
if (trackingArrayArg.indexOf(dockerfileArg) === -1) {
|
|
||||||
cleanTagsArray.push(dockerfileArg.cleanTag);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return cleanTagsArray;
|
|
||||||
};
|
|
@ -1,59 +0,0 @@
|
|||||||
import { logger } from '../npmci.logging';
|
|
||||||
import * as plugins from './mod.plugins';
|
|
||||||
import { bash } from '../npmci.bash';
|
|
||||||
import { repo } from '../npmci.env';
|
|
||||||
|
|
||||||
import { configObject } from '../npmci.config';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* handle cli input
|
|
||||||
* @param argvArg
|
|
||||||
*/
|
|
||||||
export let handleCli = async argvArg => {
|
|
||||||
if (argvArg._.length >= 2) {
|
|
||||||
const action: string = argvArg._[1];
|
|
||||||
switch (action) {
|
|
||||||
case 'mirror':
|
|
||||||
await mirror();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
logger.log('error', `npmci git -> action >>${action}<< not supported!`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.log('info', `npmci git -> cli arguments invalid! Please read the documentation.`);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export let mirror = async () => {
|
|
||||||
const githubToken = process.env.NPMCI_GIT_GITHUBTOKEN;
|
|
||||||
const githubUser = process.env.NPMCI_GIT_GITHUBGROUP || repo.user;
|
|
||||||
const githubRepo = process.env.NPMCI_GIT_GITHUB || repo.repo;
|
|
||||||
if (
|
|
||||||
configObject.projectInfo.npm.packageJson.private === true ||
|
|
||||||
configObject.npmAccessLevel === 'private'
|
|
||||||
) {
|
|
||||||
logger.log(
|
|
||||||
'warn',
|
|
||||||
`refusing to mirror due to private property use a private mirror location instead`
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (githubToken) {
|
|
||||||
logger.log('info', 'found github token.');
|
|
||||||
logger.log('info', 'attempting the mirror the repository to GitHub');
|
|
||||||
|
|
||||||
// plugins.smartgit.GitRepo;
|
|
||||||
|
|
||||||
// add the mirror
|
|
||||||
await bash(
|
|
||||||
`git remote add mirror https://${githubToken}@github.com/${githubUser}/${githubRepo}.git`
|
|
||||||
);
|
|
||||||
await bash(`git push mirror --all`);
|
|
||||||
logger.log('ok', 'pushed all branches to mirror!');
|
|
||||||
await bash(`git push mirror --tags`);
|
|
||||||
logger.log('ok', 'pushed all tags to mirror!');
|
|
||||||
} else {
|
|
||||||
logger.log('error', `cannot find NPMCI_GIT_GITHUBTOKEN env var!`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,74 +0,0 @@
|
|||||||
import { logger } from '../npmci.logging';
|
|
||||||
import * as plugins from '../npmci.plugins';
|
|
||||||
import * as paths from '../npmci.paths';
|
|
||||||
import * as npmciConfig from '../npmci.config';
|
|
||||||
import { bash, bashNoError, nvmAvailable } from '../npmci.bash';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* handle cli input
|
|
||||||
* @param argvArg
|
|
||||||
*/
|
|
||||||
export let handleCli = async argvArg => {
|
|
||||||
if (argvArg._.length >= 3) {
|
|
||||||
const action: string = argvArg._[1];
|
|
||||||
switch (action) {
|
|
||||||
case 'install':
|
|
||||||
await install(argvArg._[2]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
logger.log('error', `>>npmci node ...<< action >>${action}<< not supported`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.log(
|
|
||||||
'error',
|
|
||||||
`>>npmci node ...<< cli arguments invalid... Please read the documentation.`
|
|
||||||
);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Install a specific version of node
|
|
||||||
* @param versionArg
|
|
||||||
*/
|
|
||||||
export let install = async versionArg => {
|
|
||||||
logger.log('info', `now installing node version ${versionArg}`);
|
|
||||||
let version: string;
|
|
||||||
if (versionArg === 'stable') {
|
|
||||||
version = '12';
|
|
||||||
} else if (versionArg === 'lts') {
|
|
||||||
version = '10';
|
|
||||||
} else if (versionArg === 'legacy') {
|
|
||||||
version = '8';
|
|
||||||
} else {
|
|
||||||
version = versionArg;
|
|
||||||
}
|
|
||||||
if (await nvmAvailable.promise) {
|
|
||||||
await bash(`nvm install ${version} && nvm alias default ${version}`);
|
|
||||||
logger.log('success', `Node version ${version} successfully installed!`);
|
|
||||||
} else {
|
|
||||||
logger.log('warn', 'Nvm not in path so staying at installed node version!');
|
|
||||||
}
|
|
||||||
logger.log('info', 'now installing latest npm version');
|
|
||||||
await bash('npm install -g npm');
|
|
||||||
await bash('node -v');
|
|
||||||
await bash('npm -v');
|
|
||||||
await bash(`npm config set cache ${paths.NpmciCacheDir} --global `);
|
|
||||||
// lets look for further config
|
|
||||||
await npmciConfig.getConfig().then(async configArg => {
|
|
||||||
logger.log('info', 'Now checking for needed global npm tools...');
|
|
||||||
for (const npmTool of configArg.npmGlobalTools) {
|
|
||||||
logger.log('info', `Checking for global "${npmTool}"`);
|
|
||||||
const whichOutput: string = await bashNoError(`which ${npmTool}`);
|
|
||||||
const toolAvailable: boolean = !(/not\sfound/.test(whichOutput) || whichOutput === '');
|
|
||||||
if (toolAvailable) {
|
|
||||||
logger.log('info', `Tool ${npmTool} is available`);
|
|
||||||
} else {
|
|
||||||
logger.log('info', `globally installing ${npmTool} from npm`);
|
|
||||||
await bash(`npm install ${npmTool} -q -g`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
logger.log('success', 'all global npm tools specified in npmextra.json are now available!');
|
|
||||||
});
|
|
||||||
};
|
|
@ -1,150 +0,0 @@
|
|||||||
import { logger } from '../npmci.logging';
|
|
||||||
import * as plugins from './mod.plugins';
|
|
||||||
import * as configModule from '../npmci.config';
|
|
||||||
import { bash, bashNoError, nvmAvailable } from '../npmci.bash';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* handle cli input
|
|
||||||
* @param argvArg
|
|
||||||
*/
|
|
||||||
export let handleCli = async argvArg => {
|
|
||||||
if (argvArg._.length >= 2) {
|
|
||||||
const action: string = argvArg._[1];
|
|
||||||
switch (action) {
|
|
||||||
case 'install':
|
|
||||||
await install();
|
|
||||||
break;
|
|
||||||
case 'prepare':
|
|
||||||
await prepare();
|
|
||||||
break;
|
|
||||||
case 'test':
|
|
||||||
await test();
|
|
||||||
break;
|
|
||||||
case 'publish':
|
|
||||||
await publish();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
logger.log('error', `>>npmci npm ...<< action >>${action}<< not supported`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.log('info', `>>npmci npm ...<< cli arguments invalid... Please read the documentation.`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* authenticates npm with token from env var
|
|
||||||
*/
|
|
||||||
const prepare = async () => {
|
|
||||||
const config = await configModule.getConfig();
|
|
||||||
let npmrcFileString: string = '';
|
|
||||||
await plugins.smartparam.forEachMinimatch(process.env, 'NPMCI_TOKEN_NPM*', npmEnvArg => {
|
|
||||||
const npmRegistryUrl = npmEnvArg.split('|')[0];
|
|
||||||
const npmToken = npmEnvArg.split('|')[1];
|
|
||||||
npmrcFileString += `//${npmRegistryUrl}/:_authToken="${plugins.smartstring.base64.decode(
|
|
||||||
npmToken
|
|
||||||
)}"\n`;
|
|
||||||
});
|
|
||||||
logger.log('info', `setting default npm registry to ${config.npmRegistryUrl}`);
|
|
||||||
npmrcFileString += `registry=https://${config.npmRegistryUrl}\n`;
|
|
||||||
|
|
||||||
// final check
|
|
||||||
if (npmrcFileString.length > 0) {
|
|
||||||
logger.log('info', 'found one or more access tokens');
|
|
||||||
} else {
|
|
||||||
logger.log('error', 'no access token found! Exiting!');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// lets save it to disk
|
|
||||||
plugins.smartfile.memory.toFsSync(npmrcFileString, '/root/.npmrc');
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* publish a package to npm
|
|
||||||
*/
|
|
||||||
const publish = async () => {
|
|
||||||
const buildPublishCommand = async () => {
|
|
||||||
let npmAccessCliString = ``;
|
|
||||||
let npmRegistryCliString = ``;
|
|
||||||
let publishVerdaccioAsWell = false;
|
|
||||||
const config = await configModule.getConfig();
|
|
||||||
const availableRegistries: string[] = [];
|
|
||||||
await plugins.smartparam.forEachMinimatch(process.env, 'NPMCI_TOKEN_NPM*', npmEnvArg => {
|
|
||||||
availableRegistries.push(npmEnvArg.split('|')[0]);
|
|
||||||
});
|
|
||||||
|
|
||||||
// -> configure package access level
|
|
||||||
if (config.npmAccessLevel) {
|
|
||||||
npmAccessCliString = `--access=${config.npmAccessLevel}`;
|
|
||||||
if (config.npmAccessLevel === 'public') {
|
|
||||||
publishVerdaccioAsWell = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new Error('You need to set a npmAccessLevel!!!');
|
|
||||||
}
|
|
||||||
// -> configure registry url
|
|
||||||
if (config.npmRegistryUrl) {
|
|
||||||
npmRegistryCliString = `--registry=https://${config.npmRegistryUrl}`;
|
|
||||||
} else {
|
|
||||||
logger.log('error', `no registry url specified. Can't publish!`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
let publishCommand = `npm publish ${npmAccessCliString} ${npmRegistryCliString} `;
|
|
||||||
|
|
||||||
// publishEverywhere
|
|
||||||
if (publishVerdaccioAsWell) {
|
|
||||||
const verdaccioRegistry = availableRegistries.find(registryString =>
|
|
||||||
registryString.startsWith('verdaccio')
|
|
||||||
);
|
|
||||||
if (verdaccioRegistry) {
|
|
||||||
logger.log(
|
|
||||||
'info',
|
|
||||||
`package is public and verdaccio registry is specified. Also publishing to Verdaccio!`
|
|
||||||
);
|
|
||||||
publishCommand = `${publishCommand} && npm publish ${npmAccessCliString} --registry=https://${verdaccioRegistry}`;
|
|
||||||
} else {
|
|
||||||
logger.log(
|
|
||||||
'error',
|
|
||||||
`This package should also be published to Verdaccio, however there is no Verdaccio registry data available!`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return publishCommand;
|
|
||||||
};
|
|
||||||
|
|
||||||
// -> preparing
|
|
||||||
logger.log('info', `now preparing environment:`);
|
|
||||||
prepare();
|
|
||||||
await bash(`npm -v`);
|
|
||||||
|
|
||||||
// -> build it
|
|
||||||
await bash(`npm install`);
|
|
||||||
await bash(`npm run build`);
|
|
||||||
|
|
||||||
logger.log('success', `Nice!!! The build for the publication was successfull!`);
|
|
||||||
logger.log('info', `Lets clean up so we don't publish any packages that don't belong to us:`);
|
|
||||||
// -> clean up before we publish stuff
|
|
||||||
await bashNoError(`rm -r ./.npmci_cache`);
|
|
||||||
await bash(`rm -r ./node_modules`);
|
|
||||||
|
|
||||||
logger.log('success', `Cleaned up!:`);
|
|
||||||
|
|
||||||
// -> publish it
|
|
||||||
logger.log('info', `now invoking npm to publish the package!`);
|
|
||||||
await bash(await buildPublishCommand());
|
|
||||||
logger.log('success', `Package was successfully published!`);
|
|
||||||
};
|
|
||||||
|
|
||||||
const install = async (): Promise<void> => {
|
|
||||||
logger.log('info', 'now installing dependencies:');
|
|
||||||
await bash('npm install');
|
|
||||||
};
|
|
||||||
|
|
||||||
export let test = async (): Promise<void> => {
|
|
||||||
logger.log('info', 'now starting tests:');
|
|
||||||
await bash('npm test');
|
|
||||||
};
|
|
55
ts/npmci.classes.npmci.ts
Normal file
55
ts/npmci.classes.npmci.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import * as plugins from './npmci.plugins';
|
||||||
|
|
||||||
|
import { CloudlyConnector } from './connector.cloudly/cloudlyconnector';
|
||||||
|
|
||||||
|
import { NpmciInfo } from './npmci.classes.npmciinfo';
|
||||||
|
import { NpmciCli } from './npmci.classes.npmcicli';
|
||||||
|
import { NpmciConfig } from './npmci.classes.npmciconfig';
|
||||||
|
|
||||||
|
// mods
|
||||||
|
import { NpmciDockerManager } from './manager.docker';
|
||||||
|
import { NpmciGitManager } from './manager.git';
|
||||||
|
import { NpmciNodeJsManager } from './manager.nodejs';
|
||||||
|
import { NpmciNpmManager } from './manager.npm';
|
||||||
|
import { NpmciEnv } from './npmci.classes.npmcienv';
|
||||||
|
|
||||||
|
export class Npmci {
|
||||||
|
public analytics: plugins.smartanalytics.Analytics;
|
||||||
|
public cloudlyConnector: CloudlyConnector;
|
||||||
|
|
||||||
|
public npmciEnv: NpmciEnv;
|
||||||
|
public npmciInfo: NpmciInfo;
|
||||||
|
public npmciConfig: NpmciConfig;
|
||||||
|
public npmciCli: NpmciCli;
|
||||||
|
|
||||||
|
// managers
|
||||||
|
public dockerManager: NpmciDockerManager;
|
||||||
|
public gitManager: NpmciGitManager;
|
||||||
|
public nodejsManager: NpmciNodeJsManager;
|
||||||
|
public npmManager: NpmciNpmManager;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.analytics = new plugins.smartanalytics.Analytics({
|
||||||
|
apiEndPoint: 'https://pubapi.lossless.one/analytics',
|
||||||
|
projectId: 'gitzone',
|
||||||
|
appName: 'npmci'
|
||||||
|
});
|
||||||
|
this.cloudlyConnector = new CloudlyConnector();
|
||||||
|
this.npmciEnv = new NpmciEnv(this);
|
||||||
|
this.npmciInfo = new NpmciInfo(this);
|
||||||
|
this.npmciCli = new NpmciCli(this);
|
||||||
|
this.npmciConfig = new NpmciConfig(this);
|
||||||
|
|
||||||
|
// managers
|
||||||
|
this.dockerManager = new NpmciDockerManager(this);
|
||||||
|
this.gitManager = new NpmciGitManager(this);
|
||||||
|
this.nodejsManager = new NpmciNodeJsManager(this);
|
||||||
|
this.npmManager = new NpmciNpmManager(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async start() {
|
||||||
|
await this.npmciInfo.printToConsole();
|
||||||
|
await this.npmciConfig.init();
|
||||||
|
this.npmciCli.startParse();
|
||||||
|
}
|
||||||
|
}
|
110
ts/npmci.classes.npmcicli.ts
Normal file
110
ts/npmci.classes.npmcicli.ts
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
import { logger } from './npmci.logging';
|
||||||
|
import * as plugins from './npmci.plugins';
|
||||||
|
import * as paths from './npmci.paths';
|
||||||
|
import { Npmci } from './npmci.classes.npmci';
|
||||||
|
|
||||||
|
export class NpmciCli {
|
||||||
|
public npmciRef: Npmci;
|
||||||
|
public smartcli: plugins.smartcli.Smartcli;
|
||||||
|
|
||||||
|
constructor(npmciArg: Npmci) {
|
||||||
|
this.npmciRef = npmciArg;
|
||||||
|
this.smartcli = new plugins.smartcli.Smartcli();
|
||||||
|
this.smartcli.addVersion(this.npmciRef.npmciInfo.projectInfo.version);
|
||||||
|
|
||||||
|
// clean
|
||||||
|
this.smartcli.addCommand('clean').subscribe(
|
||||||
|
async argv => {
|
||||||
|
const modClean = await import('./mod_clean/index');
|
||||||
|
await modClean.clean();
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
console.log(err);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// command
|
||||||
|
this.smartcli.addCommand('command').subscribe(
|
||||||
|
async argv => {
|
||||||
|
const modCommand = await import('./mod_command/index');
|
||||||
|
await modCommand.command();
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
console.log(err);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// command
|
||||||
|
this.smartcli.addCommand('git').subscribe(
|
||||||
|
async argvArg => {
|
||||||
|
await this.npmciRef.gitManager.handleCli(argvArg);
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
console.log(err);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// build
|
||||||
|
this.smartcli.addCommand('docker').subscribe(
|
||||||
|
async argvArg => {
|
||||||
|
await this.npmciRef.dockerManager.handleCli(argvArg);
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
console.log(err);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// node
|
||||||
|
this.smartcli.addCommand('node').subscribe(
|
||||||
|
async argvArg => {
|
||||||
|
await this.npmciRef.nodejsManager.handleCli(argvArg);
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
console.log(err);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// npm
|
||||||
|
this.smartcli.addCommand('npm').subscribe(
|
||||||
|
async argvArg => {
|
||||||
|
await this.npmciRef.npmManager.handleCli(argvArg);
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// trigger
|
||||||
|
this.smartcli.addCommand('ssh').subscribe(
|
||||||
|
async argvArg => {
|
||||||
|
const modSsh = await import('./mod_ssh/index');
|
||||||
|
await modSsh.handleCli(argvArg);
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
console.log(err);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// trigger
|
||||||
|
this.smartcli.addCommand('trigger').subscribe(
|
||||||
|
async argv => {
|
||||||
|
const modTrigger = await import('./mod_trigger/index');
|
||||||
|
await modTrigger.trigger();
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
console.log(err);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public startParse = () => {
|
||||||
|
this.smartcli.startParse();
|
||||||
|
}
|
||||||
|
}
|
73
ts/npmci.classes.npmciconfig.ts
Normal file
73
ts/npmci.classes.npmciconfig.ts
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import * as plugins from './npmci.plugins';
|
||||||
|
import * as paths from './npmci.paths';
|
||||||
|
|
||||||
|
import { logger } from './npmci.logging';
|
||||||
|
import { Npmci } from './npmci.classes.npmci';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the main config interface for npmci
|
||||||
|
*/
|
||||||
|
export interface INpmciOptions {
|
||||||
|
projectInfo: plugins.projectinfo.ProjectInfo;
|
||||||
|
|
||||||
|
// npm
|
||||||
|
npmGlobalTools: string[];
|
||||||
|
npmAccessLevel?: 'private' | 'public';
|
||||||
|
npmRegistryUrl: string;
|
||||||
|
|
||||||
|
// docker
|
||||||
|
dockerRegistries: string[];
|
||||||
|
dockerRegistryRepoMap: { [key: string]: string };
|
||||||
|
dockerBuildargEnvMap: { [key: string]: string };
|
||||||
|
|
||||||
|
// urls
|
||||||
|
urlCloudly: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a config class for Npmci
|
||||||
|
*/
|
||||||
|
export class NpmciConfig {
|
||||||
|
public npmciRef: Npmci;
|
||||||
|
|
||||||
|
public npmciNpmextra: plugins.npmextra.Npmextra;
|
||||||
|
public kvStorage: plugins.npmextra.KeyValueStore;
|
||||||
|
public npmciQenv: plugins.qenv.Qenv;
|
||||||
|
|
||||||
|
private configObject: INpmciOptions;
|
||||||
|
|
||||||
|
constructor(npmciRefArg: Npmci) {
|
||||||
|
this.npmciRef = npmciRefArg;
|
||||||
|
|
||||||
|
this.npmciNpmextra = new plugins.npmextra.Npmextra(paths.cwd);
|
||||||
|
this.kvStorage = new plugins.npmextra.KeyValueStore(
|
||||||
|
'custom',
|
||||||
|
`${this.npmciRef.npmciEnv.repo.user}_${this.npmciRef.npmciEnv.repo.repo}`
|
||||||
|
);
|
||||||
|
this.npmciQenv = new plugins.qenv.Qenv(
|
||||||
|
paths.NpmciProjectDir,
|
||||||
|
paths.NpmciProjectNogitDir,
|
||||||
|
false,
|
||||||
|
logger
|
||||||
|
);
|
||||||
|
|
||||||
|
this.configObject = {
|
||||||
|
projectInfo: new plugins.projectinfo.ProjectInfo(paths.cwd),
|
||||||
|
npmGlobalTools: [],
|
||||||
|
dockerRegistries: [],
|
||||||
|
dockerRegistryRepoMap: {},
|
||||||
|
npmAccessLevel: 'private',
|
||||||
|
npmRegistryUrl: 'registry.npmjs.org',
|
||||||
|
dockerBuildargEnvMap: {},
|
||||||
|
urlCloudly: this.npmciQenv.getEnvVarOnDemand('NPMCI_URL_CLOUDLY')
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async init() {
|
||||||
|
this.configObject = this.npmciNpmextra.dataFor<INpmciOptions>('npmci', this.configObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getConfig(): INpmciOptions {
|
||||||
|
return this.configObject;
|
||||||
|
}
|
||||||
|
}
|
18
ts/npmci.classes.npmcienv.ts
Normal file
18
ts/npmci.classes.npmcienv.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import * as plugins from './npmci.plugins';
|
||||||
|
import { Npmci } from './npmci.classes.npmci';
|
||||||
|
|
||||||
|
export class NpmciEnv {
|
||||||
|
public npmciRef: Npmci;
|
||||||
|
|
||||||
|
public repoString: string;
|
||||||
|
public repo: plugins.smartstring.GitRepo;
|
||||||
|
|
||||||
|
constructor(npmciRefArg: Npmci) {
|
||||||
|
this.npmciRef = npmciRefArg;
|
||||||
|
this.repoString = process.env.CI_REPOSITORY_URL;
|
||||||
|
if (!this.repoString) {
|
||||||
|
this.repoString = 'https://undefined:undefined@github.com/undefined/undefined.git';
|
||||||
|
}
|
||||||
|
this.repo = new plugins.smartstring.GitRepo(this.repoString);
|
||||||
|
}
|
||||||
|
}
|
18
ts/npmci.classes.npmciinfo.ts
Normal file
18
ts/npmci.classes.npmciinfo.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import * as plugins from './npmci.plugins';
|
||||||
|
import * as paths from './npmci.paths';
|
||||||
|
import { logger } from "./npmci.logging";
|
||||||
|
import { Npmci } from './npmci.classes.npmci';
|
||||||
|
|
||||||
|
export class NpmciInfo {
|
||||||
|
|
||||||
|
public npmciRef: Npmci;
|
||||||
|
public projectInfo = new plugins.projectinfo.ProjectinfoNpm(paths.NpmciPackageRoot);
|
||||||
|
|
||||||
|
constructor(npmciArg: Npmci) {
|
||||||
|
this.npmciRef = npmciArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public printToConsole () {
|
||||||
|
logger.log('info', `npmci version: ${this.projectInfo.version}`);
|
||||||
|
}
|
||||||
|
}
|
111
ts/npmci.cli.ts
111
ts/npmci.cli.ts
@ -1,111 +0,0 @@
|
|||||||
import { logger } from './npmci.logging';
|
|
||||||
import * as plugins from './npmci.plugins';
|
|
||||||
import * as paths from './npmci.paths';
|
|
||||||
import * as npmciMonitor from './npmci.monitor';
|
|
||||||
npmciMonitor.run();
|
|
||||||
|
|
||||||
// Get Info about npmci itself
|
|
||||||
const npmciInfo = new plugins.projectinfo.ProjectinfoNpm(paths.NpmciPackageRoot);
|
|
||||||
logger.log('info', 'npmci version: ' + npmciInfo.version);
|
|
||||||
|
|
||||||
import * as NpmciEnv from './npmci.env';
|
|
||||||
|
|
||||||
const npmciSmartcli = new plugins.smartcli.Smartcli();
|
|
||||||
npmciSmartcli.addVersion(npmciInfo.version);
|
|
||||||
|
|
||||||
// clean
|
|
||||||
npmciSmartcli.addCommand('clean').subscribe(
|
|
||||||
async argv => {
|
|
||||||
const modClean = await import('./mod_clean/index');
|
|
||||||
await modClean.clean();
|
|
||||||
},
|
|
||||||
err => {
|
|
||||||
console.log(err);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// command
|
|
||||||
npmciSmartcli.addCommand('command').subscribe(
|
|
||||||
async argv => {
|
|
||||||
const modCommand = await import('./mod_command/index');
|
|
||||||
await modCommand.command();
|
|
||||||
},
|
|
||||||
err => {
|
|
||||||
console.log(err);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// command
|
|
||||||
npmciSmartcli.addCommand('git').subscribe(
|
|
||||||
async argvArg => {
|
|
||||||
const modGit = await import('./mod_git/index');
|
|
||||||
await modGit.handleCli(argvArg);
|
|
||||||
},
|
|
||||||
err => {
|
|
||||||
console.log(err);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// build
|
|
||||||
npmciSmartcli.addCommand('docker').subscribe(
|
|
||||||
async argvArg => {
|
|
||||||
const modDocker = await import('./mod_docker/index');
|
|
||||||
await modDocker.handleCli(argvArg);
|
|
||||||
},
|
|
||||||
err => {
|
|
||||||
console.log(err);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// node
|
|
||||||
npmciSmartcli.addCommand('node').subscribe(
|
|
||||||
async argvArg => {
|
|
||||||
const modNode = await import('./mod_node/index');
|
|
||||||
await modNode.handleCli(argvArg);
|
|
||||||
},
|
|
||||||
err => {
|
|
||||||
console.log(err);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// npm
|
|
||||||
npmciSmartcli.addCommand('npm').subscribe(
|
|
||||||
async argvArg => {
|
|
||||||
const modNpm = await import('./mod_npm/index');
|
|
||||||
await modNpm.handleCli(argvArg);
|
|
||||||
},
|
|
||||||
err => {
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// trigger
|
|
||||||
npmciSmartcli.addCommand('ssh').subscribe(
|
|
||||||
async argvArg => {
|
|
||||||
const modSsh = await import('./mod_ssh/index');
|
|
||||||
await modSsh.handleCli(argvArg);
|
|
||||||
},
|
|
||||||
err => {
|
|
||||||
console.log(err);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// trigger
|
|
||||||
npmciSmartcli.addCommand('trigger').subscribe(
|
|
||||||
async argv => {
|
|
||||||
const modTrigger = await import('./mod_trigger/index');
|
|
||||||
await modTrigger.trigger();
|
|
||||||
},
|
|
||||||
err => {
|
|
||||||
console.log(err);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
npmciSmartcli.startParse();
|
|
@ -1,46 +0,0 @@
|
|||||||
import * as plugins from './npmci.plugins';
|
|
||||||
import * as paths from './npmci.paths';
|
|
||||||
|
|
||||||
import { repo } from './npmci.env';
|
|
||||||
|
|
||||||
import { KeyValueStore } from '@pushrocks/npmextra';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* the main config interface for npmci
|
|
||||||
*/
|
|
||||||
export interface INpmciOptions {
|
|
||||||
projectInfo: plugins.projectinfo.ProjectInfo;
|
|
||||||
|
|
||||||
// npm
|
|
||||||
npmGlobalTools: string[];
|
|
||||||
npmAccessLevel?: 'private' | 'public';
|
|
||||||
npmRegistryUrl: string;
|
|
||||||
|
|
||||||
// docker
|
|
||||||
dockerRegistries: string[];
|
|
||||||
dockerRegistryRepoMap: { [key: string]: string };
|
|
||||||
dockerBuildargEnvMap: { [key: string]: string };
|
|
||||||
}
|
|
||||||
|
|
||||||
// instantiate a kvStorage for the current directory
|
|
||||||
export let kvStorage = new KeyValueStore('custom', `${repo.user}_${repo.repo}`);
|
|
||||||
|
|
||||||
// handle config retrival
|
|
||||||
const npmciNpmextra = new plugins.npmextra.Npmextra(paths.cwd);
|
|
||||||
const defaultConfig: INpmciOptions = {
|
|
||||||
projectInfo: new plugins.projectinfo.ProjectInfo(paths.cwd),
|
|
||||||
npmGlobalTools: [],
|
|
||||||
dockerRegistries: [],
|
|
||||||
dockerRegistryRepoMap: {},
|
|
||||||
npmAccessLevel: 'private',
|
|
||||||
npmRegistryUrl: 'registry.npmjs.org',
|
|
||||||
dockerBuildargEnvMap: {}
|
|
||||||
};
|
|
||||||
export let configObject = npmciNpmextra.dataFor<INpmciOptions>('npmci', defaultConfig);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gets the npmci portion of the npmextra.json file
|
|
||||||
*/
|
|
||||||
export let getConfig = async (): Promise<INpmciOptions> => {
|
|
||||||
return configObject;
|
|
||||||
};
|
|
@ -1,13 +0,0 @@
|
|||||||
import * as plugins from './npmci.plugins';
|
|
||||||
import * as paths from './npmci.paths';
|
|
||||||
import { GitRepo } from '@pushrocks/smartstring';
|
|
||||||
import { Dockerfile } from './mod_docker/index';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* a info instance about the git respoitory at cwd :)
|
|
||||||
*/
|
|
||||||
let repoString: string = process.env.CI_REPOSITORY_URL;
|
|
||||||
if (!repoString) {
|
|
||||||
repoString = 'https://undefined:undefined@github.com/undefined/undefined.git';
|
|
||||||
}
|
|
||||||
export let repo = new GitRepo(repoString);
|
|
@ -1,23 +0,0 @@
|
|||||||
import { logger } from './npmci.logging';
|
|
||||||
import * as plugins from './npmci.plugins';
|
|
||||||
import * as env from './npmci.env';
|
|
||||||
|
|
||||||
import { Analytics } from '@pushrocks/smartanalytics';
|
|
||||||
|
|
||||||
export let npmciAnalytics = new Analytics({
|
|
||||||
apiEndPoint: 'https://pubapi.lossless.one/analytics',
|
|
||||||
projectId: 'gitzone',
|
|
||||||
appName: 'npmci'
|
|
||||||
});
|
|
||||||
|
|
||||||
export let run = async () => {
|
|
||||||
npmciAnalytics
|
|
||||||
.recordEvent('npmToolExecution', {
|
|
||||||
host: env.repo.host,
|
|
||||||
user: env.repo.user,
|
|
||||||
repo: env.repo.repo
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
logger.log('warn', 'Lossless Analytics API not available...');
|
|
||||||
});
|
|
||||||
};
|
|
@ -1,9 +1,13 @@
|
|||||||
import * as plugins from './npmci.plugins';
|
import * as plugins from './npmci.plugins';
|
||||||
|
|
||||||
export let cwd = process.cwd();
|
export const cwd = process.cwd();
|
||||||
|
|
||||||
export let NpmciPackageRoot = plugins.path.join(__dirname, '../');
|
// package paths
|
||||||
export let NpmciPackageConfig = plugins.path.join(NpmciPackageRoot, './config.json');
|
export const NpmciPackageRoot = plugins.path.join(__dirname, '../');
|
||||||
export let NpmciProjectDir = cwd;
|
export const NpmciPackageConfig = plugins.path.join(NpmciPackageRoot, './config.json');
|
||||||
export let NpmciTestDir = plugins.path.join(cwd, './test');
|
|
||||||
export let NpmciCacheDir = plugins.path.join(cwd, './.npmci_cache');
|
// project paths
|
||||||
|
export const NpmciProjectDir = cwd;
|
||||||
|
export const NpmciProjectNogitDir = plugins.path.join(NpmciProjectDir, './.nogit');
|
||||||
|
export const NpmciTestDir = plugins.path.join(cwd, './test');
|
||||||
|
export const NpmciCacheDir = plugins.path.join(cwd, './.npmci_cache');
|
||||||
|
@ -11,8 +11,10 @@ export {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// @pushrocks
|
// @pushrocks
|
||||||
import * as projectinfo from '@pushrocks/projectinfo';
|
|
||||||
import * as npmextra from '@pushrocks/npmextra';
|
import * as npmextra from '@pushrocks/npmextra';
|
||||||
|
import * as projectinfo from '@pushrocks/projectinfo';
|
||||||
|
import * as qenv from '@pushrocks/qenv';
|
||||||
|
import * as smartanalytics from '@pushrocks/smartanalytics';
|
||||||
import * as smartdelay from '@pushrocks/smartdelay';
|
import * as smartdelay from '@pushrocks/smartdelay';
|
||||||
import * as smartfile from '@pushrocks/smartfile';
|
import * as smartfile from '@pushrocks/smartfile';
|
||||||
import * as smartcli from '@pushrocks/smartcli';
|
import * as smartcli from '@pushrocks/smartcli';
|
||||||
@ -27,8 +29,10 @@ import * as smartssh from '@pushrocks/smartssh';
|
|||||||
import * as smartstring from '@pushrocks/smartstring';
|
import * as smartstring from '@pushrocks/smartstring';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
projectinfo,
|
|
||||||
npmextra,
|
npmextra,
|
||||||
|
projectinfo,
|
||||||
|
qenv,
|
||||||
|
smartanalytics,
|
||||||
smartdelay,
|
smartdelay,
|
||||||
smartfile,
|
smartfile,
|
||||||
smartcli,
|
smartcli,
|
||||||
|
Loading…
Reference in New Issue
Block a user