Compare commits

...

94 Commits

Author SHA1 Message Date
0b5dada524 3.1.23 2019-05-08 22:43:49 +02:00
40bddba3b5 fix(core): update 2019-05-08 22:43:48 +02:00
6f6ee6d799 3.1.22 2019-02-24 22:50:12 +01:00
e30cc3f5a0 fix(core): update 2019-02-24 22:50:12 +01:00
a4562d4d1b 3.1.21 2018-12-24 02:13:05 +01:00
524b405773 fix(core): update 2018-12-24 02:13:04 +01:00
0d19c1c68d 3.1.20 2018-12-23 18:57:15 +01:00
cff79bc3b4 fix(mirror): now refusing to mirror for private code 2018-12-23 18:57:15 +01:00
28541a838d 3.1.19 2018-12-23 18:54:17 +01:00
c3ab527341 fix(core): update 2018-12-23 18:54:16 +01:00
52cc249098 3.1.18 2018-12-23 17:29:25 +01:00
2e189b0660 fix(core): update 2018-12-23 17:29:25 +01:00
f876c7414b 3.1.17 2018-12-12 22:29:59 +01:00
08b7585cfc fix(core): update 2018-12-12 22:29:59 +01:00
76311fab72 3.1.16 2018-12-11 01:02:22 +01:00
1b73df64f5 fix(core): update 2018-12-11 01:02:21 +01:00
701cee573b 3.1.15 2018-12-11 00:25:40 +01:00
3dd086f711 fix(core): update 2018-12-11 00:25:39 +01:00
67ff5d09d4 3.1.14 2018-12-09 16:48:33 +01:00
5cb8a79b6a fix(core): update 2018-12-09 16:48:33 +01:00
2dcbca2362 3.1.13 2018-12-09 16:26:28 +01:00
bd63194f4b fix(core): update 2018-12-09 16:26:28 +01:00
2763fdef5f 3.1.12 2018-12-09 15:53:39 +01:00
bbedde01b9 fix(core): update 2018-12-09 15:53:38 +01:00
f26606f757 3.1.11 2018-12-09 15:22:20 +01:00
99b03aa796 fix(core): update 2018-12-09 15:22:20 +01:00
f30dd3da65 3.1.10 2018-12-09 14:59:51 +01:00
d4decddb4b fix(core): update 2018-12-09 14:59:51 +01:00
5c2880da1a 3.1.9 2018-12-09 14:53:44 +01:00
bfffc5b130 3.1.8 2018-12-09 14:39:25 +01:00
8900a13c6b fix(core): update 2018-12-09 14:39:24 +01:00
d42acf737f 3.1.7 2018-12-09 02:51:04 +01:00
77e3b2912d fix(core): update 2018-12-09 02:51:03 +01:00
103e470eb4 3.1.6 2018-12-09 02:50:00 +01:00
74c1324e55 fix(core): update 2018-12-09 02:50:00 +01:00
a1876963a8 3.1.5 2018-11-28 21:06:12 +01:00
5d88e25c99 fix(dependencies): update 2018-11-28 21:06:12 +01:00
b3c47546e2 3.1.4 2018-11-26 18:01:55 +01:00
6316e81958 fix(core): update 2018-11-26 18:01:54 +01:00
ff10afbee4 3.1.3 2018-11-24 15:12:55 +01:00
9dbfa77084 fix(ci): remove npmts build dependency 2018-11-24 15:12:55 +01:00
46dbd61d89 3.1.2 2018-11-24 15:10:56 +01:00
713df1867a fix(core): update 2018-11-24 15:10:55 +01:00
23886c1ed3 3.1.1 2018-11-24 15:08:08 +01:00
0c46b627be fix(core): update 2018-11-24 15:08:07 +01:00
622ccd8dd9 3.1.0 2018-11-24 15:00:19 +01:00
0079addfc5 feat(logging): use smartlog 2018-11-24 15:00:19 +01:00
8604c63d37 3.0.59 2018-09-22 15:18:21 +02:00
db0b38bd7b fix(cli): update cli files to be in line with gitzone cli template 2018-09-22 15:18:21 +02:00
edde87b6be 3.0.58 2018-09-22 14:36:26 +02:00
5085d664cb fix(fix request package usage): update 2018-09-22 14:36:25 +02:00
5d468fc840 3.0.57 2018-09-22 14:13:26 +02:00
e2ac6cdcc9 fix(dependencies): update 2018-09-22 14:13:25 +02:00
fcd04415be 3.0.56 2018-07-16 00:04:24 +02:00
1fd1899099 fix(ci): update to latest standards 2018-07-16 00:04:24 +02:00
7df7f882d1 3.0.55 2018-07-16 00:02:30 +02:00
348b4d60fd fix(security): snyk 2018-07-16 00:02:29 +02:00
37589fb5e5 3.0.54 2018-07-15 23:58:43 +02:00
3dd115fe42 fix(ci): adjust to newer build system 2018-07-15 23:58:43 +02:00
01c88a6a6c 3.0.53 2018-07-15 23:49:38 +02:00
f5cacb7400 fix(core): update 2018-07-15 23:49:37 +02:00
887da51d78 3.0.52 2018-07-02 23:15:25 +02:00
585703fc55 fix(core): switch to @pushrocks/smartpromise 2018-07-02 23:15:24 +02:00
ec3e296d73 3.0.51 2018-07-02 23:09:52 +02:00
33f234cf73 fix(core): update to latest standards 2018-07-02 23:09:52 +02:00
e7ec765ed5 3.0.50 2018-05-27 15:43:50 +02:00
2f46197864 fix(structure): removed .npmignore 2018-05-27 15:43:50 +02:00
da44233263 3.0.49 2018-05-27 15:41:58 +02:00
cb2430f7b2 fix(build): improved asset handling 2018-05-27 15:41:58 +02:00
5fe9134f4a 3.0.48 2018-05-27 14:34:42 +02:00
7681f09d38 feat(npm) switch to npm as default package manager 2018-05-27 14:34:38 +02:00
d55c77560a 3.0.47 2018-05-07 10:51:45 +02:00
0e337a3574 fix(ci): update .gitlab.yml to latest gitzone version 2018-05-07 10:51:45 +02:00
94c5567b75 3.0.46 2018-05-05 02:28:26 +02:00
7b37506d4e update .npmignore 2018-05-05 02:28:02 +02:00
a401633b73 3.0.45 2018-05-05 02:27:29 +02:00
948a8e64d7 3.0.44 2018-05-04 15:58:18 +02:00
9e8fbac573 update to better smartcli parsing 2018-05-04 15:58:11 +02:00
362740a55f 3.0.43 2018-05-04 00:48:32 +02:00
3edc08b0ed update snyk policy 2018-05-04 00:48:25 +02:00
15d7e6cbfc 3.0.42 2018-05-04 00:42:53 +02:00
6824210da0 3.0.41 2018-05-04 00:23:23 +02:00
41d2d04958 update dependencies 2018-05-04 00:23:21 +02:00
e490c6f730 3.0.40 2018-05-04 00:22:10 +02:00
bdf4815145 3.0.39 2018-05-03 23:52:55 +02:00
84fdf8b139 now cleans up before publishing 2018-05-03 23:52:51 +02:00
545896821d 3.0.38 2018-05-03 21:29:38 +02:00
c7516458bd update .gitignore 2018-05-03 21:29:35 +02:00
c2f92e63c5 3.0.37 2018-05-03 20:40:29 +02:00
d4116aefdb update npm 2018-05-03 20:40:26 +02:00
0f5f1f7772 3.0.36 2018-05-03 20:08:00 +02:00
7722187ea5 update ci 2018-05-03 20:07:49 +02:00
734a21c925 update publishing process 2018-05-03 19:56:38 +02:00
bb36beb682 3.0.35 2018-05-03 19:48:03 +02:00
36 changed files with 4087 additions and 2423 deletions

1
.gitignore vendored
View File

@@ -4,3 +4,4 @@ coverage/
public/ public/
config.json config.json
.yarn/ .yarn/
.npmci_cache

View File

@@ -3,94 +3,148 @@ image: hosttoday/ht-docker-node:npmci
cache: cache:
paths: paths:
- .yarn/ - .npmci_cache/
key: "$CI_BUILD_STAGE" key: "$CI_BUILD_STAGE"
stages: stages:
- security - security
- test - test
- release - release
- trigger - metadata
- pages
# ====================
# security stage
# ====================
mirror: mirror:
stage: security stage: security
script: script:
- npmci git mirror - npmci git mirror
tags: tags:
- docker - docker
- notpriv
snyk: snyk:
stage: security stage: security
script: script:
- npmci command yarn global add snyk - npmci npm prepare
- npmci command yarn install --ignore-scripts - npmci command npm install -g snyk
- npmci command npm install --ignore-scripts
- npmci command snyk test - npmci command snyk test
tags: tags:
- docker - docker
- notpriv
testLEGACY: sast:
stage: test stage: security
image: registry.gitlab.com/hosttoday/ht-docker-dbase:npmci
variables:
DOCKER_DRIVER: overlay2
allow_failure: true
services:
- docker:stable-dind
script: script:
- npmci node install legacy - npmci npm prepare
- npmci npm install - npmci npm install
- npmci npm test - npmci command npm run build
coverage: /\d+.?\d+?\%\s*coverage/ - export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
- docker run
--env SAST_CONFIDENCE_LEVEL="${SAST_CONFIDENCE_LEVEL:-3}"
--volume "$PWD:/code"
--volume /var/run/docker.sock:/var/run/docker.sock
"registry.gitlab.com/gitlab-org/security-products/sast:$SP_VERSION" /app/bin/run /code
artifacts:
reports:
sast: gl-sast-report.json
tags: tags:
- docker - docker
allow_failure: true - priv
# ====================
# test stage
# ====================
testLTS: testLTS:
stage: test stage: test
script: script:
- npmci npm prepare
- npmci node install lts - npmci node install lts
- npmci npm install - npmci npm install
- npmci npm test - npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/ coverage: /\d+.?\d+?\%\s*coverage/
tags: tags:
- docker - docker
- notpriv
testSTABLE: testSTABLE:
stage: test stage: test
script: script:
- npmci npm prepare
- npmci node install stable - npmci node install stable
- npmci npm install - npmci npm install
- npmci npm test - npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/ coverage: /\d+.?\d+?\%\s*coverage/
tags: tags:
- docker - docker
- notpriv
release: release:
stage: release stage: release
script: script:
- npmci node install stable - npmci node install stable
- npmci npm prepare
- npmci npm publish - npmci npm publish
only: only:
- tags - tags
tags: tags:
- docker - docker
- notpriv
# ====================
# metadata stage
# ====================
codequality:
stage: metadata
image: docker:stable
allow_failure: true
services:
- docker:stable-dind
script:
- export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
- docker run
--env SOURCE_CODE="$PWD"
--volume "$PWD":/code
--volume /var/run/docker.sock:/var/run/docker.sock
"registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
artifacts:
paths: [codeclimate.json]
tags:
- docker
- priv
trigger: trigger:
stage: trigger stage: metadata
script: script:
- npmci trigger - npmci trigger
only: only:
- tags - tags
tags: tags:
- docker - docker
- notpriv
pages: pages:
image: hosttoday/ht-docker-node:npmci image: hosttoday/ht-docker-node:npmci
stage: pages stage: metadata
script: script:
- npmci command yarn global add npmpage - npmci command npm install -g typedoc typescript
- npmci command npmpage - npmci npm prepare
- npmci npm install
- npmci command typedoc --module "commonjs" --target "ES2016" --out public/ ts/
tags: tags:
- docker - docker
- notpriv
only: only:
- tags - tags
artifacts: artifacts:
expire_in: 1 week expire_in: 1 week
paths: paths:
- public - public
allow_failure: true

View File

@@ -1,5 +0,0 @@
pages/
coverage/
test/
node_modules/
config.json

15
.snyk
View File

@@ -1,15 +1,4 @@
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. # Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
version: v1.10.2 version: v1.13.1
# ignores vulnerabilities until expiry date; change duration by modifying expiry date ignore: {}
ignore:
'npm:shelljs:20140723':
- shelljs:
reason: None given
expires: '2018-05-04T20:41:54.426Z'
- smartshell > shelljs:
reason: None given
expires: '2018-05-04T20:41:54.426Z'
- smartssh > shelljs:
reason: None given
expires: '2018-05-04T20:41:54.426Z'
patch: {} patch: {}

3
cli.js Normal file
View File

@@ -0,0 +1,3 @@
#!/usr/bin/env node
process.env.CLI_CALL = 'true';
require('./dist/index');

4
cli.ts.js Normal file
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env node
process.env.CLI_CALL = 'true';
require('@gitzone/tsrun');
require('./ts/index');

View File

@@ -1,100 +0,0 @@
# npmci
node and docker in gitlab ci on steroids
## Availabililty
[![npm](https://gitzone.gitlab.io/assets/repo-button-npm.svg)](https://www.npmjs.com/package/npmci)
[![git](https://gitzone.gitlab.io/assets/repo-button-git.svg)](https://GitLab.com/gitzone/npmci)
[![git](https://gitzone.gitlab.io/assets/repo-button-mirror.svg)](https://github.com/gitzone/npmci)
[![docs](https://gitzone.gitlab.io/assets/repo-button-docs.svg)](https://gitzone.gitlab.io/npmci/)
## Status for master
[![build status](https://GitLab.com/gitzone/npmci/badges/master/build.svg)](https://GitLab.com/gitzone/npmci/commits/master)
[![coverage report](https://GitLab.com/gitzone/npmci/badges/master/coverage.svg)](https://GitLab.com/gitzone/npmci/commits/master)
[![npm downloads per month](https://img.shields.io/npm/dm/npmci.svg)](https://www.npmjs.com/package/npmci)
[![Dependency Status](https://david-dm.org/gitzonetools/npmci.svg)](https://david-dm.org/gitzonetools/npmci)
[![bitHound Dependencies](https://www.bithound.io/github/gitzonetools/npmci/badges/dependencies.svg)](https://www.bithound.io/github/gitzonetools/npmci/master/dependencies/npm)
[![bitHound Code](https://www.bithound.io/github/gitzonetools/npmci/badges/code.svg)](https://www.bithound.io/github/gitzonetools/npmci)
[![TypeScript](https://img.shields.io/badge/TypeScript-2.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![node](https://img.shields.io/badge/node->=%206.x.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)
## Usage
Use TypeScript for best in class instellisense.
npmci is designed to work in docker CI environments. The following docker images come with npmci presinstalled:
Docker Hub:
* [hosttoday/ht-docker-node:npmci](https://hub.docker.com/r/hosttoday/ht-docker-node/)
has LTS node version and npmci preinstalled.
* [hosttoday/ht-docker-dbase](https://hub.docker.com/r/hosttoday/ht-docker-dbase/)
based on docker:git, can be used to build docker images in conjunction with docker:dind
npmci can be called from commandline:
```shell
# Install any node version:
npmci install lts # will install latest LTS node version and update PATH for node and npm versions
npmci install stable # will install latest stable node version and update PATH for node and npm
npmci install legacy # will install latest legacy node version and update PATH for node and npm
npmci install x.x.x # will install any specific node version.
# Install any node version, install dependencies and run test in cwd:
npmci test lts # will install latest lts node version and run "npm install" and "npm test".
npmci test stable # will install latest stable node version and run "npm install" and "npm test".
npmci test legacy # will install latest legacy node version and run "npm install" and "npm test".
npmci test x.x.x # will install any specific node version and run "npm install" and "npm test".
npmci test docker # will test any build image with tests defined in ./npmci/dockertest_1.sh to ./npmci/dockertest_100.sh
## npmci test docker will look at all Dockerfiles and look for according tags on GitLab container registry
# prepare tools
npmci prepare npm # will look for $NPMCI_TOKEN_NPM env var and create .npmrc, so npm is authenticated
npmci prepare docker # will look for $NPMCI_LOGIN_DOCKER in form username|password and authenticate docker
npmci prepare docker-gitlab # will authenticate docker for gitlab container registry
# build containers
npmci build docker # will build containers
## all Dockerfiles named Dockerfile* are picked up.
## specify tags like this Dockerfile_[tag]
## uploads all built images as [username]/[reponame]:[tag]_test to GitLab
## then test in next step with "npmci test docker"
# publish npm module
npmci publish npm # will look vor $NPMCI_TOKEN_NPM env var and push any module in cwd to npm
npmci publish docker
# trigger webhooks
npmci trigger # will look for NPMCI_TRIGGER_1 to NPMCI_TRIGGER_100 in form domain|id|token|ref|name
```
## Configuration
npmci supports the use of npmextra.
To configure npmci create a `npmextra.json` file at the root of your project
```json
{
"npmci": {
"globalNpmTools": ["npm-check-updates", "protractor", "npmts", "gitzone"]
}
}
```
**Available options**
| setting | example | description |
| -------------- | ----------------------------- | ------------------------------------------------------------------------------------------------- |
| globalNpmTools | "globalNpmTools": ["gitbook"] | Will look for the specified package names locally and (if not yet present) install them from npm. |
For further information read the linked docs at the top of this README.
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
> | By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy.html)
[![repo-footer](https://gitzone.gitlab.io/assets/repo-footer.svg)](https://push.rocks)

View File

@@ -1,22 +0,0 @@
# SSH
npmci allows easy usage of ssh:
## Add the SSH KEY to the environment
To make npmci aware of any SSH KEY add it to the environment in the following format
```
# Key
NPMCI_SSHKEY_[A_NAME_FROM_YOU]
# Value:
[targeted host]|[privatekey as base64]|***
```
## Use npmci cli tool in your ci script
```
npmci prepare ssh
npmci command git remote add heroku ssh://git@heroku.com/[you project name].git
npmci command git push heroku master
```

View File

@@ -1,17 +1,26 @@
{ {
"npmts":{ "npmts": {
"mode":"default", "mode": "default",
"coverageTreshold": "70", "coverageTreshold": "70",
"cli": true "cli": true
}, },
"npmci": { "npmci": {
"npmGlobalTools": [ "npmGlobalTools": [],
"@gitzone/npmts" "npmAccessLevel": "public",
], "npmRegistryUrl": "registry.npmjs.org"
"npmAccessLevel": "public"
}, },
"npmdocker":{ "npmdocker": {
"baseImage":"hosttoday/ht-docker-node:npmci", "baseImage": "hosttoday/ht-docker-node:npmci",
"command": "npmci test stable" "command": "npmci test stable"
},
"gitzone": {
"module": {
"githost": "gitlab.com",
"gitscope": "shipzone",
"gitrepo": "npmci",
"shortDescription": "node and docker in gitlab ci on steroids",
"npmPackagename": "@shipzone/npmci",
"license": "MIT"
}
} }
} }

3458
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,16 +1,17 @@
{ {
"name": "@shipzone/npmci", "name": "@shipzone/npmci",
"version": "3.0.34", "version": "3.1.23",
"private": false,
"description": "node and docker in gitlab ci on steroids", "description": "node and docker in gitlab ci on steroids",
"main": "dist/index.js", "main": "dist/index.js",
"typings": "dist/index.d.ts", "typings": "dist/index.d.ts",
"bin": { "bin": {
"npmci": "dist/cli.js" "npmci": "cli.js"
}, },
"scripts": { "scripts": {
"test": "(rm -f config.json) && (npmts) && (npm run testVersion)", "test": "(rm -f config.json) && tstest test/",
"build": "(rm -f config.json) && (npmts) && (npm run testVersion)", "build": "(rm -f config.json) && tsbuild && (npm run testVersion)",
"testVersion": "(cd test/assets/ && node ../../dist/cli.js -v)" "testVersion": "(cd test/assets/ && node ../../cli.js -v)"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@@ -23,31 +24,35 @@
}, },
"homepage": "https://gitlab.com/gitzone/npmci#README", "homepage": "https://gitlab.com/gitzone/npmci#README",
"devDependencies": { "devDependencies": {
"tapbundle": "^2.0.0" "@gitzone/tsbuild": "^2.1.11",
"@gitzone/tsrun": "^1.2.6",
"@gitzone/tstest": "^1.0.20",
"@pushrocks/tapbundle": "^3.0.9",
"@types/node": "^12.0.0",
"tslint": "^5.16.0",
"tslint-config-prettier": "^1.18.0"
}, },
"dependencies": { "dependencies": {
"@types/lodash": "^4.14.74", "@pushrocks/lik": "^3.0.5",
"@types/shelljs": "^0.7.4", "@pushrocks/npmextra": "^3.0.1",
"@types/through2": "^2.0.33", "@pushrocks/projectinfo": "^4.0.2",
"beautylog": "^6.1.10", "@pushrocks/smartanalytics": "^2.0.15",
"cflare": "^1.0.5", "@pushrocks/smartcli": "^3.0.7",
"lik": "^2.0.5", "@pushrocks/smartdelay": "^2.0.3",
"lodash": "^4.17.4", "@pushrocks/smartfile": "^7.0.2",
"npmextra": "^2.0.9", "@pushrocks/smartlog": "^2.0.19",
"projectinfo": "^3.0.2", "@pushrocks/smartlog-destination-local": "^7.0.5",
"request": "^2.81.0", "@pushrocks/smartparam": "^1.0.4",
"shelljs": "^0.8.1", "@pushrocks/smartpromise": "^3.0.2",
"smartanalytics": "^2.0.9", "@pushrocks/smartrequest": "^1.1.15",
"smartcli": "^2.0.7", "@pushrocks/smartshell": "^2.0.13",
"smartdelay": "^1.0.3", "@pushrocks/smartsocket": "^1.1.36",
"smartfile": "^4.2.20", "@pushrocks/smartssh": "^1.2.3",
"smartparam": "^1.0.2", "@pushrocks/smartstring": "^3.0.10",
"smartq": "^1.1.6", "@types/lodash": "^4.14.124",
"smartshell": "^1.0.18", "@types/shelljs": "^0.8.5",
"smartsocket": "^1.1.10", "@types/through2": "^2.0.34",
"smartssh": "^1.2.2", "lodash": "^4.17.11",
"smartstring": "^2.0.24", "through2": "^3.0.1"
"smartsystem": "^2.0.2",
"through2": "^2.0.3"
} }
} }

110
readme.md
View File

@@ -1,33 +1,101 @@
# npmci # @shipzone/npmci
node and docker in gitlab ci on steroids node and docker in gitlab ci on steroids
## Availabililty ## Availabililty and Links
* [npmjs.org (npm package)](https://www.npmjs.com/package/@shipzone/npmci)
[![npm](https://shipzone.gitlab.io/assets/repo-button-npm.svg)](https://www.npmjs.com/package/@shipzone/npmci) * [gitlab.com (source)](https://gitlab.com/shipzone/npmci)
[![git](https://shipzone.gitlab.io/assets/repo-button-git.svg)](https://GitLab.com/shipzone/npmci) * [github.com (source mirror)](https://github.com/shipzone/npmci)
[![git](https://shipzone.gitlab.io/assets/repo-button-mirror.svg)](https://github.com/shipzone/npmci) * [docs (typedoc)](https://shipzone.gitlab.io/npmci/)
[![docs](https://shipzone.gitlab.io/assets/repo-button-docs.svg)](https://shipzone.gitlab.io/npmci/)
## Status for master ## Status for master
[![build status](https://gitlab.com/shipzone/npmci/badges/master/build.svg)](https://gitlab.com/shipzone/npmci/commits/master)
[![build status](https://GitLab.com/shipzone/npmci/badges/master/build.svg)](https://GitLab.com/shipzone/npmci/commits/master) [![coverage report](https://gitlab.com/shipzone/npmci/badges/master/coverage.svg)](https://gitlab.com/shipzone/npmci/commits/master)
[![coverage report](https://GitLab.com/shipzone/npmci/badges/master/coverage.svg)](https://GitLab.com/shipzone/npmci/commits/master) [![npm downloads per month](https://img.shields.io/npm/dm/@shipzone/npmci.svg)](https://www.npmjs.com/package/@shipzone/npmci)
[![npm downloads per month](https://img.shields.io/npm/dm/npmci.svg)](https://www.npmjs.com/package/@shipzone/npmci) [![Known Vulnerabilities](https://snyk.io/test/npm/@shipzone/npmci/badge.svg)](https://snyk.io/test/npm/@shipzone/npmci)
[![Dependency Status](https://david-dm.org/shipzone/npmci.svg)](https://david-dm.org/shipzone/npmci) [![TypeScript](https://img.shields.io/badge/TypeScript->=%203.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
[![bitHound Dependencies](https://www.bithound.io/github/shipzone/npmci/badges/dependencies.svg)](https://www.bithound.io/github/shipzone/npmci/master/dependencies/npm) [![node](https://img.shields.io/badge/node->=%2010.x.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
[![bitHound Code](https://www.bithound.io/github/shipzone/npmci/badges/code.svg)](https://www.bithound.io/github/shipzone/npmci) [![JavaScript Style Guide](https://img.shields.io/badge/code%20style-prettier-ff69b4.svg)](https://prettier.io/)
[![TypeScript](https://img.shields.io/badge/TypeScript-2.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![node](https://img.shields.io/badge/node->=%206.x.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)
## Usage ## Usage
Use TypeScript for best in class instellisense. Use TypeScript for best in class instellisense.
npmci is designed to work in docker CI environments. The following docker images come with npmci presinstalled:
Docker Hub:
- [hosttoday/ht-docker-node:npmci](https://hub.docker.com/r/hosttoday/ht-docker-node/)
has LTS node version and npmci preinstalled.
- [hosttoday/ht-docker-dbase](https://hub.docker.com/r/hosttoday/ht-docker-dbase/)
based on docker:git, can be used to build docker images in conjunction with docker:dind
npmci can be called from commandline and handle a lot of tasks durug ci:
```shell
# Handle node versions
npmci node install stable # will install latest stable node version and update PATH for node and npm
npmci node install lts # will install latest LTS node version and update PATH for node and npm versions
npmci node install legacy # will install latest legacy node version and update PATH for node and npm
npmci node install x.x.x # will install any specific node version.
# Handle npm and yarn tasks
npmcu npm login # logs in npm using the auth key provided at env var "NPMCI_TOKEN_NPM"
npmci npm install # installs dependencies using npm or yarn dependending on availablity
npmci npm test # tests the package
npmci npm publish # builds a package and publishes it
# handle docker tasks
npmci docker prepare
## npmci test docker will look at all Dockerfiles and look for according tags on GitLab container registry
# prepare tools
npmci prepare npm # will look for $NPMCI_TOKEN_NPM env var and create .npmrc, so npm is authenticated
npmci prepare docker # will look for $NPMCI_LOGIN_DOCKER in form username|password and authenticate docker
npmci prepare docker-gitlab # will authenticate docker for gitlab container registry
# build containers
npmci docker build # will build containers
## all Dockerfiles named Dockerfile* are picked up.
## specify tags like this Dockerfile_[tag]
## uploads all built images as [username]/[reponame]:[tag]_test to GitLab
## then test in next step with "npmci test docker"
# publish npm module
npmci publish npm # will look vor $NPMCI_TOKEN_NPM env var and push any module in cwd to npm
npmci publish docker
# trigger webhooks
npmci trigger # will look for NPMCI_TRIGGER_1 to NPMCI_TRIGGER_100 in form domain|id|token|ref|name
```
## Configuration
npmci supports the use of npmextra.
To configure npmci create a `npmextra.json` file at the root of your project
```json
{
"npmci": {
"globalNpmTools": ["npm-check-updates", "protractor", "npmts", "gitzone"]
}
}
```
**Available options**
| setting | example | description |
| -------------- | ----------------------------- | ------------------------------------------------------------------------------------------------- |
| globalNpmTools | "globalNpmTools": ["gitbook"] | Will look for the specified package names locally and (if not yet present) install them from npm. |
For further information read the linked docs at the top of this README. For further information read the linked docs at the top of this README.
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh) Use TypeScript for best in class instellisense.
> | By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy.html)
[![repo-footer](https://shipzone.gitlab.io/assets/repo-footer.svg)](https://push.rocks) For further information read the linked docs at the top of this readme.
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy.html)
[![repo-footer](https://shipzone.gitlab.io/assets/repo-footer.svg)](https://maintainedby.lossless.com)

View File

@@ -1,4 +1,4 @@
import { tap, expect } from 'tapbundle'; import { tap, expect } from '@pushrocks/tapbundle';
import * as path from 'path'; import * as path from 'path';
// Setup test // Setup test

View File

@@ -1,31 +0,0 @@
import * as plugins from './mod.plugins';
let npmciCflare = new plugins.cflare.CflareAccount();
/**
* handle cli input
* @param argvArg
*/
export let handleCli = async argvArg => {
if (argvArg._.length >= 2) {
let action: string = argvArg._[1];
switch (action) {
default:
plugins.beautylog.error(`>>npmci cloudflare ...<< action >>${action}<< not supported`);
process.exit(1);
}
} else {
plugins.beautylog.log(
`>>npmci cloudflare ...<< cli arguments invalid... Please read the documentation.`
);
process.exit(1);
}
};
export let purge = async argvArg => {
npmciCflare.auth({
email: '',
key: ''
});
npmciCflare.purgeZone(argvArg._[1]);
};

View File

@@ -1,5 +0,0 @@
export * from '../npmci.plugins';
import * as cflare from 'cflare';
export { cflare };

View File

@@ -1,3 +1,4 @@
import { logger } from '../npmci.logging';
import * as plugins from './mod.plugins'; import * as plugins from './mod.plugins';
import * as paths from '../npmci.paths'; import * as paths from '../npmci.paths';
import { bash } from '../npmci.bash'; import { bash } from '../npmci.bash';
@@ -10,7 +11,7 @@ import { DockerRegistry } from './mod.classes.dockerregistry';
import { RegistryStorage } from './mod.classes.registrystorage'; import { RegistryStorage } from './mod.classes.registrystorage';
// instances // instances
let npmciRegistryStorage = new RegistryStorage(); const npmciRegistryStorage = new RegistryStorage();
export { Dockerfile, helpers }; export { Dockerfile, helpers };
@@ -23,7 +24,7 @@ export let modArgvArg; // will be set through the build command
export let handleCli = async argvArg => { export let handleCli = async argvArg => {
modArgvArg = argvArg; modArgvArg = argvArg;
if (argvArg._.length >= 2) { if (argvArg._.length >= 2) {
let action: string = argvArg._[1]; const action: string = argvArg._[1];
switch (action) { switch (action) {
case 'build': case 'build':
await build(); await build();
@@ -42,10 +43,11 @@ export let handleCli = async argvArg => {
await pull(argvArg); await pull(argvArg);
break; break;
default: default:
plugins.beautylog.error(`>>npmci docker ...<< action >>${action}<< not supported`); logger.log('error', `>>npmci docker ...<< action >>${action}<< not supported`);
} }
} else { } else {
plugins.beautylog.log( logger.log(
'info',
`>>npmci docker ...<< cli arguments invalid... Please read the documentation.` `>>npmci docker ...<< cli arguments invalid... Please read the documentation.`
); );
} }
@@ -56,7 +58,7 @@ export let handleCli = async argvArg => {
*/ */
export let build = async () => { export let build = async () => {
await prepare(); await prepare();
plugins.beautylog.log('now building Dockerfiles...'); logger.log('info', 'now building Dockerfiles...');
await helpers await helpers
.readDockerfiles() .readDockerfiles()
.then(helpers.sortDockerfiles) .then(helpers.sortDockerfiles)
@@ -78,7 +80,7 @@ export let login = async () => {
export let prepare = async () => { export let prepare = async () => {
// Always login to GitLab Registry // Always login to GitLab Registry
if (!process.env.CI_BUILD_TOKEN || process.env.CI_BUILD_TOKEN === '') { if (!process.env.CI_BUILD_TOKEN || process.env.CI_BUILD_TOKEN === '') {
plugins.beautylog.error('No registry token specified by gitlab!'); logger.log('error', 'No registry token specified by gitlab!');
process.exit(1); process.exit(1);
} }
npmciRegistryStorage.addRegistry( npmciRegistryStorage.addRegistry(
@@ -98,40 +100,41 @@ export let prepare = async () => {
export let push = async argvArg => { export let push = async argvArg => {
await prepare(); await prepare();
let registryUrlArg = argvArg._[2]; const registryUrlArg = argvArg._[2];
let suffix = null; let suffix = null;
if (argvArg._.length >= 4) { if (argvArg._.length >= 4) {
suffix = argvArg._[3]; suffix = argvArg._[3];
} }
let dockerfileArray = await helpers const dockerfileArray = await helpers
.readDockerfiles() .readDockerfiles()
.then(helpers.sortDockerfiles) .then(helpers.sortDockerfiles)
.then(helpers.mapDockerfiles); .then(helpers.mapDockerfiles);
let localDockerRegistry = npmciRegistryStorage.getRegistryByUrl(registryUrlArg); const localDockerRegistry = npmciRegistryStorage.getRegistryByUrl(registryUrlArg);
if (!localDockerRegistry) { if (!localDockerRegistry) {
plugins.beautylog.error( logger.log(
'error',
`Cannot push to registry ${registryUrlArg}, because it was not found in the authenticated registry list.` `Cannot push to registry ${registryUrlArg}, because it was not found in the authenticated registry list.`
); );
process.exit(1); process.exit(1);
} }
for (let dockerfile of dockerfileArray) { for (const dockerfile of dockerfileArray) {
await dockerfile.push(localDockerRegistry, suffix); await dockerfile.push(localDockerRegistry, suffix);
} }
}; };
export let pull = async argvArg => { export let pull = async argvArg => {
await prepare(); await prepare();
let registryUrlArg = argvArg._[2]; const registryUrlArg = argvArg._[2];
let suffix = null; let suffix = null;
if (argvArg._.length >= 4) { if (argvArg._.length >= 4) {
suffix = argvArg._[3]; suffix = argvArg._[3];
} }
let localDockerRegistry = npmciRegistryStorage.getRegistryByUrl(registryUrlArg); const localDockerRegistry = npmciRegistryStorage.getRegistryByUrl(registryUrlArg);
let dockerfileArray = await helpers const dockerfileArray = await helpers
.readDockerfiles() .readDockerfiles()
.then(helpers.sortDockerfiles) .then(helpers.sortDockerfiles)
.then(helpers.mapDockerfiles); .then(helpers.mapDockerfiles);
for (let dockerfile of dockerfileArray) { for (const dockerfile of dockerfileArray) {
await dockerfile.pull(localDockerRegistry, suffix); await dockerfile.pull(localDockerRegistry, suffix);
} }
}; };

View File

@@ -1,3 +1,4 @@
import { logger } from '../npmci.logging';
import * as plugins from './mod.plugins'; import * as plugins from './mod.plugins';
import * as NpmciEnv from '../npmci.env'; import * as NpmciEnv from '../npmci.env';
import { bash } from '../npmci.bash'; import { bash } from '../npmci.bash';
@@ -10,16 +11,16 @@ import * as helpers from './mod.helpers';
* class Dockerfile represents a Dockerfile on disk in npmci * class Dockerfile represents a Dockerfile on disk in npmci
*/ */
export class Dockerfile { export class Dockerfile {
filePath: string; public filePath: string;
repo: string; public repo: string;
version: string; public version: string;
cleanTag: string; public cleanTag: string;
buildTag: string; public buildTag: string;
containerName: string; public containerName: string;
content: string; public content: string;
baseImage: string; public baseImage: string;
localBaseImageDependent: boolean; public localBaseImageDependent: boolean;
localBaseDockerfile: Dockerfile; public localBaseDockerfile: Dockerfile;
constructor(options: { filePath?: string; fileContents?: string | Buffer; read?: boolean }) { constructor(options: { filePath?: string; fileContents?: string | Buffer; read?: boolean }) {
this.filePath = options.filePath; this.filePath = options.filePath;
this.repo = NpmciEnv.repo.user + '/' + NpmciEnv.repo.repo; this.repo = NpmciEnv.repo.user + '/' + NpmciEnv.repo.repo;
@@ -38,10 +39,12 @@ export class Dockerfile {
/** /**
* builds the Dockerfile * builds the Dockerfile
*/ */
async build() { public async build() {
plugins.beautylog.info('now building Dockerfile for ' + this.cleanTag); logger.log('info', 'now building Dockerfile for ' + this.cleanTag);
let buildArgsString = await helpers.getDockerBuildArgs(); const buildArgsString = await helpers.getDockerBuildArgs();
let buildCommand = `docker build -t ${this.buildTag} -f ${this.filePath} ${buildArgsString} .`; const buildCommand = `docker build -t ${this.buildTag} -f ${
this.filePath
} ${buildArgsString} .`;
await bash(buildCommand); await bash(buildCommand);
return; return;
} }
@@ -49,8 +52,8 @@ export class Dockerfile {
/** /**
* pushes the Dockerfile to a registry * pushes the Dockerfile to a registry
*/ */
async push(dockerRegistryArg: DockerRegistry, versionSuffix: string = null) { public async push(dockerRegistryArg: DockerRegistry, versionSuffix: string = null) {
let pushTag = helpers.getDockerTagString( const pushTag = helpers.getDockerTagString(
dockerRegistryArg.registryUrl, dockerRegistryArg.registryUrl,
this.repo, this.repo,
this.version, this.version,
@@ -63,8 +66,8 @@ export class Dockerfile {
/** /**
* pulls the Dockerfile from a registry * pulls the Dockerfile from a registry
*/ */
async pull(registryArg: DockerRegistry, versionSuffixArg: string = null) { public async pull(registryArg: DockerRegistry, versionSuffixArg: string = null) {
let pullTag = helpers.getDockerTagString( const pullTag = helpers.getDockerTagString(
registryArg.registryUrl, registryArg.registryUrl,
this.repo, this.repo,
this.version, this.version,
@@ -77,9 +80,9 @@ export class Dockerfile {
/** /**
* tests the Dockerfile; * tests the Dockerfile;
*/ */
async test() { public async test() {
let testFile: string = plugins.path.join(paths.NpmciTestDir, 'test_' + this.version + '.sh'); const testFile: string = plugins.path.join(paths.NpmciTestDir, 'test_' + this.version + '.sh');
let testFileExists: boolean = plugins.smartfile.fs.fileExistsSync(testFile); const testFileExists: boolean = plugins.smartfile.fs.fileExistsSync(testFile);
if (testFileExists) { if (testFileExists) {
// run tests // run tests
await bash( await bash(
@@ -93,17 +96,17 @@ export class Dockerfile {
await bash(`docker rm npmci_test_container`); await bash(`docker rm npmci_test_container`);
await bash(`docker rmi --force npmci_test_image`); await bash(`docker rmi --force npmci_test_image`);
} else { } else {
plugins.beautylog.warn( logger.log('warn', 'skipping tests for ' + this.cleanTag + ' because no testfile was found!');
'skipping tests for ' + this.cleanTag + ' because no testfile was found!'
);
} }
} }
/** /**
* gets the id of a Dockerfile * gets the id of a Dockerfile
*/ */
async getId() { public async getId() {
let containerId = await bash('docker inspect --type=image --format="{{.Id}}" ' + this.buildTag); const containerId = await bash(
'docker inspect --type=image --format="{{.Id}}" ' + this.buildTag
);
return containerId; return containerId;
} }
} }

View File

@@ -1,3 +1,4 @@
import { logger } from '../npmci.logging';
import * as plugins from './mod.plugins'; import * as plugins from './mod.plugins';
import { bash } from '../npmci.bash'; import { bash } from '../npmci.bash';
@@ -8,26 +9,26 @@ export interface IDockerRegistryConstructorOptions {
} }
export class DockerRegistry { export class DockerRegistry {
registryUrl: string; public registryUrl: string;
username: string; public username: string;
password: string; public password: string;
constructor(optionsArg: IDockerRegistryConstructorOptions) { constructor(optionsArg: IDockerRegistryConstructorOptions) {
this.registryUrl = optionsArg.registryUrl; this.registryUrl = optionsArg.registryUrl;
this.username = optionsArg.username; this.username = optionsArg.username;
this.password = optionsArg.password; this.password = optionsArg.password;
plugins.beautylog.info(`created DockerRegistry for ${this.registryUrl}`); logger.log('info', `created DockerRegistry for ${this.registryUrl}`);
} }
static fromEnvString(envString: string): DockerRegistry { public static fromEnvString(envString: string): DockerRegistry {
let dockerRegexResultArray = envString.split('|'); const dockerRegexResultArray = envString.split('|');
if (dockerRegexResultArray.length !== 3) { if (dockerRegexResultArray.length !== 3) {
plugins.beautylog.error('malformed docker env var...'); logger.log('error', 'malformed docker env var...');
process.exit(1); process.exit(1);
return; return;
} }
let registryUrl = dockerRegexResultArray[0]; const registryUrl = dockerRegexResultArray[0];
let username = dockerRegexResultArray[1]; const username = dockerRegexResultArray[1];
let password = dockerRegexResultArray[2]; const password = dockerRegexResultArray[2];
return new DockerRegistry({ return new DockerRegistry({
registryUrl: registryUrl, registryUrl: registryUrl,
username: username, username: username,
@@ -35,13 +36,13 @@ export class DockerRegistry {
}); });
} }
async login() { public async login() {
if (this.registryUrl === 'docker.io') { if (this.registryUrl === 'docker.io') {
await bash(`docker login -u ${this.username} -p ${this.password}`); await bash(`docker login -u ${this.username} -p ${this.password}`);
plugins.beautylog.info('Logged in to standard docker hub'); logger.log('info', 'Logged in to standard docker hub');
} else { } else {
await bash(`docker login -u ${this.username} -p ${this.password} ${this.registryUrl}`); await bash(`docker login -u ${this.username} -p ${this.password} ${this.registryUrl}`);
} }
plugins.beautylog.ok(`docker authenticated for ${this.registryUrl}!`); logger.log('ok', `docker authenticated for ${this.registryUrl}!`);
} }
} }

View File

@@ -1,5 +1,6 @@
import { logger } from '../npmci.logging';
import * as plugins from './mod.plugins'; import * as plugins from './mod.plugins';
import { Objectmap } from 'lik'; import { Objectmap } from '@pushrocks/lik';
import { DockerRegistry } from './mod.classes.dockerregistry'; import { DockerRegistry } from './mod.classes.dockerregistry';
@@ -23,6 +24,6 @@ export class RegistryStorage {
await this.objectMap.forEach(async registryArg => { await this.objectMap.forEach(async registryArg => {
await registryArg.login(); await registryArg.login();
}); });
plugins.beautylog.success('logged in successfully into all available DockerRegistries!'); logger.log('success', 'logged in successfully into all available DockerRegistries!');
} }
} }

View File

@@ -1,3 +1,4 @@
import { logger } from '../npmci.logging';
import * as plugins from './mod.plugins'; import * as plugins from './mod.plugins';
import * as paths from '../npmci.paths'; import * as paths from '../npmci.paths';
import * as NpmciEnv from '../npmci.env'; import * as NpmciEnv from '../npmci.env';
@@ -11,14 +12,14 @@ import { Dockerfile } from './mod.classes.dockerfile';
* @returns Promise<Dockerfile[]> * @returns Promise<Dockerfile[]>
*/ */
export let readDockerfiles = async (): Promise<Dockerfile[]> => { export let readDockerfiles = async (): Promise<Dockerfile[]> => {
let fileTree = await plugins.smartfile.fs.listFileTree(paths.cwd, 'Dockerfile*'); const fileTree = await plugins.smartfile.fs.listFileTree(paths.cwd, 'Dockerfile*');
// create the Dockerfile array // create the Dockerfile array
let readDockerfilesArray: Dockerfile[] = []; const readDockerfilesArray: Dockerfile[] = [];
plugins.beautylog.info(`found ${fileTree.length} Dockerfiles:`); logger.log('info', `found ${fileTree.length} Dockerfiles:`);
console.log(fileTree); console.log(fileTree);
for (let dockerfilePath of fileTree) { for (const dockerfilePath of fileTree) {
let myDockerfile = new Dockerfile({ const myDockerfile = new Dockerfile({
filePath: dockerfilePath, filePath: dockerfilePath,
read: true read: true
}); });
@@ -34,14 +35,14 @@ export let readDockerfiles = async (): Promise<Dockerfile[]> => {
* @returns Promise<Dockerfile[]> * @returns Promise<Dockerfile[]>
*/ */
export let sortDockerfiles = (sortableArrayArg: Dockerfile[]): Promise<Dockerfile[]> => { export let sortDockerfiles = (sortableArrayArg: Dockerfile[]): Promise<Dockerfile[]> => {
let done = plugins.q.defer<Dockerfile[]>(); const done = plugins.smartpromise.defer<Dockerfile[]>();
plugins.beautylog.info('sorting Dockerfiles:'); logger.log('info', 'sorting Dockerfiles:');
let sortedArray: Dockerfile[] = []; const sortedArray: Dockerfile[] = [];
let cleanTagsOriginal = cleanTagsArrayFunction(sortableArrayArg, sortedArray); const cleanTagsOriginal = cleanTagsArrayFunction(sortableArrayArg, sortedArray);
let sorterFunctionCounter: number = 0; let sorterFunctionCounter: number = 0;
let sorterFunction = function() { const sorterFunction = () => {
sortableArrayArg.forEach(dockerfileArg => { sortableArrayArg.forEach(dockerfileArg => {
let cleanTags = cleanTagsArrayFunction(sortableArrayArg, sortedArray); const cleanTags = cleanTagsArrayFunction(sortableArrayArg, sortedArray);
if ( if (
cleanTags.indexOf(dockerfileArg.baseImage) === -1 && cleanTags.indexOf(dockerfileArg.baseImage) === -1 &&
sortedArray.indexOf(dockerfileArg) === -1 sortedArray.indexOf(dockerfileArg) === -1
@@ -54,8 +55,8 @@ export let sortDockerfiles = (sortableArrayArg: Dockerfile[]): Promise<Dockerfil
}); });
if (sortableArrayArg.length === sortedArray.length) { if (sortableArrayArg.length === sortedArray.length) {
let counter = 1; let counter = 1;
for (let dockerfile of sortedArray) { for (const dockerfile of sortedArray) {
plugins.beautylog.log(`tag ${counter}: -> ${dockerfile.cleanTag}`); logger.log('info', `tag ${counter}: -> ${dockerfile.cleanTag}`);
counter++; counter++;
} }
done.resolve(sortedArray); done.resolve(sortedArray);
@@ -88,7 +89,7 @@ export let mapDockerfiles = async (sortedArray: Dockerfile[]): Promise<Dockerfil
* builds the correspoding real docker image for each Dockerfile class instance * builds the correspoding real docker image for each Dockerfile class instance
*/ */
export let buildDockerfiles = async (sortedArrayArg: Dockerfile[]) => { export let buildDockerfiles = async (sortedArrayArg: Dockerfile[]) => {
for (let dockerfileArg of sortedArrayArg) { for (const dockerfileArg of sortedArrayArg) {
await dockerfileArg.build(); await dockerfileArg.build();
} }
return sortedArrayArg; return sortedArrayArg;
@@ -99,7 +100,7 @@ export let buildDockerfiles = async (sortedArrayArg: Dockerfile[]) => {
* @param sortedArrayArg Dockerfile[] that contains all Dockerfiles in cwd * @param sortedArrayArg Dockerfile[] that contains all Dockerfiles in cwd
*/ */
export let testDockerfiles = async (sortedArrayArg: Dockerfile[]) => { export let testDockerfiles = async (sortedArrayArg: Dockerfile[]) => {
for (let dockerfileArg of sortedArrayArg) { for (const dockerfileArg of sortedArrayArg) {
await dockerfileArg.test(); await dockerfileArg.test();
} }
return sortedArrayArg; return sortedArrayArg;
@@ -111,8 +112,8 @@ export let testDockerfiles = async (sortedArrayArg: Dockerfile[]) => {
*/ */
export let dockerFileVersion = (dockerfileNameArg: string): string => { export let dockerFileVersion = (dockerfileNameArg: string): string => {
let versionString: string; let versionString: string;
let versionRegex = /Dockerfile_([a-zA-Z0-9\.]*)$/; const versionRegex = /Dockerfile_([a-zA-Z0-9\.]*)$/;
let regexResultArray = versionRegex.exec(dockerfileNameArg); const regexResultArray = versionRegex.exec(dockerfileNameArg);
if (regexResultArray && regexResultArray.length === 2) { if (regexResultArray && regexResultArray.length === 2) {
versionString = regexResultArray[1]; versionString = regexResultArray[1];
} else { } else {
@@ -124,9 +125,9 @@ export let dockerFileVersion = (dockerfileNameArg: string): string => {
/** /**
* returns the docker base image for a Dockerfile * returns the docker base image for a Dockerfile
*/ */
export let dockerBaseImage = function(dockerfileContentArg: string) { export let dockerBaseImage = (dockerfileContentArg: string) => {
let baseImageRegex = /FROM\s([a-zA-z0-9\/\-\:]*)\n?/; const baseImageRegex = /FROM\s([a-zA-z0-9\/\-\:]*)\n?/;
let regexResultArray = baseImageRegex.exec(dockerfileContentArg); const regexResultArray = baseImageRegex.exec(dockerfileContentArg);
return regexResultArray[1]; return regexResultArray[1];
}; };
@@ -140,8 +141,8 @@ export let getDockerTagString = (
suffixArg?: string suffixArg?: string
): string => { ): string => {
// determine wether the repo should be mapped accordingly to the registry // determine wether the repo should be mapped accordingly to the registry
let mappedRepo = NpmciConfig.configObject.dockerRegistryRepoMap[registryArg]; const mappedRepo = NpmciConfig.configObject.dockerRegistryRepoMap[registryArg];
let repo = (() => { const repo = (() => {
if (mappedRepo) { if (mappedRepo) {
return mappedRepo; return mappedRepo;
} else { } else {
@@ -155,16 +156,16 @@ export let getDockerTagString = (
version = versionArg + '_' + suffixArg; version = versionArg + '_' + suffixArg;
} }
let tagString = `${registryArg}/${repo}:${version}`; const tagString = `${registryArg}/${repo}:${version}`;
return tagString; return tagString;
}; };
export let getDockerBuildArgs = async (): Promise<string> => { export let getDockerBuildArgs = async (): Promise<string> => {
plugins.beautylog.info('checking for env vars to be supplied to the docker build'); logger.log('info', 'checking for env vars to be supplied to the docker build');
let buildArgsString: string = ''; let buildArgsString: string = '';
for (let key in NpmciConfig.configObject.dockerBuildargEnvMap) { for (const key in NpmciConfig.configObject.dockerBuildargEnvMap) {
let targetValue = process.env[NpmciConfig.configObject.dockerBuildargEnvMap[key]]; const targetValue = process.env[NpmciConfig.configObject.dockerBuildargEnvMap[key]];
buildArgsString = `${buildArgsString} --build-arg ${key}=${targetValue}`; buildArgsString = `${buildArgsString} --build-arg ${key}="${targetValue}"`;
} }
return buildArgsString; return buildArgsString;
}; };
@@ -172,12 +173,12 @@ export let getDockerBuildArgs = async (): Promise<string> => {
/** /**
* *
*/ */
export let cleanTagsArrayFunction = function( export let cleanTagsArrayFunction = (
dockerfileArrayArg: Dockerfile[], dockerfileArrayArg: Dockerfile[],
trackingArrayArg: Dockerfile[] trackingArrayArg: Dockerfile[]
): string[] { ): string[] => {
let cleanTagsArray: string[] = []; const cleanTagsArray: string[] = [];
dockerfileArrayArg.forEach(function(dockerfileArg) { dockerfileArrayArg.forEach(dockerfileArg => {
if (trackingArrayArg.indexOf(dockerfileArg) === -1) { if (trackingArrayArg.indexOf(dockerfileArg) === -1) {
cleanTagsArray.push(dockerfileArg.cleanTag); cleanTagsArray.push(dockerfileArg.cleanTag);
} }

View File

@@ -1,45 +1,56 @@
import { logger } from '../npmci.logging';
import * as plugins from './mod.plugins'; import * as plugins from './mod.plugins';
import { bash } from '../npmci.bash'; import { bash } from '../npmci.bash';
import { repo } from '../npmci.env'; import { repo } from '../npmci.env';
import { configObject } from '../npmci.config';
/** /**
* handle cli input * handle cli input
* @param argvArg * @param argvArg
*/ */
export let handleCli = async argvArg => { export let handleCli = async argvArg => {
if (argvArg._.length >= 2) { if (argvArg._.length >= 2) {
let action: string = argvArg._[1]; const action: string = argvArg._[1];
switch (action) { switch (action) {
case 'mirror': case 'mirror':
await mirror(); await mirror();
break; break;
default: default:
plugins.beautylog.error(`>>npmci git ...<< action >>${action}<< not supported`); logger.log('error', `npmci git -> action >>${action}<< not supported!`);
} }
} else { } else {
plugins.beautylog.log( logger.log('info', `npmci git -> cli arguments invalid! Please read the documentation.`);
`>>npmci git ...<< cli arguments invalid... Please read the documentation.`
);
} }
}; };
export let mirror = async () => { export let mirror = async () => {
let githubToken = process.env.NPMCI_GIT_GITHUBTOKEN; const githubToken = process.env.NPMCI_GIT_GITHUBTOKEN;
let githubUser = process.env.NPMCI_GIT_GITHUBGROUP || repo.user; const githubUser = process.env.NPMCI_GIT_GITHUBGROUP || repo.user;
let githubRepo = process.env.NPMCI_GIT_GITHUB || repo.repo; 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) { if (githubToken) {
plugins.beautylog.info('found github token.'); logger.log('info', 'found github token.');
plugins.beautylog.log('attempting the mirror the repository to GitHub'); logger.log('info', 'attempting the mirror the repository to GitHub');
// add the mirror // add the mirror
await bash( await bash(
`git remote add mirror https://${githubToken}@github.com/${githubUser}/${githubRepo}.git` `git remote add mirror https://${githubToken}@github.com/${githubUser}/${githubRepo}.git`
); );
await bash(`git push mirror --all`); await bash(`git push mirror --all`);
plugins.beautylog.ok('pushed all branches to mirror!'); logger.log('ok', 'pushed all branches to mirror!');
await bash(`git push mirror --tags`); await bash(`git push mirror --tags`);
plugins.beautylog.ok('pushed all tags to mirror!'); logger.log('ok', 'pushed all tags to mirror!');
} else { } else {
plugins.beautylog.error(`cannot find NPMCI_GIT_GITHUBTOKEN env var!`); logger.log('error', `cannot find NPMCI_GIT_GITHUBTOKEN env var!`);
process.exit(1); process.exit(1);
} }
}; };

View File

@@ -1,6 +1,8 @@
import { logger } from '../npmci.logging';
import * as plugins from '../npmci.plugins'; import * as plugins from '../npmci.plugins';
import * as paths from '../npmci.paths';
import * as npmciConfig from '../npmci.config'; import * as npmciConfig from '../npmci.config';
import { bash, bashNoError, nvmAvailable, yarnAvailable } from '../npmci.bash'; import { bash, bashNoError, nvmAvailable } from '../npmci.bash';
/** /**
* handle cli input * handle cli input
@@ -8,17 +10,18 @@ import { bash, bashNoError, nvmAvailable, yarnAvailable } from '../npmci.bash';
*/ */
export let handleCli = async argvArg => { export let handleCli = async argvArg => {
if (argvArg._.length >= 3) { if (argvArg._.length >= 3) {
let action: string = argvArg._[1]; const action: string = argvArg._[1];
switch (action) { switch (action) {
case 'install': case 'install':
await install(argvArg._[2]); await install(argvArg._[2]);
break; break;
default: default:
plugins.beautylog.error(`>>npmci node ...<< action >>${action}<< not supported`); logger.log('error', `>>npmci node ...<< action >>${action}<< not supported`);
process.exit(1); process.exit(1);
} }
} else { } else {
plugins.beautylog.error( logger.log(
'error',
`>>npmci node ...<< cli arguments invalid... Please read the documentation.` `>>npmci node ...<< cli arguments invalid... Please read the documentation.`
); );
process.exit(1); process.exit(1);
@@ -30,12 +33,12 @@ export let handleCli = async argvArg => {
* @param versionArg * @param versionArg
*/ */
export let install = async versionArg => { export let install = async versionArg => {
plugins.beautylog.log(`now installing node version ${versionArg}`); logger.log('info', `now installing node version ${versionArg}`);
let version: string; let version: string;
if (versionArg === 'stable') { if (versionArg === 'stable') {
version = '9'; version = '11';
} else if (versionArg === 'lts') { } else if (versionArg === 'lts') {
version = '8'; version = '10';
} else if (versionArg === 'legacy') { } else if (versionArg === 'legacy') {
version = '8'; version = '8';
} else { } else {
@@ -43,30 +46,27 @@ export let install = async versionArg => {
} }
if (await nvmAvailable.promise) { if (await nvmAvailable.promise) {
await bash(`nvm install ${version} && nvm alias default ${version}`); await bash(`nvm install ${version} && nvm alias default ${version}`);
plugins.beautylog.success(`Node version ${version} successfully installed!`); logger.log('success', `Node version ${version} successfully installed!`);
} else { } else {
plugins.beautylog.warn('Nvm not in path so staying at installed node version!'); logger.log('warn', 'Nvm not in path so staying at installed node version!');
} }
await bash('node -v'); await bash('node -v');
await bash('npm -v'); await bash('npm -v');
await bash(`npm config set cache ${paths.NpmciCacheDir} --global `);
// lets look for further config // lets look for further config
await npmciConfig.getConfig().then(async configArg => { await npmciConfig.getConfig().then(async configArg => {
plugins.beautylog.log('Now checking for needed global npm tools...'); logger.log('info', 'Now checking for needed global npm tools...');
for (let npmTool of configArg.npmGlobalTools) { for (const npmTool of configArg.npmGlobalTools) {
plugins.beautylog.info(`Checking for global "${npmTool}"`); logger.log('info', `Checking for global "${npmTool}"`);
let whichOutput: string = await bashNoError(`which ${npmTool}`); const whichOutput: string = await bashNoError(`which ${npmTool}`);
let toolAvailable: boolean = !(/not\sfound/.test(whichOutput) || whichOutput === ''); const toolAvailable: boolean = !(/not\sfound/.test(whichOutput) || whichOutput === '');
if (toolAvailable) { if (toolAvailable) {
plugins.beautylog.log(`Tool ${npmTool} is available`); logger.log('info', `Tool ${npmTool} is available`);
} else {
plugins.beautylog.info(`globally installing ${npmTool} from npm`);
if (await yarnAvailable.promise) {
await bash(`yarn global add ${npmTool}`);
} else { } else {
logger.log('info', `globally installing ${npmTool} from npm`);
await bash(`npm install ${npmTool} -q -g`); await bash(`npm install ${npmTool} -q -g`);
} }
} }
} logger.log('success', 'all global npm tools specified in npmextra.json are now available!');
plugins.beautylog.success('all global npm tools specified in npmextra.json are now available!');
}); });
}; };

View File

@@ -1,6 +1,7 @@
import { logger } from '../npmci.logging';
import * as plugins from './mod.plugins'; import * as plugins from './mod.plugins';
import * as configModule from '../npmci.config'; import * as configModule from '../npmci.config';
import { bash, bashNoError, nvmAvailable, yarnAvailable } from '../npmci.bash'; import { bash, bashNoError, nvmAvailable } from '../npmci.bash';
/** /**
* handle cli input * handle cli input
@@ -8,7 +9,7 @@ import { bash, bashNoError, nvmAvailable, yarnAvailable } from '../npmci.bash';
*/ */
export let handleCli = async argvArg => { export let handleCli = async argvArg => {
if (argvArg._.length >= 2) { if (argvArg._.length >= 2) {
let action: string = argvArg._[1]; const action: string = argvArg._[1];
switch (action) { switch (action) {
case 'install': case 'install':
await install(); await install();
@@ -23,13 +24,11 @@ export let handleCli = async argvArg => {
await publish(); await publish();
break; break;
default: default:
plugins.beautylog.error(`>>npmci npm ...<< action >>${action}<< not supported`); logger.log('error', `>>npmci npm ...<< action >>${action}<< not supported`);
process.exit(1); process.exit(1);
} }
} else { } else {
plugins.beautylog.log( logger.log('info', `>>npmci npm ...<< cli arguments invalid... Please read the documentation.`);
`>>npmci npm ...<< cli arguments invalid... Please read the documentation.`
);
process.exit(1); process.exit(1);
} }
}; };
@@ -37,16 +36,28 @@ export let handleCli = async argvArg => {
/** /**
* authenticates npm with token from env var * authenticates npm with token from env var
*/ */
let prepare = async () => { const prepare = async () => {
let npmrcPrefix: string = '//registry.npmjs.org/:_authToken='; const config = await configModule.getConfig();
let npmToken: string = process.env.NPMCI_TOKEN_NPM; let npmrcFileString: string = '';
let npmrcFileString: string = npmrcPrefix + npmToken; await plugins.smartparam.forEachMinimatch(process.env, 'NPMCI_TOKEN_NPM*', npmEnvArg => {
if (npmToken) { const npmRegistryUrl = npmEnvArg.split('|')[0];
plugins.beautylog.info('found access token'); 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 { } else {
plugins.beautylog.error('no access token found! Exiting!'); logger.log('error', 'no access token found! Exiting!');
process.exit(1); process.exit(1);
} }
// lets save it to disk
plugins.smartfile.memory.toFsSync(npmrcFileString, '/root/.npmrc'); plugins.smartfile.memory.toFsSync(npmrcFileString, '/root/.npmrc');
return; return;
}; };
@@ -54,8 +65,9 @@ let prepare = async () => {
/** /**
* publish a package to npm * publish a package to npm
*/ */
let publish = async () => { const publish = async () => {
let npmAccessCliString = ``; let npmAccessCliString = ``;
let npmRegistryCliString = ``;
const config = await configModule.getConfig(); const config = await configModule.getConfig();
// -> configure package access level // -> configure package access level
@@ -66,24 +78,43 @@ let publish = async () => {
npmAccessCliString = `--access=${config.npmAccessLevel}`; npmAccessCliString = `--access=${config.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);
}
// -> preparing
logger.log('info', `now preparing environment:`);
prepare();
await bash(`npm -v`);
// -> build it // -> build it
await bash(`yarn install`); await bash(`npm install`);
await bash(`yarn run build`); 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 // -> publish it
await bash(`npm publish ${npmAccessCliString}`); logger.log('info', `now invoking npm to publish the package!`);
await bash(`npm publish ${npmAccessCliString} ${npmRegistryCliString}`);
logger.log('success', `Package was successfully published!`);
}; };
let install = async (): Promise<void> => { const install = async (): Promise<void> => {
plugins.beautylog.info('now installing dependencies:'); logger.log('info', 'now installing dependencies:');
if (await yarnAvailable.promise) {
await bash('yarn install');
} else {
await bash('npm install'); await bash('npm install');
}
}; };
export let test = async (): Promise<void> => { export let test = async (): Promise<void> => {
plugins.beautylog.info('now starting tests:'); logger.log('info', 'now starting tests:');
await bash('yarn test'); await bash('npm test');
}; };

View File

@@ -1,19 +1,20 @@
import { logger } from '../npmci.logging';
import * as plugins from './mod.plugins'; import * as plugins from './mod.plugins';
let sshInstance: plugins.smartssh.SshInstance; let sshInstance: plugins.smartssh.SshInstance;
export let handleCli = async argvArg => { export let handleCli = async argvArg => {
if (argvArg._.length >= 2) { if (argvArg._.length >= 2) {
let action: string = argvArg._[1]; const action: string = argvArg._[1];
switch (action) { switch (action) {
case 'prepare': case 'prepare':
await prepare(); await prepare();
break; break;
default: default:
plugins.beautylog.error(`action >>${action}<< not supported`); logger.log('error', `action >>${action}<< not supported`);
process.exit(1); process.exit(1);
} }
} else { } else {
plugins.beautylog.error(`>>npmci ssh ...<< please specify an action!`); logger.log('error', `>>npmci ssh ...<< please specify an action!`);
process.exit(1); process.exit(1);
} }
}; };
@@ -21,7 +22,7 @@ export let handleCli = async argvArg => {
/** /**
* checks if not undefined * checks if not undefined
*/ */
let notUndefined = (stringArg: string) => { const notUndefined = (stringArg: string) => {
return stringArg && stringArg !== 'undefined' && stringArg !== '##'; return stringArg && stringArg !== 'undefined' && stringArg !== '##';
}; };
@@ -34,27 +35,27 @@ export let prepare = async () => {
if (!process.env.NPMTS_TEST) { if (!process.env.NPMTS_TEST) {
sshInstance.writeToDisk(); sshInstance.writeToDisk();
} else { } else {
plugins.beautylog.log('In test mode, so not storing SSH keys to disk!'); logger.log('info', 'In test mode, so not storing SSH keys to disk!');
} }
}; };
/** /**
* gets called for each found SSH ENV Var and deploys it * gets called for each found SSH ENV Var and deploys it
*/ */
let evaluateSshEnv = async (sshkeyEnvVarArg: string) => { const evaluateSshEnv = async (sshkeyEnvVarArg: string) => {
let sshEnvArray = sshkeyEnvVarArg.split('|'); const sshEnvArray = sshkeyEnvVarArg.split('|');
let sshKey = new plugins.smartssh.SshKey(); const sshKey = new plugins.smartssh.SshKey();
plugins.beautylog.info('Found SSH identity for ' + sshEnvArray[1]); logger.log('info', 'Found SSH identity for ' + sshEnvArray[1]);
if (notUndefined(sshEnvArray[0])) { if (notUndefined(sshEnvArray[0])) {
plugins.beautylog.log('---> host defined!'); logger.log('info', '---> host defined!');
sshKey.host = sshEnvArray[0]; sshKey.host = sshEnvArray[0];
} }
if (notUndefined(sshEnvArray[1])) { if (notUndefined(sshEnvArray[1])) {
plugins.beautylog.log('---> privKey defined!'); logger.log('info', '---> privKey defined!');
sshKey.privKeyBase64 = sshEnvArray[1]; sshKey.privKeyBase64 = sshEnvArray[1];
} }
if (notUndefined(sshEnvArray[2])) { if (notUndefined(sshEnvArray[2])) {
plugins.beautylog.log('---> pubKey defined!'); logger.log('info', '---> pubKey defined!');
sshKey.pubKeyBase64 = sshEnvArray[2]; sshKey.pubKeyBase64 = sshEnvArray[2];
} }

View File

@@ -1,28 +1,42 @@
import * as plugins from './mod.plugins'; import * as plugins from './mod.plugins';
import { bash } from '../npmci.bash'; import { bash } from '../npmci.bash';
import { logger } from '../npmci.logging';
let triggerValueRegex = /^([a-zA-Z0-9\.]*)\|([a-zA-Z0-9\.]*)\|([a-zA-Z0-9\.]*)\|([a-zA-Z0-9\.]*)\|?([a-zA-Z0-9\.\-\/]*)/; const triggerValueRegex = /^([a-zA-Z0-9\.]*)\|([a-zA-Z0-9\.]*)\|([a-zA-Z0-9\.]*)\|([a-zA-Z0-9\.]*)\|?([a-zA-Z0-9\.\-\/]*)/;
export let trigger = async () => { export let trigger = async () => {
plugins.beautylog.info('now running triggers'); logger.log('info', 'now running triggers');
plugins.smartparam.forEachMinimatch(process.env, 'NPMCI_TRIGGER_*', evaluateTrigger); await plugins.smartparam.forEachMinimatch(process.env, 'NPMCI_TRIGGER_*', evaluateTrigger);
}; };
let evaluateTrigger = async triggerEnvVarArg => { const evaluateTrigger = async triggerEnvVarArg => {
let triggerRegexResultArray = triggerValueRegex.exec(triggerEnvVarArg); const triggerRegexResultArray = triggerValueRegex.exec(triggerEnvVarArg);
let regexDomain = triggerRegexResultArray[1]; const regexDomain = triggerRegexResultArray[1];
let regexProjectId = triggerRegexResultArray[2]; const regexProjectId = triggerRegexResultArray[2];
let regexProjectTriggerToken = triggerRegexResultArray[3]; const regexProjectTriggerToken = triggerRegexResultArray[3];
let regexRefName = triggerRegexResultArray[4]; const regexRefName = triggerRegexResultArray[4];
let regexTriggerName; let regexTriggerName;
if (triggerRegexResultArray.length === 6) { if (triggerRegexResultArray.length === 6) {
regexTriggerName = triggerRegexResultArray[5]; regexTriggerName = triggerRegexResultArray[5];
} else { } else {
regexTriggerName = 'Unnamed Trigger'; regexTriggerName = 'Unnamed Trigger';
} }
plugins.beautylog.info('Found Trigger!'); logger.log('info', 'Found Trigger!');
plugins.beautylog.log('triggering build for ref ' + regexRefName + ' of ' + regexTriggerName); logger.log('info', 'triggering build for ref ' + regexRefName + ' of ' + regexTriggerName);
plugins.request.post('https://gitlab.com/api/v3/projects/' + regexProjectId + '/trigger/builds', { plugins.smartrequest.postFormData(
form: { token: regexProjectTriggerToken, ref: regexRefName } 'https://gitlab.com/api/v3/projects/' + regexProjectId + '/trigger/builds',
}); {},
[
{
name: 'token',
payload: regexProjectTriggerToken,
type: 'string'
},
{
name: 'ref',
payload: regexRefName,
type: 'string'
}
]
);
}; };

View File

@@ -1,17 +1,17 @@
import { logger } from './npmci.logging';
import * as plugins from './npmci.plugins'; import * as plugins from './npmci.plugins';
import * as paths from './npmci.paths'; import * as paths from './npmci.paths';
import * as smartq from 'smartq'; import * as smartpromise from '@pushrocks/smartpromise';
/** /**
* wether nvm is available or not * wether nvm is available or not
*/ */
export let nvmAvailable = smartq.defer<boolean>(); export let nvmAvailable = smartpromise.defer<boolean>();
export let yarnAvailable = smartq.defer<boolean>();
/** /**
* the smartshell instance for npmci * the smartshell instance for npmci
*/ */
let npmciSmartshell = new plugins.smartshell.Smartshell({ const npmciSmartshell = new plugins.smartshell.Smartshell({
executor: 'bash', executor: 'bash',
sourceFilePaths: [] sourceFilePaths: []
}); });
@@ -19,38 +19,24 @@ let npmciSmartshell = new plugins.smartshell.Smartshell({
/** /**
* check for tools. * check for tools.
*/ */
let checkToolsAvailable = async () => { const checkToolsAvailable = async () => {
// check for nvm // check for nvm
if (!process.env.NPMTS_TEST) { if (!process.env.NPMTS_TEST) {
if ( if (
(await plugins.smartshell.execSilent(`bash -c "source /usr/local/nvm/nvm.sh"`)).exitCode === 0 (await npmciSmartshell.execSilent(`bash -c "source /usr/local/nvm/nvm.sh"`)).exitCode === 0
) { ) {
npmciSmartshell.addSourceFiles([`/usr/local/nvm/nvm.sh`]); npmciSmartshell.shellEnv.addSourceFiles([`/usr/local/nvm/nvm.sh`]);
nvmAvailable.resolve(true); nvmAvailable.resolve(true);
} else if ( } else if (
(await plugins.smartshell.execSilent(`bash -c "source ~/.nvm/nvm.sh"`)).exitCode === 0 (await npmciSmartshell.execSilent(`bash -c "source ~/.nvm/nvm.sh"`)).exitCode === 0
) { ) {
npmciSmartshell.addSourceFiles([`~/.nvm/nvm.sh`]); npmciSmartshell.shellEnv.addSourceFiles([`~/.nvm/nvm.sh`]);
nvmAvailable.resolve(true); nvmAvailable.resolve(true);
} else { } else {
nvmAvailable.resolve(false); nvmAvailable.resolve(false);
} }
// check for yarn
await plugins.smartshell.which('yarn').then(
async () => {
await plugins.smartshell.exec(
`yarn config set cache-folder ${plugins.path.join(paths.cwd, '.yarn')}`
);
yarnAvailable.resolve(true);
},
() => {
yarnAvailable.resolve(false);
}
);
} else { } else {
nvmAvailable.resolve(true); nvmAvailable.resolve(true);
yarnAvailable.resolve(true);
} }
}; };
checkToolsAvailable(); checkToolsAvailable();
@@ -83,21 +69,19 @@ export let bash = async (commandArg: string, retryArg: number = 2): Promise<stri
if (execResult.exitCode !== 0 && i === retryArg) { if (execResult.exitCode !== 0 && i === retryArg) {
// something went wrong and retries are exhausted // something went wrong and retries are exhausted
if (failOnError) { if (failOnError) {
plugins.beautylog.error('something went wrong and retries are exhausted'); logger.log('error', 'something went wrong and retries are exhausted');
process.exit(1); process.exit(1);
} }
} else if (execResult.exitCode === 0) { } else if (execResult.exitCode === 0) {
// everything went fine, or no error wanted // everything went fine, or no error wanted
i = retryArg + 1; // retry +1 breaks for loop, if everything works out ok retrials are not wanted i = retryArg + 1; // retry +1 breaks for loop, if everything works out ok retrials are not wanted
} else { } else {
plugins.beautylog.warn( logger.log('warn', 'Something went wrong! Exit Code: ' + execResult.exitCode.toString());
'Something went wrong! Exit Code: ' + execResult.exitCode.toString() logger.log('info', 'Retry ' + (i + 1).toString() + ' of ' + retryArg.toString());
);
plugins.beautylog.info('Retry ' + (i + 1).toString() + ' of ' + retryArg.toString());
} }
} }
} else { } else {
plugins.beautylog.log('ShellExec would be: ' + commandArg); logger.log('info', 'ShellExec would be: ' + commandArg);
execResult = { execResult = {
exitCode: 0, exitCode: 0,
stdout: 'testOutput' stdout: 'testOutput'

View File

@@ -1,122 +1,111 @@
import { logger } from './npmci.logging';
import * as plugins from './npmci.plugins'; import * as plugins from './npmci.plugins';
import * as paths from './npmci.paths'; import * as paths from './npmci.paths';
import * as npmciMonitor from './npmci.monitor'; import * as npmciMonitor from './npmci.monitor';
npmciMonitor.run(); npmciMonitor.run();
// Get Info about npmci itself // Get Info about npmci itself
let npmciInfo = new plugins.projectinfo.ProjectinfoNpm(paths.NpmciPackageRoot); const npmciInfo = new plugins.projectinfo.ProjectinfoNpm(paths.NpmciPackageRoot);
plugins.beautylog.log('npmci version: ' + npmciInfo.version); logger.log('info', 'npmci version: ' + npmciInfo.version);
import * as NpmciEnv from './npmci.env'; import * as NpmciEnv from './npmci.env';
import * as npmciMods from './npmci.mods'; const npmciSmartcli = new plugins.smartcli.Smartcli();
npmciSmartcli.addVersion(npmciInfo.version);
let smartcli = new plugins.smartcli.Smartcli();
smartcli.addVersion(npmciInfo.version);
// clean // clean
smartcli npmciSmartcli.addCommand('clean').subscribe(
.addCommand('clean') async argv => {
.then(async argv => { const modClean = await import('./mod_clean/index');
let modClean = await npmciMods.modClean.load();
await modClean.clean(); await modClean.clean();
}) },
.catch(err => { err => {
console.log(err); console.log(err);
process.exit(1); process.exit(1);
}); }
);
// cloudflare
smartcli
.addCommand('cloudflare')
.then(async argvArg => {
let modPurge = await npmciMods.modCloudflare.load();
await modPurge.handleCli(argvArg);
})
.catch(err => {
console.log(err);
});
// command // command
smartcli npmciSmartcli.addCommand('command').subscribe(
.addCommand('command') async argv => {
.then(async argv => { const modCommand = await import('./mod_command/index');
let modCommand = await npmciMods.modCommand.load();
await modCommand.command(); await modCommand.command();
}) },
.catch(err => { err => {
console.log(err); console.log(err);
process.exit(1); process.exit(1);
}); }
);
// command // command
smartcli npmciSmartcli.addCommand('git').subscribe(
.addCommand('git') async argvArg => {
.then(async argvArg => { const modGit = await import('./mod_git/index');
let modGit = await npmciMods.modGit.load();
await modGit.handleCli(argvArg); await modGit.handleCli(argvArg);
}) },
.catch(err => { err => {
console.log(err); console.log(err);
process.exit(1); process.exit(1);
}); }
);
// build // build
smartcli npmciSmartcli.addCommand('docker').subscribe(
.addCommand('docker') async argvArg => {
.then(async argvArg => { const modDocker = await import('./mod_docker/index');
let modDocker = await npmciMods.modDocker.load();
await modDocker.handleCli(argvArg); await modDocker.handleCli(argvArg);
}) },
.catch(err => { err => {
console.log(err); console.log(err);
process.exit(1); process.exit(1);
}); }
);
// node // node
smartcli npmciSmartcli.addCommand('node').subscribe(
.addCommand('node') async argvArg => {
.then(async argvArg => { const modNode = await import('./mod_node/index');
let modNode = await npmciMods.modNode.load();
await modNode.handleCli(argvArg); await modNode.handleCli(argvArg);
}) },
.catch(err => { err => {
console.log(err); console.log(err);
}); process.exit(1);
}
);
// npm // npm
smartcli npmciSmartcli.addCommand('npm').subscribe(
.addCommand('npm') async argvArg => {
.then(async argvArg => { const modNpm = await import('./mod_npm/index');
let modNpm = await npmciMods.modNpm.load();
await modNpm.handleCli(argvArg); await modNpm.handleCli(argvArg);
}) },
.catch(err => { err => {
console.log(err); console.log(err);
}); }
);
// trigger // trigger
smartcli npmciSmartcli.addCommand('ssh').subscribe(
.addCommand('ssh') async argvArg => {
.then(async argvArg => { const modSsh = await import('./mod_ssh/index');
let modSsh = await npmciMods.modSsh.load();
await modSsh.handleCli(argvArg); await modSsh.handleCli(argvArg);
}) },
.catch(err => { err => {
console.log(err); console.log(err);
process.exit(1); process.exit(1);
}); }
);
// trigger // trigger
smartcli npmciSmartcli.addCommand('trigger').subscribe(
.addCommand('trigger') async argv => {
.then(async argv => { const modTrigger = await import('./mod_trigger/index');
let modTrigger = await npmciMods.modTrigger.load();
await modTrigger.trigger(); await modTrigger.trigger();
}) },
.catch(err => { err => {
console.log(err); console.log(err);
process.exit(1); process.exit(1);
}); }
);
smartcli.startParse(); npmciSmartcli.startParse();

View File

@@ -1,15 +1,15 @@
import * as q from 'q';
import * as plugins from './npmci.plugins'; import * as plugins from './npmci.plugins';
import * as paths from './npmci.paths'; import * as paths from './npmci.paths';
import { repo } from './npmci.env'; import { repo } from './npmci.env';
import { KeyValueStore } from 'npmextra'; import { KeyValueStore } from '@pushrocks/npmextra';
export interface INpmciOptions { export interface INpmciOptions {
projectInfo: plugins.projectinfo.ProjectInfo;
npmGlobalTools: string[]; npmGlobalTools: string[];
npmAccessLevel?: 'private' | 'public'; npmAccessLevel?: 'private' | 'public';
npmRegistryUrl: string;
dockerRegistryRepoMap: any; dockerRegistryRepoMap: any;
dockerBuildargEnvMap: any; dockerBuildargEnvMap: any;
} }
@@ -18,10 +18,13 @@ export interface INpmciOptions {
export let kvStorage = new KeyValueStore('custom', `${repo.user}_${repo.repo}`); export let kvStorage = new KeyValueStore('custom', `${repo.user}_${repo.repo}`);
// handle config retrival // handle config retrival
let npmciNpmextra = new plugins.npmextra.Npmextra(paths.cwd); const npmciNpmextra = new plugins.npmextra.Npmextra(paths.cwd);
let defaultConfig: INpmciOptions = { const defaultConfig: INpmciOptions = {
projectInfo: new plugins.projectinfo.ProjectInfo(paths.cwd),
npmGlobalTools: [], npmGlobalTools: [],
dockerRegistryRepoMap: {}, dockerRegistryRepoMap: {},
npmAccessLevel: 'private',
npmRegistryUrl: 'registry.npmjs.org',
dockerBuildargEnvMap: {} dockerBuildargEnvMap: {}
}; };
export let configObject = npmciNpmextra.dataFor<INpmciOptions>('npmci', defaultConfig); export let configObject = npmciNpmextra.dataFor<INpmciOptions>('npmci', defaultConfig);

View File

@@ -1,6 +1,6 @@
import * as plugins from './npmci.plugins'; import * as plugins from './npmci.plugins';
import * as paths from './npmci.paths'; import * as paths from './npmci.paths';
import { GitRepo } from 'smartstring'; import { GitRepo } from '@pushrocks/smartstring';
import { Dockerfile } from './mod_docker/index'; import { Dockerfile } from './mod_docker/index';
/** /**

14
ts/npmci.logging.ts Normal file
View File

@@ -0,0 +1,14 @@
import * as plugins from './npmci.plugins';
export const logger = new plugins.smartlog.Smartlog({
logContext: {
company: 'Some Company',
companyunit: 'Some Unit',
containerName: 'Some ContainerName',
environment: 'test',
runtime: 'node',
zone: 'Some Zone'
}
});
logger.addLogDestination(new plugins.smartlogDestinationLocal.DestinationLocal());

View File

@@ -1,24 +0,0 @@
import * as _modClean from './mod_clean/index';
import * as _modCloudflare from './mod_cloudflare/index';
import * as _modCommand from './mod_command/index';
import * as _modDocker from './mod_docker/index';
import * as _modGit from './mod_git/index';
import * as _modNpm from './mod_npm/index';
import * as _modNode from './mod_node/index';
import * as _modSsh from './mod_ssh/index';
import * as _modTrigger from './mod_trigger/index';
import { LazyModule } from 'smartsystem';
export let modClean = new LazyModule<typeof _modClean>('./mod_clean/index', __dirname);
export let modCloudflare = new LazyModule<typeof _modCloudflare>(
'./mod_cloudflare/index',
__dirname
);
export let modCommand = new LazyModule<typeof _modCommand>('./mod_command/index', __dirname);
export let modGit = new LazyModule<typeof _modGit>('./mod_git/index', __dirname);
export let modDocker = new LazyModule<typeof _modDocker>('./mod_docker/index', __dirname);
export let modNode = new LazyModule<typeof _modNode>('./mod_node/index', __dirname);
export let modNpm = new LazyModule<typeof _modNpm>('./mod_npm/index', __dirname);
export let modSsh = new LazyModule<typeof _modSsh>('./mod_ssh/index', __dirname);
export let modTrigger = new LazyModule<typeof _modTrigger>('./mod_trigger/index', __dirname);

View File

@@ -1,7 +1,8 @@
import { logger } from './npmci.logging';
import * as plugins from './npmci.plugins'; import * as plugins from './npmci.plugins';
import * as env from './npmci.env'; import * as env from './npmci.env';
import { Analytics } from 'smartanalytics'; import { Analytics } from '@pushrocks/smartanalytics';
export let npmciAnalytics = new Analytics({ export let npmciAnalytics = new Analytics({
apiEndPoint: 'https://pubapi.lossless.one/analytics', apiEndPoint: 'https://pubapi.lossless.one/analytics',
@@ -17,6 +18,6 @@ export let run = async () => {
repo: env.repo.repo repo: env.repo.repo
}) })
.catch(err => { .catch(err => {
plugins.beautylog.warn('Lossless Analytics API not available...'); logger.log('warn', 'Lossless Analytics API not available...');
}); });
}; };

View File

@@ -6,3 +6,4 @@ export let NpmciPackageRoot = plugins.path.join(__dirname, '../');
export let NpmciPackageConfig = plugins.path.join(NpmciPackageRoot, './config.json'); export let NpmciPackageConfig = plugins.path.join(NpmciPackageRoot, './config.json');
export let NpmciProjectDir = cwd; export let NpmciProjectDir = cwd;
export let NpmciTestDir = plugins.path.join(cwd, './test'); export let NpmciTestDir = plugins.path.join(cwd, './test');
export let NpmciCacheDir = plugins.path.join(cwd, './.npmci_cache');

View File

@@ -1,19 +1,43 @@
export import beautylog = require('beautylog'); // node native
export import lodash = require('lodash'); import * as path from 'path';
export import npmextra = require('npmextra');
export import path = require('path'); export { path };
export import projectinfo = require('projectinfo');
export import q = require('smartq'); // @pushrocks
export let request = require('request'); import * as projectinfo from '@pushrocks/projectinfo';
export import smartcli = require('smartcli'); import * as npmextra from '@pushrocks/npmextra';
export import smartdelay = require('smartdelay'); import * as smartdelay from '@pushrocks/smartdelay';
export import smartfile = require('smartfile'); import * as smartfile from '@pushrocks/smartfile';
export import shelljs = require('shelljs'); import * as smartcli from '@pushrocks/smartcli';
export import smartparam = require('smartparam'); import * as smartlog from '@pushrocks/smartlog';
export import smartq = require('smartq'); import * as smartlogDestinationLocal from '@pushrocks/smartlog-destination-local';
export import smartshell = require('smartshell'); import * as smartparam from '@pushrocks/smartparam';
export import smartsocket = require('smartsocket'); import * as smartpromise from '@pushrocks/smartpromise';
export import smartsystem = require('smartsystem'); import * as smartrequest from '@pushrocks/smartrequest';
export import smartssh = require('smartssh'); import * as smartshell from '@pushrocks/smartshell';
export import smartstring = require('smartstring'); import * as smartsocket from '@pushrocks/smartsocket';
export import through2 = require('through2'); import * as smartssh from '@pushrocks/smartssh';
import * as smartstring from '@pushrocks/smartstring';
export {
projectinfo,
npmextra,
smartdelay,
smartfile,
smartcli,
smartlog,
smartlogDestinationLocal,
smartparam,
smartpromise,
smartrequest,
smartshell,
smartsocket,
smartssh,
smartstring
};
// third party
import * as lodash from 'lodash';
import * as through2 from 'through2';
export { lodash, through2 };

View File

@@ -1,3 +1,17 @@
{ {
"extends": "tslint-config-standard" "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"
} }

1836
yarn.lock

File diff suppressed because it is too large Load Diff