Compare commits
	
		
			37 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| bbb5718184 | |||
| 0d8b54637c | |||
| e51b2e28b9 | |||
| f767140cc8 | |||
| 0d4d69f072 | |||
| a3e628c43f | |||
| a58fa135c1 | |||
| 93c7af6c91 | |||
| ad0e12bf7b | |||
| 498dd6eff6 | |||
| b3aa964739 | |||
| 03eb9d2657 | |||
| 373a838a6a | |||
| 960e3f4675 | |||
| 09bf676b58 | |||
| 76ba8e2ab9 | |||
| aaaaca2d19 | |||
| 71b27eda17 | |||
| 2d00882fd7 | |||
| ba5e69041f | |||
| d2871d601a | |||
| 9c66d88dc0 | |||
| fb4c84e1de | |||
| 57aca36f11 | |||
| 905f594af1 | |||
| b788b7f96b | |||
| 319a2dc41a | |||
| e01a998f0e | |||
| e40606d97b | |||
| 449c7b2c04 | |||
| 006782b57f | |||
| d643da29b0 | |||
| 635f92d2bc | |||
| 9a2cb56094 | |||
| 5886283002 | |||
| f886194c9c | |||
| e4efec89d9 | 
| @@ -13,31 +13,24 @@ stages: | ||||
|   - metadata | ||||
|  | ||||
| before_script: | ||||
|   - npm install -g @shipzone/npmci | ||||
|   - pnpm install -g pnpm | ||||
|   - pnpm install -g @shipzone/npmci | ||||
|   - npmci npm prepare | ||||
|  | ||||
| # ==================== | ||||
| # security stage | ||||
| # ==================== | ||||
| mirror: | ||||
|   stage: security | ||||
|   script: | ||||
|     - npmci git mirror | ||||
|   only: | ||||
|     - tags | ||||
|   tags: | ||||
|     - lossless | ||||
|     - docker | ||||
|     - notpriv | ||||
|  | ||||
| # ==================== | ||||
| # security stage | ||||
| # ==================== | ||||
| auditProductionDependencies: | ||||
|   image: registry.gitlab.com/hosttoday/ht-docker-node:npmci | ||||
|   stage: security | ||||
|   script: | ||||
|     - npmci npm prepare | ||||
|     - npmci command npm install --production --ignore-scripts | ||||
|     - npmci command npm config set registry https://registry.npmjs.org | ||||
|     - npmci command npm audit --audit-level=high --only=prod --production | ||||
|      - npmci command npm config set registry https://registry.npmjs.org | ||||
|      - npmci command pnpm audit --audit-level=high --prod | ||||
|   tags: | ||||
|     - lossless | ||||
|     - docker | ||||
|   allow_failure: true | ||||
|  | ||||
| @@ -45,11 +38,10 @@ auditDevDependencies: | ||||
|   image: registry.gitlab.com/hosttoday/ht-docker-node:npmci | ||||
|   stage: security | ||||
|   script: | ||||
|     - npmci npm prepare | ||||
|     - npmci command npm install --ignore-scripts | ||||
|     - npmci command npm config set registry https://registry.npmjs.org | ||||
|     - npmci command npm audit --audit-level=high --only=dev | ||||
|     - npmci command pnpm audit --audit-level=high --dev | ||||
|   tags: | ||||
|     - lossless | ||||
|     - docker | ||||
|   allow_failure: true | ||||
|  | ||||
| @@ -60,7 +52,6 @@ auditDevDependencies: | ||||
| testStable: | ||||
|   stage: test | ||||
|   script: | ||||
|     - npmci npm prepare | ||||
|     - npmci node install stable | ||||
|     - npmci npm install | ||||
|     - npmci npm test | ||||
| @@ -71,10 +62,9 @@ testStable: | ||||
| testBuild: | ||||
|   stage: test | ||||
|   script: | ||||
|     - npmci npm prepare | ||||
|     - npmci node install stable | ||||
|     - npmci npm install | ||||
|     - npmci command npm run build | ||||
|     - npmci npm build | ||||
|   coverage: /\d+.?\d+?\%\s*coverage/ | ||||
|   tags: | ||||
|     - docker | ||||
| @@ -100,10 +90,9 @@ codequality: | ||||
|   only: | ||||
|     - tags | ||||
|   script: | ||||
|     - npmci command npm install -g tslint typescript | ||||
|     - npmci command npm install -g typescript | ||||
|     - npmci npm prepare | ||||
|     - npmci npm install | ||||
|     - npmci command "tslint -c tslint.json ./ts/**/*.ts" | ||||
|   tags: | ||||
|     - lossless | ||||
|     - docker | ||||
| @@ -123,11 +112,9 @@ trigger: | ||||
| pages: | ||||
|   stage: metadata | ||||
|   script: | ||||
|     - npmci node install lts | ||||
|     - npmci command npm install -g @gitzone/tsdoc | ||||
|     - npmci npm prepare | ||||
|     - npmci node install stable | ||||
|     - npmci npm install | ||||
|     - npmci command tsdoc | ||||
|     - npmci command npm run buildDocs | ||||
|   tags: | ||||
|     - lossless | ||||
|     - docker | ||||
|   | ||||
							
								
								
									
										4
									
								
								cli.child.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								cli.child.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| #!/usr/bin/env node | ||||
| process.env.CLI_CALL = 'true'; | ||||
| import * as cliTool from './ts/index.js'; | ||||
| cliTool.runCli(); | ||||
							
								
								
									
										2
									
								
								cli.js
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								cli.js
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| #!/usr/bin/env node | ||||
| process.env.CLI_CALL = 'true'; | ||||
| const cliTool = require('./dist_ts/index'); | ||||
| const cliTool = await import('./dist_ts/index.js'); | ||||
| cliTool.runCli(); | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| #!/usr/bin/env node | ||||
| process.env.CLI_CALL = 'true'; | ||||
| require('@gitzone/tsrun'); | ||||
| const cliTool = require('./ts/index'); | ||||
| cliTool.runCli(); | ||||
|  | ||||
| import * as tsrun from '@gitzone/tsrun'; | ||||
| tsrun.runPath('./cli.child.js', import.meta.url); | ||||
|   | ||||
| @@ -14,7 +14,7 @@ | ||||
|       "githost": "gitlab.com", | ||||
|       "gitscope": "shipzone", | ||||
|       "gitrepo": "npmci", | ||||
|       "shortDescription": "node and docker in gitlab ci on steroids", | ||||
|       "description": "node and docker in gitlab ci on steroids", | ||||
|       "npmPackagename": "@shipzone/npmci", | ||||
|       "license": "MIT" | ||||
|     } | ||||
|   | ||||
							
								
								
									
										27557
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										27557
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										52
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,17 +1,19 @@ | ||||
| { | ||||
|   "name": "@shipzone/npmci", | ||||
|   "version": "3.1.80", | ||||
|   "version": "4.1.3", | ||||
|   "private": false, | ||||
|   "description": "node and docker in gitlab ci on steroids", | ||||
|   "main": "dist_ts/index.js", | ||||
|   "typings": "dist_ts/index.d.ts", | ||||
|   "type": "module", | ||||
|   "bin": { | ||||
|     "npmci": "cli.js" | ||||
|   }, | ||||
|   "scripts": { | ||||
|     "test": "tstest test/", | ||||
|     "build": "tsbuild && (npm run testVersion)", | ||||
|     "testVersion": "(cd test/assets/ && node ../../cli.js -v)" | ||||
|     "build": "tsbuild --allowimplicitany && (npm run testVersion)", | ||||
|     "testVersion": "(cd test/assets/ && node ../../cli.js -v)", | ||||
|     "buildDocs": "tsdoc" | ||||
|   }, | ||||
|   "repository": { | ||||
|     "type": "git", | ||||
| @@ -24,36 +26,36 @@ | ||||
|   }, | ||||
|   "homepage": "https://gitlab.com/gitzone/npmci#README", | ||||
|   "devDependencies": { | ||||
|     "@gitzone/tsbuild": "^2.1.28", | ||||
|     "@gitzone/tsrun": "^1.2.18", | ||||
|     "@gitzone/tstest": "^1.0.59", | ||||
|     "@pushrocks/tapbundle": "^3.2.14", | ||||
|     "@types/node": "^16.11.6", | ||||
|     "tslint": "^6.1.3", | ||||
|     "tslint-config-prettier": "^1.18.0" | ||||
|     "@gitzone/tsbuild": "^2.1.65", | ||||
|     "@gitzone/tsrun": "^1.2.37", | ||||
|     "@gitzone/tstest": "^1.0.73", | ||||
|     "@pushrocks/tapbundle": "^5.0.4", | ||||
|     "@types/node": "^18.8.3" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@apiglobal/typedrequest": "^1.0.58", | ||||
|     "@pushrocks/lik": "^5.0.0", | ||||
|     "@apiglobal/typedrequest": "^2.0.10", | ||||
|     "@pushrocks/lik": "^6.0.0", | ||||
|     "@pushrocks/npmextra": "^3.0.9", | ||||
|     "@pushrocks/projectinfo": "^4.0.5", | ||||
|     "@pushrocks/qenv": "^4.0.10", | ||||
|     "@pushrocks/projectinfo": "^5.0.1", | ||||
|     "@pushrocks/qenv": "^5.0.2", | ||||
|     "@pushrocks/smartanalytics": "^2.0.15", | ||||
|     "@pushrocks/smartcli": "^3.0.14", | ||||
|     "@pushrocks/smartcli": "^4.0.6", | ||||
|     "@pushrocks/smartdelay": "^2.0.13", | ||||
|     "@pushrocks/smartfile": "^8.0.10", | ||||
|     "@pushrocks/smartgit": "^2.0.1", | ||||
|     "@pushrocks/smartlog": "^2.0.44", | ||||
|     "@pushrocks/smartenv": "^5.0.3", | ||||
|     "@pushrocks/smartfile": "^10.0.5", | ||||
|     "@pushrocks/smartgit": "^3.0.0", | ||||
|     "@pushrocks/smartlog": "^3.0.1", | ||||
|     "@pushrocks/smartlog-destination-local": "^8.0.8", | ||||
|     "@pushrocks/smartparam": "^1.1.6", | ||||
|     "@pushrocks/smartpromise": "^3.1.6", | ||||
|     "@pushrocks/smartrequest": "^1.1.52", | ||||
|     "@pushrocks/smartshell": "^2.0.28", | ||||
|     "@pushrocks/smartsocket": "^1.2.8", | ||||
|     "@pushrocks/smartssh": "^1.2.3", | ||||
|     "@pushrocks/smartstring": "^3.0.24", | ||||
|     "@pushrocks/smartpath": "^5.0.5", | ||||
|     "@pushrocks/smartpromise": "^3.1.7", | ||||
|     "@pushrocks/smartrequest": "^2.0.11", | ||||
|     "@pushrocks/smartshell": "^2.0.30", | ||||
|     "@pushrocks/smartsocket": "^2.0.7", | ||||
|     "@pushrocks/smartssh": "^2.0.0", | ||||
|     "@pushrocks/smartstring": "^4.0.5", | ||||
|     "@servezone/interfaces": "^1.0.3", | ||||
|     "@tsclass/tsclass": "^3.0.36", | ||||
|     "@tsclass/tsclass": "^4.0.21", | ||||
|     "@types/through2": "^2.0.36", | ||||
|     "through2": "^4.0.2" | ||||
|   }, | ||||
|   | ||||
							
								
								
									
										4360
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										4360
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -21,7 +21,6 @@ Code Style | [](htt | ||||
| PackagePhobia (total standalone install weight) | [](https://lossless.cloud) | ||||
| PackagePhobia (package size on registry) | [](https://lossless.cloud) | ||||
| BundlePhobia (total size when bundled) | [](https://lossless.cloud) | ||||
| Platform support | [](https://lossless.cloud) [](https://lossless.cloud) | ||||
|  | ||||
| ## Usage | ||||
|  | ||||
| @@ -106,7 +105,6 @@ We are always happy for code contributions. If you are not the code contributing | ||||
|  | ||||
| For further information read the linked docs at the top of this readme. | ||||
|  | ||||
| > MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh) | ||||
| ## Legal | ||||
| > MIT licensed | **©** [Task Venture Capital GmbH](https://task.vc) | ||||
| | By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy) | ||||
|  | ||||
| [](https://maintainedby.lossless.com) | ||||
|   | ||||
							
								
								
									
										26
									
								
								test/test.cloudly.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								test/test.cloudly.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; | ||||
| import { tap, expect } from '@pushrocks/tapbundle'; | ||||
|  | ||||
| import * as cloudlyConnectorMod from '../ts/connector.cloudly/cloudlyconnector.js'; | ||||
|  | ||||
| tap.test('should be able to announce a container to cloudly', async () => { | ||||
|   const cloudlyConnector = new cloudlyConnectorMod.CloudlyConnector(null); | ||||
|   await cloudlyConnector.announceDockerContainer( | ||||
|     { | ||||
|       registryUrl: 'registry.losssless.com', | ||||
|       tag: 'testcontainer', | ||||
|       version: 'x.x.x', | ||||
|       labels: [], | ||||
|     }, | ||||
|     'cloudly.lossless.one' | ||||
|   ); | ||||
| }); | ||||
|  | ||||
| tap.test('should close the program despite socket timeout', async (toolsArg) => { | ||||
|   // TODO: remove when unreffed timeouts in webrequest have been solved. | ||||
|   toolsArg.delayFor(0).then(() => { | ||||
|     process.exit(); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| tap.start(); | ||||
							
								
								
									
										18
									
								
								test/test.ts
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								test/test.ts
									
									
									
									
									
								
							| @@ -1,7 +1,9 @@ | ||||
| import { tap, expect } from '@pushrocks/tapbundle'; | ||||
| import * as path from 'path'; | ||||
| import * as smartpath from '@pushrocks/smartpath'; | ||||
|  | ||||
| process.env.NPMTS_TEST = 'true'; | ||||
| process.env.NPMCI_URL_CLOUDLY = 'localhost'; | ||||
|  | ||||
| // set up environment | ||||
| process.env.CI_REPOSITORY_URL = 'https://yyyyyy:xxxxxxxx@gitlab.com/mygroup/myrepo.git'; | ||||
| @@ -14,10 +16,14 @@ process.env.NPMCI_LOGIN_DOCKER = 'docker.io|someuser|somepass'; | ||||
| process.env.NPMCI_SSHKEY_1 = 'hostString|somePrivKey|##'; | ||||
|  | ||||
| process.cwd = () => { | ||||
|   return path.join(__dirname, 'assets/'); | ||||
|   return path.join(smartpath.get.dirnameFromImportMetaUrl(import.meta.url), 'assets/'); | ||||
| }; | ||||
|  | ||||
| import * as npmci from '../ts'; | ||||
| let npmci: typeof import('../ts/index.js'); | ||||
|  | ||||
| tap.preTask('should import npmci', async () => { | ||||
|   npmci = await import('../ts/index.js'); | ||||
| }); | ||||
|  | ||||
| // ====== | ||||
| // Docker | ||||
| @@ -37,8 +43,8 @@ tap.test('should return valid Dockerfiles', async () => { | ||||
|     filePath: './Dockerfile_sometag1', | ||||
|     read: true, | ||||
|   }); | ||||
|   expect(dockerfile1.version).to.equal('latest'); | ||||
|   return expect(dockerfile2.version).to.equal('sometag1'); | ||||
|   expect(dockerfile1.version).toEqual('latest'); | ||||
|   return expect(dockerfile2.version).toEqual('sometag1'); | ||||
| }); | ||||
|  | ||||
| tap.test('should read a directory of Dockerfiles', async () => { | ||||
| @@ -46,7 +52,7 @@ tap.test('should read a directory of Dockerfiles', async () => { | ||||
|   return npmci.Dockerfile.readDockerfiles(npmciInstance.dockerManager).then( | ||||
|     async (readDockerfilesArrayArg: npmci.Dockerfile[]) => { | ||||
|       sortableArray = readDockerfilesArrayArg; | ||||
|       return expect(readDockerfilesArrayArg[1].version).to.equal('sometag1'); | ||||
|       return expect(readDockerfilesArrayArg[1].version).toEqual('sometag1'); | ||||
|     } | ||||
|   ); | ||||
| }); | ||||
| @@ -91,7 +97,7 @@ tap.test('should login docker daemon', async () => { | ||||
| // SSH | ||||
| // === | ||||
| tap.test('should prepare SSH keys', async () => { | ||||
|   const npmciModSsh = await import('../ts/mod_ssh'); | ||||
|   const npmciModSsh = await import('../ts/mod_ssh/index.js'); | ||||
|   return await npmciModSsh.handleCli({ | ||||
|     _: ['ssh', 'prepare'], | ||||
|   }); | ||||
|   | ||||
							
								
								
									
										8
									
								
								ts/00_commitinfo_data.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								ts/00_commitinfo_data.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| /** | ||||
|  * autocreated commitinfo by @pushrocks/commitinfo | ||||
|  */ | ||||
| export const commitinfo = { | ||||
|   name: '@shipzone/npmci', | ||||
|   version: '4.1.3', | ||||
|   description: 'node and docker in gitlab ci on steroids' | ||||
| } | ||||
| @@ -1,7 +1,7 @@ | ||||
| import * as plugins from '../npmci.plugins'; | ||||
| import * as plugins from '../npmci.plugins.js'; | ||||
|  | ||||
| import { Npmci } from '../npmci.classes.npmci'; | ||||
| import { logger } from '../npmci.logging'; | ||||
| import { Npmci } from '../npmci.classes.npmci.js'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
|  | ||||
| /** | ||||
|  * connects to cloudly | ||||
| @@ -14,9 +14,10 @@ export class CloudlyConnector { | ||||
|   } | ||||
|  | ||||
|   public async announceDockerContainer( | ||||
|     optionsArg: plugins.tsclass.container.IContainer | ||||
|     optionsArg: plugins.tsclass.container.IContainer, | ||||
|     testCloudlyUrlArg?: string | ||||
|   ) { | ||||
|     const cloudlyUrl = this.npmciRef.npmciConfig.getConfig().urlCloudly; | ||||
|     const cloudlyUrl = testCloudlyUrlArg || this.npmciRef.npmciConfig.getConfig().urlCloudly; | ||||
|     if (!cloudlyUrl) { | ||||
|       logger.log( | ||||
|         'warn', | ||||
| @@ -32,7 +33,7 @@ export class CloudlyConnector { | ||||
|       ); | ||||
|  | ||||
|     const response = await typedrequest.fire({ | ||||
|       containerImageInfo: optionsArg | ||||
|       containerImageInfo: optionsArg, | ||||
|     }); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import { Npmci } from './npmci.classes.npmci'; | ||||
| import { Dockerfile } from './manager.docker/mod.classes.dockerfile'; | ||||
| import { Npmci } from './npmci.classes.npmci.js'; | ||||
| import { Dockerfile } from './manager.docker/mod.classes.dockerfile.js'; | ||||
|  | ||||
| export const npmciInstance = new Npmci(); | ||||
|  | ||||
|   | ||||
| @@ -1,13 +1,13 @@ | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from './mod.plugins'; | ||||
| import * as paths from '../npmci.paths'; | ||||
| import { bash } from '../npmci.bash'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
| import * as paths from '../npmci.paths.js'; | ||||
| import { bash } from '../npmci.bash.js'; | ||||
|  | ||||
| // 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'; | ||||
| import { Npmci } from '../npmci.classes.npmci.js'; | ||||
| import { Dockerfile } from './mod.classes.dockerfile.js'; | ||||
| import { DockerRegistry } from './mod.classes.dockerregistry.js'; | ||||
| import { RegistryStorage } from './mod.classes.registrystorage.js'; | ||||
|  | ||||
| export class NpmciDockerManager { | ||||
|   public npmciRef: Npmci; | ||||
| @@ -77,7 +77,7 @@ export class NpmciDockerManager { | ||||
|    */ | ||||
|   public prepare = async () => { | ||||
|     // Always login to GitLab Registry | ||||
|     if (!process.env.CI_BUILD_TOKEN || process.env.CI_BUILD_TOKEN === '') { | ||||
|     if (!process.env.CI_JOB_TOKEN || process.env.CI_JOB_TOKEN === '') { | ||||
|       logger.log('error', 'No registry token specified by gitlab!'); | ||||
|       process.exit(1); | ||||
|     } | ||||
| @@ -85,7 +85,7 @@ export class NpmciDockerManager { | ||||
|       new DockerRegistry({ | ||||
|         registryUrl: 'registry.gitlab.com', | ||||
|         username: 'gitlab-ci-token', | ||||
|         password: process.env.CI_BUILD_TOKEN, | ||||
|         password: process.env.CI_JOB_TOKEN, | ||||
|       }) | ||||
|     ); | ||||
|  | ||||
|   | ||||
| @@ -1,13 +1,13 @@ | ||||
| import * as plugins from './mod.plugins'; | ||||
| import * as paths from '../npmci.paths'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
| import * as paths from '../npmci.paths.js'; | ||||
|  | ||||
| import { logger } from '../npmci.logging'; | ||||
| import { bash } from '../npmci.bash'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
| import { bash } from '../npmci.bash.js'; | ||||
|  | ||||
| import { DockerRegistry } from './mod.classes.dockerregistry'; | ||||
| import * as helpers from './mod.helpers'; | ||||
| import { NpmciDockerManager } from '.'; | ||||
| import { Npmci } from '../npmci.classes.npmci'; | ||||
| import { DockerRegistry } from './mod.classes.dockerregistry.js'; | ||||
| import * as helpers from './mod.helpers.js'; | ||||
| import { NpmciDockerManager } from './index.js'; | ||||
| import { Npmci } from '../npmci.classes.npmci.js'; | ||||
|  | ||||
| /** | ||||
|  * class Dockerfile represents a Dockerfile on disk in npmci | ||||
| @@ -177,14 +177,17 @@ export class Dockerfile { | ||||
|   ): 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( | ||||
|     for (const dockerArgKey of Object.keys( | ||||
|       npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().dockerBuildargEnvMap | ||||
|     )) { | ||||
|       const targetValue = | ||||
|         process.env[ | ||||
|           npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().dockerBuildargEnvMap[key] | ||||
|         ]; | ||||
|       buildArgsString = `${buildArgsString} --build-arg ${key}="${targetValue}"`; | ||||
|       const dockerArgOuterEnvVar = | ||||
|         npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().dockerBuildargEnvMap[dockerArgKey]; | ||||
|       logger.log( | ||||
|         'note', | ||||
|         `docker ARG "${dockerArgKey}" maps to outer env var "${dockerArgOuterEnvVar}"` | ||||
|       ); | ||||
|       const targetValue = process.env[dockerArgOuterEnvVar]; | ||||
|       buildArgsString = `${buildArgsString} --build-arg ${dockerArgKey}="${targetValue}"`; | ||||
|     } | ||||
|     return buildArgsString; | ||||
|   } | ||||
| @@ -276,8 +279,7 @@ export class Dockerfile { | ||||
|       registryUrl: this.pushTag, | ||||
|       tag: this.buildTag, | ||||
|       labels: [], | ||||
|       version: | ||||
|         this.npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().projectInfo.npm.version, | ||||
|       version: this.npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().projectInfo.npm.version, | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from './mod.plugins'; | ||||
| import { bash } from '../npmci.bash'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
| import { bash } from '../npmci.bash.js'; | ||||
|  | ||||
| export interface IDockerRegistryConstructorOptions { | ||||
|   registryUrl: string; | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from './mod.plugins'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
| import { ObjectMap } from '@pushrocks/lik'; | ||||
|  | ||||
| import { DockerRegistry } from './mod.classes.dockerregistry'; | ||||
| import { DockerRegistry } from './mod.classes.dockerregistry.js'; | ||||
|  | ||||
| export class RegistryStorage { | ||||
|   objectMap = new ObjectMap<DockerRegistry>(); | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from './mod.plugins'; | ||||
| import * as paths from '../npmci.paths'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
| import * as paths from '../npmci.paths.js'; | ||||
|  | ||||
| import { Dockerfile } from './mod.classes.dockerfile'; | ||||
| import { Dockerfile } from './mod.classes.dockerfile.js'; | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| export * from '../npmci.plugins'; | ||||
| export * from '../npmci.plugins.js'; | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from './mod.plugins'; | ||||
| import { bash, bashNoError } from '../npmci.bash'; | ||||
| import { Npmci } from '../npmci.classes.npmci'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
| import { bash, bashNoError } from '../npmci.bash.js'; | ||||
| import { Npmci } from '../npmci.classes.npmci.js'; | ||||
|  | ||||
| export class NpmciGitManager { | ||||
|   public npmciRef: Npmci; | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| export * from '../npmci.plugins'; | ||||
| export * from '../npmci.plugins.js'; | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| import * as plugins from '../npmci.plugins'; | ||||
| import * as paths from '../npmci.paths'; | ||||
| import * as plugins from '../npmci.plugins.js'; | ||||
| import * as paths from '../npmci.paths.js'; | ||||
|  | ||||
| import { logger } from '../npmci.logging'; | ||||
| import { bash, bashNoError, nvmAvailable } from '../npmci.bash'; | ||||
| import { Npmci } from '../npmci.classes.npmci'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
| import { bash, bashNoError, nvmAvailable } from '../npmci.bash.js'; | ||||
| import { Npmci } from '../npmci.classes.npmci.js'; | ||||
|  | ||||
| export class NpmciNodeJsManager { | ||||
|   public npmciRef: Npmci; | ||||
| @@ -44,11 +44,11 @@ export class NpmciNodeJsManager { | ||||
|     logger.log('info', `now installing node version ${versionArg}`); | ||||
|     let version: string; | ||||
|     if (versionArg === 'stable') { | ||||
|       version = '16'; | ||||
|       version = '18'; | ||||
|     } else if (versionArg === 'lts') { | ||||
|       version = '14'; | ||||
|       version = '16'; | ||||
|     } else if (versionArg === 'legacy') { | ||||
|       version = '12'; | ||||
|       version = '14'; | ||||
|     } else { | ||||
|       version = versionArg; | ||||
|     } | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| import * as plugins from './mod.plugins'; | ||||
| import * as paths from '../npmci.paths'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
| import * as paths from '../npmci.paths.js'; | ||||
|  | ||||
| import { logger } from '../npmci.logging'; | ||||
| import { bash, bashNoError, nvmAvailable } from '../npmci.bash'; | ||||
| import { Npmci } from '../npmci.classes.npmci'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
| import { bash, bashNoError, nvmAvailable } from '../npmci.bash.js'; | ||||
| import { Npmci } from '../npmci.classes.npmci.js'; | ||||
|  | ||||
| export class NpmciNpmManager { | ||||
|   public npmciRef: Npmci; | ||||
| @@ -59,6 +59,7 @@ export class NpmciNpmManager { | ||||
|       'NPMCI_TOKEN_NPM*', | ||||
|       (npmEnvArg: string) => { | ||||
|         const npmRegistryUrl = npmEnvArg.split('|')[0]; | ||||
|         logger.log('ok', `found token for ${npmRegistryUrl}`); | ||||
|         let npmToken = npmEnvArg.split('|')[1]; | ||||
|         if (npmEnvArg.split('|')[2] && npmEnvArg.split('|')[2] === 'plain') { | ||||
|           logger.log('ok', 'npm token not base64 encoded.'); | ||||
| @@ -151,6 +152,7 @@ export class NpmciNpmManager { | ||||
|     logger.log('info', `now preparing environment:`); | ||||
|     this.prepare(); | ||||
|     await bash(`npm -v`); | ||||
|     await bash(`pnpm -v`); | ||||
|  | ||||
|     // -> build it | ||||
|     await this.install(); | ||||
| @@ -172,16 +174,16 @@ export class NpmciNpmManager { | ||||
|  | ||||
|   public async install(): Promise<void> { | ||||
|     logger.log('info', 'now installing dependencies:'); | ||||
|     await bash('npm ci'); | ||||
|     await bash('pnpm install'); | ||||
|   } | ||||
|  | ||||
|   public async build(): Promise<void> { | ||||
|     logger.log('info', 'now building the project:'); | ||||
|     await bash('npm run build'); | ||||
|     await bash('pnpm run build'); | ||||
|   } | ||||
|  | ||||
|   public async test(): Promise<void> { | ||||
|     logger.log('info', 'now starting tests:'); | ||||
|     await bash('npm test'); | ||||
|     await bash('pnpm test'); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| export * from '../npmci.plugins'; | ||||
| export * from '../npmci.plugins.js'; | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import * as plugins from './mod.plugins'; | ||||
| import * as paths from '../npmci.paths'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
| import * as paths from '../npmci.paths.js'; | ||||
|  | ||||
| /** | ||||
|  * cleans npmci config files | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| export * from '../npmci.plugins'; | ||||
| export * from '../npmci.plugins.js'; | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import * as plugins from './mod.plugins'; | ||||
| import { bash } from '../npmci.bash'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
| import { bash } from '../npmci.bash.js'; | ||||
|  | ||||
| export let command = async () => { | ||||
|   let wrappedCommand: string = ''; | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| export * from '../npmci.plugins'; | ||||
| export * from '../npmci.plugins.js'; | ||||
|   | ||||
							
								
								
									
										24
									
								
								ts/mod_precheck/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								ts/mod_precheck/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| import * as plugins from './plugins.js'; | ||||
| import * as paths from '../npmci.paths.js'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
| import { Npmci } from '../npmci.classes.npmci.js'; | ||||
|  | ||||
| export const handleCli = async (npmciRefArg: Npmci, argvArg: any) => { | ||||
|   logger.log('info', 'checking execution context'); | ||||
|   const presentRunnerTags = process.env.CI_RUNNER_TAGS.split(',').map((stringArg) => | ||||
|     stringArg.trim() | ||||
|   ); | ||||
|   let allDesiredGitlabRunnerTagsPresent = true; | ||||
|   for (const desiredRunnerTag of npmciRefArg.npmciConfig.getConfig().gitlabRunnerTags) { | ||||
|     if (!presentRunnerTags.includes(desiredRunnerTag)) { | ||||
|       allDesiredGitlabRunnerTagsPresent = false; | ||||
|       logger.log( | ||||
|         'error', | ||||
|         `Desired runnerRag ${desiredRunnerTag} is missing in current execution context.` | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
|   if (!allDesiredGitlabRunnerTagsPresent) { | ||||
|     process.exit(1); | ||||
|   } | ||||
| }; | ||||
							
								
								
									
										1
									
								
								ts/mod_precheck/plugins.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								ts/mod_precheck/plugins.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| export * from '../npmci.plugins.js'; | ||||
| @@ -1,5 +1,5 @@ | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from './mod.plugins'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
| let sshInstance: plugins.smartssh.SshInstance; | ||||
|  | ||||
| export let handleCli = async (argvArg: any) => { | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| export * from '../npmci.plugins'; | ||||
| export * from '../npmci.plugins.js'; | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import * as plugins from './mod.plugins'; | ||||
| import { bash } from '../npmci.bash'; | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
| import { bash } from '../npmci.bash.js'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
|  | ||||
| const triggerValueRegex = | ||||
|   /^([a-zA-Z0-9\.]*)\|([a-zA-Z0-9\.]*)\|([a-zA-Z0-9\.]*)\|([a-zA-Z0-9\.]*)\|?([a-zA-Z0-9\.\-\/]*)/; | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| export * from '../npmci.plugins'; | ||||
| export * from '../npmci.plugins.js'; | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import { logger } from './npmci.logging'; | ||||
| import * as plugins from './npmci.plugins'; | ||||
| import * as paths from './npmci.paths'; | ||||
| import { logger } from './npmci.logging.js'; | ||||
| import * as plugins from './npmci.plugins.js'; | ||||
| import * as paths from './npmci.paths.js'; | ||||
|  | ||||
| import * as smartpromise from '@pushrocks/smartpromise'; | ||||
|  | ||||
|   | ||||
| @@ -1,17 +1,17 @@ | ||||
| import * as plugins from './npmci.plugins'; | ||||
| import * as plugins from './npmci.plugins.js'; | ||||
|  | ||||
| import { CloudlyConnector } from './connector.cloudly/cloudlyconnector'; | ||||
| import { CloudlyConnector } from './connector.cloudly/cloudlyconnector.js'; | ||||
|  | ||||
| import { NpmciInfo } from './npmci.classes.npmciinfo'; | ||||
| import { NpmciCli } from './npmci.classes.npmcicli'; | ||||
| import { NpmciConfig } from './npmci.classes.npmciconfig'; | ||||
| import { NpmciInfo } from './npmci.classes.npmciinfo.js'; | ||||
| import { NpmciCli } from './npmci.classes.npmcicli.js'; | ||||
| import { NpmciConfig } from './npmci.classes.npmciconfig.js'; | ||||
|  | ||||
| // 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'; | ||||
| import { NpmciDockerManager } from './manager.docker/index.js'; | ||||
| import { NpmciGitManager } from './manager.git/index.js'; | ||||
| import { NpmciNodeJsManager } from './manager.nodejs/index.js'; | ||||
| import { NpmciNpmManager } from './manager.npm/index.js'; | ||||
| import { NpmciEnv } from './npmci.classes.npmcienv.js'; | ||||
|  | ||||
| export class Npmci { | ||||
|   public analytics: plugins.smartanalytics.Analytics; | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import { logger } from './npmci.logging'; | ||||
| import * as plugins from './npmci.plugins'; | ||||
| import * as paths from './npmci.paths'; | ||||
| import { Npmci } from './npmci.classes.npmci'; | ||||
| import { logger } from './npmci.logging.js'; | ||||
| import * as plugins from './npmci.plugins.js'; | ||||
| import * as paths from './npmci.paths.js'; | ||||
| import { Npmci } from './npmci.classes.npmci.js'; | ||||
|  | ||||
| export class NpmciCli { | ||||
|   public npmciRef: Npmci; | ||||
| @@ -15,7 +15,7 @@ export class NpmciCli { | ||||
|     // clean | ||||
|     this.smartcli.addCommand('clean').subscribe( | ||||
|       async (argv) => { | ||||
|         const modClean = await import('./mod_clean/index'); | ||||
|         const modClean = await import('./mod_clean/index.js'); | ||||
|         await modClean.clean(); | ||||
|       }, | ||||
|       (err) => { | ||||
| @@ -27,7 +27,7 @@ export class NpmciCli { | ||||
|     // command | ||||
|     this.smartcli.addCommand('command').subscribe( | ||||
|       async (argv) => { | ||||
|         const modCommand = await import('./mod_command/index'); | ||||
|         const modCommand = await import('./mod_command/index.js'); | ||||
|         await modCommand.command(); | ||||
|       }, | ||||
|       (err) => { | ||||
| @@ -79,22 +79,21 @@ export class NpmciCli { | ||||
|       } | ||||
|     ); | ||||
|  | ||||
|     this.smartcli.addCommand('precheck').subscribe(async (argvArg) => { | ||||
|       const modPrecheck = await import('./mod_precheck/index.js'); | ||||
|       await modPrecheck.handleCli(this.npmciRef, argvArg); | ||||
|     }); | ||||
|  | ||||
|     // 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); | ||||
|       } | ||||
|     ); | ||||
|     this.smartcli.addCommand('ssh').subscribe(async (argvArg) => { | ||||
|       const modSsh = await import('./mod_ssh/index.js'); | ||||
|       await modSsh.handleCli(argvArg); | ||||
|     }); | ||||
|  | ||||
|     // trigger | ||||
|     this.smartcli.addCommand('trigger').subscribe( | ||||
|       async (argv) => { | ||||
|         const modTrigger = await import('./mod_trigger/index'); | ||||
|         const modTrigger = await import('./mod_trigger/index.js'); | ||||
|         await modTrigger.trigger(); | ||||
|       }, | ||||
|       (err) => { | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| import * as plugins from './npmci.plugins'; | ||||
| import * as paths from './npmci.paths'; | ||||
| import * as plugins from './npmci.plugins.js'; | ||||
| import * as paths from './npmci.paths.js'; | ||||
|  | ||||
| import { logger } from './npmci.logging'; | ||||
| import { Npmci } from './npmci.classes.npmci'; | ||||
| import { logger } from './npmci.logging.js'; | ||||
| import { Npmci } from './npmci.classes.npmci.js'; | ||||
|  | ||||
| /** | ||||
|  * the main config interface for npmci | ||||
| @@ -20,6 +20,9 @@ export interface INpmciOptions { | ||||
|   dockerRegistryRepoMap: { [key: string]: string }; | ||||
|   dockerBuildargEnvMap: { [key: string]: string }; | ||||
|  | ||||
|   // gitlab | ||||
|   gitlabRunnerTags: string[]; | ||||
|  | ||||
|   // urls | ||||
|   urlCloudly: string; | ||||
| } | ||||
| @@ -57,6 +60,7 @@ export class NpmciConfig { | ||||
|       dockerRegistryRepoMap: {}, | ||||
|       npmAccessLevel: 'private', | ||||
|       npmRegistryUrl: 'registry.npmjs.org', | ||||
|       gitlabRunnerTags: [], | ||||
|       dockerBuildargEnvMap: {}, | ||||
|       urlCloudly: this.npmciQenv.getEnvVarOnDemand('NPMCI_URL_CLOUDLY'), | ||||
|     }; | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import * as plugins from './npmci.plugins'; | ||||
| import { Npmci } from './npmci.classes.npmci'; | ||||
| import * as plugins from './npmci.plugins.js'; | ||||
| import { Npmci } from './npmci.classes.npmci.js'; | ||||
|  | ||||
| export class NpmciEnv { | ||||
|   public npmciRef: Npmci; | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import * as plugins from './npmci.plugins'; | ||||
| import * as paths from './npmci.paths'; | ||||
| import { logger } from './npmci.logging'; | ||||
| import { Npmci } from './npmci.classes.npmci'; | ||||
| import * as plugins from './npmci.plugins.js'; | ||||
| import * as paths from './npmci.paths.js'; | ||||
| import { logger } from './npmci.logging.js'; | ||||
| import { Npmci } from './npmci.classes.npmci.js'; | ||||
|  | ||||
| export class NpmciInfo { | ||||
|   public npmciRef: Npmci; | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import * as plugins from './npmci.plugins'; | ||||
| import * as plugins from './npmci.plugins.js'; | ||||
|  | ||||
| export const logger = new plugins.smartlog.Smartlog({ | ||||
|   logContext: { | ||||
|   | ||||
| @@ -1,9 +1,12 @@ | ||||
| import * as plugins from './npmci.plugins'; | ||||
| import * as plugins from './npmci.plugins.js'; | ||||
|  | ||||
| export const cwd = process.cwd(); | ||||
|  | ||||
| // package paths | ||||
| export const NpmciPackageRoot = plugins.path.join(__dirname, '../'); | ||||
| export const NpmciPackageRoot = plugins.path.join( | ||||
|   plugins.smartpath.get.dirnameFromImportMetaUrl(import.meta.url), | ||||
|   '../' | ||||
| ); | ||||
| export const NpmciPackageConfig = plugins.path.join(NpmciPackageRoot, './config.json'); | ||||
|  | ||||
| // project paths | ||||
|   | ||||
| @@ -25,6 +25,7 @@ import * as smartgit from '@pushrocks/smartgit'; | ||||
| import * as smartlog from '@pushrocks/smartlog'; | ||||
| import * as smartlogDestinationLocal from '@pushrocks/smartlog-destination-local'; | ||||
| import * as smartparam from '@pushrocks/smartparam'; | ||||
| import * as smartpath from '@pushrocks/smartpath'; | ||||
| import * as smartpromise from '@pushrocks/smartpromise'; | ||||
| import * as smartrequest from '@pushrocks/smartrequest'; | ||||
| import * as smartshell from '@pushrocks/smartshell'; | ||||
| @@ -39,10 +40,12 @@ export { | ||||
|   smartanalytics, | ||||
|   smartdelay, | ||||
|   smartfile, | ||||
|   smartgit, | ||||
|   smartcli, | ||||
|   smartlog, | ||||
|   smartlogDestinationLocal, | ||||
|   smartparam, | ||||
|   smartpath, | ||||
|   smartpromise, | ||||
|   smartrequest, | ||||
|   smartshell, | ||||
| @@ -54,9 +57,7 @@ export { | ||||
| // @tsclass scope | ||||
| import * as tsclass from '@tsclass/tsclass'; | ||||
|  | ||||
| export { | ||||
|   tsclass | ||||
| } | ||||
| export { tsclass }; | ||||
|  | ||||
| // third party | ||||
| import * as through2 from 'through2'; | ||||
|   | ||||
							
								
								
									
										10
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| { | ||||
|   "compilerOptions": { | ||||
|     "experimentalDecorators": true, | ||||
|     "useDefineForClassFields": false, | ||||
|     "target": "ES2022", | ||||
|     "module": "ES2022", | ||||
|     "moduleResolution": "nodenext", | ||||
|     "esModuleInterop": true | ||||
|   } | ||||
| } | ||||
							
								
								
									
										17
									
								
								tslint.json
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								tslint.json
									
									
									
									
									
								
							| @@ -1,17 +0,0 @@ | ||||
| { | ||||
|   "extends": ["tslint:latest", "tslint-config-prettier"], | ||||
|   "rules": { | ||||
|     "semicolon": [true, "always"], | ||||
|     "no-console": false, | ||||
|     "ordered-imports": false, | ||||
|     "object-literal-sort-keys": false, | ||||
|     "member-ordering": { | ||||
|       "options":{ | ||||
|         "order": [ | ||||
|           "static-method" | ||||
|         ] | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   "defaultSeverity": "warning" | ||||
| } | ||||
		Reference in New Issue
	
	Block a user