Compare commits
	
		
			163 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 43eb19f772 | |||
| dc2665d250 | |||
| 00f324e151 | |||
| e38cc40f11 | |||
| e9e8acafe4 | |||
| c763db40bb | |||
| 01256480c4 | |||
| c6918399bf | |||
| 66d28e5081 | |||
| 9de77139ea | |||
| 7b4bf10cc0 | |||
| 9eaa6347c1 | |||
| 6e4c967917 | |||
| 52a8f42fc9 | |||
| 8e9a61bbb2 | |||
| dc809a6023 | |||
| 7eeca992b0 | |||
| d018102014 | |||
| 838f2d6959 | |||
| 0d42e5f6eb | |||
| f96de8cdc3 | |||
| 965833916f | |||
| 81ec1391e3 | |||
| bbbca44640 | |||
| 7ba7dc54a1 | |||
| 4f98eeec2a | |||
| 419a6b9e5f | |||
| 9c040c34f5 | |||
| 50d3f2d795 | |||
| 305856b9e1 | |||
| 3683743f3c | |||
| 41237e0e5f | |||
| bce84a0e74 | |||
| 79bed919d8 | |||
| 4b202ce00e | |||
| 16ca787314 | |||
| 3a9b6f658a | |||
| 5c5dbf303f | |||
| 4c07131e51 | |||
| ba039469ff | |||
| 49f2498ecd | |||
| 1060060366 | |||
| 0fa3a579f7 | |||
| 0e4556d59e | |||
| e2e7967fba | |||
| 45b8d67abf | |||
| 0a69aa5d62 | |||
| dfbab1a1df | |||
| e58f009a24 | |||
| 2afd9cddc5 | |||
| d79c5366ef | |||
| 8e4f7ad244 | |||
| 39de3a1601 | |||
| cb3d2964d1 | |||
| 6b5390cef8 | |||
| 2736b85de3 | |||
| 82d7778f59 | |||
| 8c99cc0491 | |||
| 955e3d0dbe | |||
| 702ae8bed8 | |||
| b6f0723b75 | |||
| 8a2fb30e59 | |||
| 95b4030120 | |||
| 5c77cfbdc2 | |||
| 5ea42320a9 | |||
| d07ebfc9c6 | |||
| 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 | |||
| dbc12a593f | |||
| d7666e862b | |||
| e262d29510 | |||
| 858d97cb5c | |||
| b8a2df66fe | |||
| 1c128dd694 | |||
| 2744d0bf7f | |||
| 9eb232da39 | |||
| 52af1d5188 | |||
| 4325f21c8c | |||
| 6cd3eaceb4 | |||
| f850c79b6c | |||
| efdf789575 | |||
| 6ef6446022 | |||
| ef7d85e7c4 | |||
| 93b5d9869b | |||
| 2a0cfeffe9 | |||
| 909aafbd5f | |||
| 91288e2d74 | |||
| 25709b1f9a | |||
| 8a03d9aa94 | |||
| bbe1cf770a | |||
| ac8190282f | |||
| 446d140e32 | |||
| 726948651e | |||
| dd0a7bb782 | |||
| fca00ffcf8 | |||
| 13f6334ae5 | |||
| 7275a858d6 | |||
| 5a3befe5af | |||
| 385a93a05e | |||
| b4d444ff05 | |||
| 487bcb9a70 | |||
| aaf11b66d7 | |||
| 83d7d46896 | |||
| 693bda6a49 | |||
| bfe3e266ee | |||
| 5f33ebd8a7 | |||
| f78c80e100 | |||
| f4d8656831 | |||
| 2290081ef0 | |||
| 189d02a16f | |||
| 55aee04334 | |||
| 0e407b9b9d | |||
| 24095bbd40 | |||
| f97ee94b5a | |||
| 4cf7aea374 | |||
| 6ab5e9cb30 | |||
| 95c1145bf5 | |||
| ea04a1b788 | |||
| 3bc2499d09 | |||
| 1f5967ac45 | |||
| fd952f086b | |||
| 79500cb2c2 | |||
| 6c58864fcf | |||
| 7ea3ac182d | |||
| 8979d26005 | |||
| c8876dac88 | |||
| 9c8a257c2a | |||
| 8b77930ece | 
							
								
								
									
										66
									
								
								.gitea/workflows/default_nottags.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								.gitea/workflows/default_nottags.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | |||||||
|  | name: Default (not tags) | ||||||
|  |  | ||||||
|  | on: | ||||||
|  |   push: | ||||||
|  |     tags-ignore: | ||||||
|  |       - '**' | ||||||
|  |  | ||||||
|  | env: | ||||||
|  |   IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci | ||||||
|  |   NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}} | ||||||
|  |   NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}} | ||||||
|  |   NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}} | ||||||
|  |   NPMCI_URL_CLOUDLY: ${{secrets.NPMCI_URL_CLOUDLY}} | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |  | ||||||
|  |   security: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     continue-on-error: true | ||||||
|  |     container: | ||||||
|  |       image: ${{ env.IMAGE }} | ||||||
|  |  | ||||||
|  |     steps: | ||||||
|  |     - uses: actions/checkout@v3 | ||||||
|  |  | ||||||
|  |     - name: Install pnpm and npmci | ||||||
|  |       run: | | ||||||
|  |         pnpm install -g pnpm | ||||||
|  |         pnpm install -g @shipzone/npmci | ||||||
|  |  | ||||||
|  |     - name: Run npm prepare | ||||||
|  |       run: npmci npm prepare | ||||||
|  |  | ||||||
|  |     - name: Audit production dependencies | ||||||
|  |       run: | | ||||||
|  |         npmci command npm config set registry https://registry.npmjs.org | ||||||
|  |         npmci command pnpm audit --audit-level=high --prod | ||||||
|  |       continue-on-error: true | ||||||
|  |  | ||||||
|  |     - name: Audit development dependencies | ||||||
|  |       run: | | ||||||
|  |         npmci command npm config set registry https://registry.npmjs.org | ||||||
|  |         npmci command pnpm audit --audit-level=high --dev | ||||||
|  |       continue-on-error: true | ||||||
|  |  | ||||||
|  |   test: | ||||||
|  |     if: ${{ always() }} | ||||||
|  |     needs: security | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     container: | ||||||
|  |       image: ${{ env.IMAGE }} | ||||||
|  |  | ||||||
|  |     steps: | ||||||
|  |     - uses: actions/checkout@v3 | ||||||
|  |  | ||||||
|  |     - name: Test stable | ||||||
|  |       run: | | ||||||
|  |         npmci node install stable | ||||||
|  |         npmci npm install | ||||||
|  |         npmci npm test | ||||||
|  |  | ||||||
|  |     - name: Test build | ||||||
|  |       run: | | ||||||
|  |         npmci node install stable | ||||||
|  |         npmci npm install | ||||||
|  |         npmci npm build | ||||||
							
								
								
									
										108
									
								
								.gitea/workflows/default_tags.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								.gitea/workflows/default_tags.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | |||||||
|  | name: Default (tags) | ||||||
|  |  | ||||||
|  | on: | ||||||
|  |   push: | ||||||
|  |     tags: | ||||||
|  |       - '*' | ||||||
|  |  | ||||||
|  | env: | ||||||
|  |   IMAGE: registry.gitlab.com/hosttoday/ht-docker-node:npmci | ||||||
|  |   NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}} | ||||||
|  |   NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}} | ||||||
|  |   NPMCI_LOGIN_DOCKER_GITEA: ${{secrets.NPMCI_DOCKER_REGISTRYURL_DEFAULT}}|${{ gitea.repository_owner }}|${{ secrets.GITEA_TOKEN }} | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |  | ||||||
|  |   security: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     continue-on-error: true | ||||||
|  |     container: | ||||||
|  |       image: ${{ env.IMAGE }} | ||||||
|  |  | ||||||
|  |     steps: | ||||||
|  |     - uses: actions/checkout@v3 | ||||||
|  |  | ||||||
|  |     - name: Install pnpm and npmci | ||||||
|  |       run: | | ||||||
|  |         pnpm install -g pnpm | ||||||
|  |         pnpm install -g @shipzone/npmci | ||||||
|  |  | ||||||
|  |     - name: Run npm prepare | ||||||
|  |       run: npmci npm prepare | ||||||
|  |  | ||||||
|  |     - name: Audit production dependencies | ||||||
|  |       run: | | ||||||
|  |         npmci command npm config set registry https://registry.npmjs.org | ||||||
|  |         npmci command pnpm audit --audit-level=high --prod | ||||||
|  |       continue-on-error: true | ||||||
|  |  | ||||||
|  |     - name: Audit development dependencies | ||||||
|  |       run: | | ||||||
|  |         npmci command npm config set registry https://registry.npmjs.org | ||||||
|  |         npmci command pnpm audit --audit-level=high --dev | ||||||
|  |       continue-on-error: true | ||||||
|  |  | ||||||
|  |   test: | ||||||
|  |     if: ${{ always() }} | ||||||
|  |     needs: security | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     container: | ||||||
|  |       image: ${{ env.IMAGE }} | ||||||
|  |  | ||||||
|  |     steps: | ||||||
|  |     - uses: actions/checkout@v3 | ||||||
|  |  | ||||||
|  |     - name: Test stable | ||||||
|  |       run: | | ||||||
|  |         npmci node install stable | ||||||
|  |         npmci npm install | ||||||
|  |         npmci npm test | ||||||
|  |  | ||||||
|  |     - name: Test build | ||||||
|  |       run: | | ||||||
|  |         npmci node install stable | ||||||
|  |         npmci npm install | ||||||
|  |         npmci npm build | ||||||
|  |  | ||||||
|  |   release: | ||||||
|  |     needs: test | ||||||
|  |     if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     container: | ||||||
|  |       image: ${{ env.IMAGE }} | ||||||
|  |  | ||||||
|  |     steps: | ||||||
|  |     - uses: actions/checkout@v3 | ||||||
|  |  | ||||||
|  |     - name: Release | ||||||
|  |       run: | | ||||||
|  |         npmci node install stable | ||||||
|  |         npmci npm publish | ||||||
|  |  | ||||||
|  |   metadata: | ||||||
|  |     needs: test | ||||||
|  |     if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     container: | ||||||
|  |       image: ${{ env.IMAGE }} | ||||||
|  |     continue-on-error: true | ||||||
|  |  | ||||||
|  |     steps: | ||||||
|  |     - uses: actions/checkout@v3 | ||||||
|  |  | ||||||
|  |     - name: Code quality | ||||||
|  |       run: | | ||||||
|  |         npmci command npm install -g typescript | ||||||
|  |         npmci npm prepare | ||||||
|  |         npmci npm install | ||||||
|  |  | ||||||
|  |     - name: Trigger | ||||||
|  |       run: npmci trigger | ||||||
|  |  | ||||||
|  |     - name: Build docs and upload artifacts | ||||||
|  |       run: | | ||||||
|  |         npmci node install stable | ||||||
|  |         npmci npm install | ||||||
|  |         pnpm install -g @git.zone/tsdoc | ||||||
|  |         npmci command tsdoc | ||||||
|  |       continue-on-error: true | ||||||
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -15,8 +15,6 @@ node_modules/ | |||||||
|  |  | ||||||
| # builds | # builds | ||||||
| dist/ | dist/ | ||||||
| dist_web/ | dist_*/ | ||||||
| dist_serve/ |  | ||||||
| dist_ts_web/ |  | ||||||
|  |  | ||||||
| # custom | # custom | ||||||
							
								
								
									
										119
									
								
								.gitlab-ci.yml
									
									
									
									
									
								
							
							
						
						
									
										119
									
								
								.gitlab-ci.yml
									
									
									
									
									
								
							| @@ -1,119 +0,0 @@ | |||||||
| # gitzone ci_default |  | ||||||
| image: registry.gitlab.com/hosttoday/ht-docker-node:npmci |  | ||||||
|  |  | ||||||
| cache: |  | ||||||
|   paths: |  | ||||||
|   - .npmci_cache/ |  | ||||||
|   key: "$CI_BUILD_STAGE" |  | ||||||
|  |  | ||||||
| stages: |  | ||||||
| - security |  | ||||||
| - test |  | ||||||
| - release |  | ||||||
| - metadata |  | ||||||
|  |  | ||||||
| # ==================== |  | ||||||
| # security stage |  | ||||||
| # ==================== |  | ||||||
| mirror: |  | ||||||
|   stage: security |  | ||||||
|   script: |  | ||||||
|   - npmci git mirror |  | ||||||
|   tags: |  | ||||||
|   - docker |  | ||||||
|   - notpriv |  | ||||||
|  |  | ||||||
| snyk: |  | ||||||
|   stage: security |  | ||||||
|   script: |  | ||||||
|     - npmci npm prepare |  | ||||||
|     - npmci command npm install -g snyk |  | ||||||
|     - npmci command npm install --ignore-scripts |  | ||||||
|     - npmci command snyk test |  | ||||||
|   tags: |  | ||||||
|   - docker |  | ||||||
|   - notpriv |  | ||||||
|  |  | ||||||
| # ==================== |  | ||||||
| # test stage |  | ||||||
| # ==================== |  | ||||||
|  |  | ||||||
| testStable: |  | ||||||
|   stage: test |  | ||||||
|   script: |  | ||||||
|   - npmci npm prepare |  | ||||||
|   - npmci node install stable |  | ||||||
|   - npmci npm install |  | ||||||
|   - npmci npm test |  | ||||||
|   coverage: /\d+.?\d+?\%\s*coverage/ |  | ||||||
|   tags: |  | ||||||
|   - docker |  | ||||||
|   - priv |  | ||||||
|  |  | ||||||
| testBuild: |  | ||||||
|   stage: test |  | ||||||
|   script: |  | ||||||
|   - npmci npm prepare |  | ||||||
|   - npmci node install lts |  | ||||||
|   - npmci npm install |  | ||||||
|   - npmci command npm run build |  | ||||||
|   coverage: /\d+.?\d+?\%\s*coverage/ |  | ||||||
|   tags: |  | ||||||
|   - docker |  | ||||||
|   - notpriv |  | ||||||
|  |  | ||||||
| release: |  | ||||||
|   stage: release |  | ||||||
|   script: |  | ||||||
|   - npmci node install lts |  | ||||||
|   - npmci npm publish |  | ||||||
|   only: |  | ||||||
|   - tags |  | ||||||
|   tags: |  | ||||||
|   - docker |  | ||||||
|   - notpriv |  | ||||||
|  |  | ||||||
| # ==================== |  | ||||||
| # metadata stage |  | ||||||
| # ==================== |  | ||||||
| codequality: |  | ||||||
|   stage: metadata |  | ||||||
|   allow_failure: true |  | ||||||
|   script: |  | ||||||
|     - npmci command npm install -g tslint typescript |  | ||||||
|     - npmci npm install |  | ||||||
|     - npmci command "tslint -c tslint.json ./ts/**/*.ts" |  | ||||||
|   tags: |  | ||||||
|   - docker |  | ||||||
|   - priv |  | ||||||
|  |  | ||||||
| trigger: |  | ||||||
|   stage: metadata |  | ||||||
|   script: |  | ||||||
|   - npmci trigger |  | ||||||
|   only: |  | ||||||
|   - tags |  | ||||||
|   tags: |  | ||||||
|   - docker |  | ||||||
|   - notpriv |  | ||||||
|  |  | ||||||
| pages: |  | ||||||
|   image: hosttoday/ht-docker-dbase:npmci |  | ||||||
|   services: |  | ||||||
|    - docker:stable-dind |  | ||||||
|   stage: metadata |  | ||||||
|   script: |  | ||||||
|     - npmci command npm install -g @gitzone/tsdoc |  | ||||||
|     - npmci npm prepare |  | ||||||
|     - npmci npm install |  | ||||||
|     - npmci command tsdoc |  | ||||||
|   tags: |  | ||||||
|     - docker |  | ||||||
|     - notpriv |  | ||||||
|   only: |  | ||||||
|     - tags |  | ||||||
|   artifacts: |  | ||||||
|     expire_in: 1 week |  | ||||||
|     paths: |  | ||||||
|     - public |  | ||||||
|   allow_failure: true |  | ||||||
							
								
								
									
										4
									
								
								.snyk
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								.snyk
									
									
									
									
									
								
							| @@ -1,4 +0,0 @@ | |||||||
| # Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. |  | ||||||
| version: v1.13.1 |  | ||||||
| ignore: {} |  | ||||||
| patch: {} |  | ||||||
							
								
								
									
										11
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | { | ||||||
|  |   "version": "0.2.0", | ||||||
|  |   "configurations": [ | ||||||
|  |     { | ||||||
|  |       "command": "npm test", | ||||||
|  |       "name": "Run npm test", | ||||||
|  |       "request": "launch", | ||||||
|  |       "type": "node-terminal" | ||||||
|  |     } | ||||||
|  |   ] | ||||||
|  | } | ||||||
							
								
								
									
										25
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							| @@ -1,3 +1,26 @@ | |||||||
| { | { | ||||||
|   "workbench.colorCustomizations": {} |   "json.schemas": [ | ||||||
|  |     { | ||||||
|  |       "fileMatch": ["/npmextra.json"], | ||||||
|  |       "schema": { | ||||||
|  |         "type": "object", | ||||||
|  |         "properties": { | ||||||
|  |           "npmci": { | ||||||
|  |             "type": "object", | ||||||
|  |             "description": "settings for npmci" | ||||||
|  |           }, | ||||||
|  |           "gitzone": { | ||||||
|  |             "type": "object", | ||||||
|  |             "description": "settings for gitzone", | ||||||
|  |             "properties": { | ||||||
|  |               "projectType": { | ||||||
|  |                 "type": "string", | ||||||
|  |                 "enum": ["website", "element", "service", "npm", "wcc"] | ||||||
|  |               } | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   ] | ||||||
| } | } | ||||||
							
								
								
									
										86
									
								
								changelog.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								changelog.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | |||||||
|  | # Changelog | ||||||
|  |  | ||||||
|  | ## 2024-11-17 - 4.1.36 - fix(docker) | ||||||
|  | Improve logging for Dockerfile build order with base image details. | ||||||
|  |  | ||||||
|  | - Enhance logging in Dockerfile sorting process to include base image information. | ||||||
|  |  | ||||||
|  | ## 2024-11-17 - 4.1.35 - fix(docker) | ||||||
|  | Fix Dockerfile dependency sorting and enhance environment variable handling for GitHub repos | ||||||
|  |  | ||||||
|  | - Refined the algorithm for sorting Dockerfiles based on dependencies to ensure proper build order. | ||||||
|  | - Enhanced environment variable handling in the NpmciEnv class to support conditional assignments. | ||||||
|  | - Updated various dependencies in package.json for improved performance and compatibility. | ||||||
|  | - Added error handling to circular dependency detection in Dockerfile sorting. | ||||||
|  |  | ||||||
|  | ## 2024-11-05 - 4.1.34 - fix(connector) | ||||||
|  | Remove unused typedrequest implementation in cloudlyconnector | ||||||
|  |  | ||||||
|  | - Removed commented out code that initialized typedrequest in CloudlyConnector. | ||||||
|  |  | ||||||
|  | ## 2024-11-05 - 4.1.33 - fix(core) | ||||||
|  | Updated dependencies and improved npm preparation logic. | ||||||
|  |  | ||||||
|  | - Updated @git.zone/tsbuild from ^2.1.84 to ^2.2.0. | ||||||
|  | - Updated @git.zone/tsrun from ^1.2.49 to ^1.3.3. | ||||||
|  | - Updated @types/node from ^22.7.9 to ^22.8.7. | ||||||
|  | - Updated @serve.zone/api from ^1.2.1 to ^4.3.1. | ||||||
|  | - Improved npm preparation logic to handle empty tokens gracefully. | ||||||
|  |  | ||||||
|  | ## 2024-10-23 - 4.1.32 - fix(dependencies) | ||||||
|  | Update project dependencies to latest versions | ||||||
|  |  | ||||||
|  | - Updated development dependencies, including @git.zone/tsbuild and @git.zone/tsrun. | ||||||
|  | - Updated production dependencies such as @api.global/typedrequest and @push.rocks/smartfile. | ||||||
|  |  | ||||||
|  | ## 2022-10-24 - 4.0.11 - prerelease | ||||||
|  | now includes a precheck for more generic runner execution | ||||||
|  |  | ||||||
|  | - Implemented a precheck feature for runners. | ||||||
|  |  | ||||||
|  | ## 2022-10-09 to 2022-10-11 - 4.0.0 to 4.0.10 - migration | ||||||
|  | internal migrations and fixes | ||||||
|  |  | ||||||
|  | - Major switch to ESM style module: **BREAKING CHANGE**. | ||||||
|  | - Multiple fixes in core functionalities and module updates. | ||||||
|  |  | ||||||
|  | ## 2019-11-26 - 3.1.73 - fixes | ||||||
|  | correctly setting npm cache and other updates | ||||||
|  |  | ||||||
|  | - Ensured correct npm cache setting during preparation. | ||||||
|  | - Various core updates. | ||||||
|  |  | ||||||
|  | ## 2018-12-23 - 3.1.19 - privacy updates | ||||||
|  | enhanced mirroring controls for private code | ||||||
|  |  | ||||||
|  | - Now refusing to mirror private code. | ||||||
|  |  | ||||||
|  | ## 2018-11-24 - 3.1.2 - ci improvement | ||||||
|  | removed unnecessary build dependency | ||||||
|  |  | ||||||
|  | - Removed npmts build dependency in CI pipeline. | ||||||
|  |  | ||||||
|  | ## 2018-09-22 - 3.0.59 - enhancement | ||||||
|  | integrated smartlog for improved logging | ||||||
|  |  | ||||||
|  | - Logs now utilize smartlog for better management. | ||||||
|  |  | ||||||
|  | ## 2017-09-08 - 3.0.14 - analytics | ||||||
|  | added analytics features | ||||||
|  |  | ||||||
|  | - Enabled analytics throughout the system. | ||||||
|  |  | ||||||
|  | ## 2017-08-29 - 3.0.9 - docker enhancements | ||||||
|  | docker improvements and build args implementation | ||||||
|  |  | ||||||
|  | - Implemented working `dockerBuildArgEnvMap`. | ||||||
|  |  | ||||||
|  | ## 2017-07-27 - 2.4.0 - stability improvements | ||||||
|  | various updates to stabilize the environment | ||||||
|  |  | ||||||
|  | - Fixed npmci versioning issues. | ||||||
|  |  | ||||||
|  | ## 2016-11-25 - 2.3.24 - global tools | ||||||
|  | improved handling for global tool installations | ||||||
|  |  | ||||||
|  | - Improved install handling for needed global tools. | ||||||
							
								
								
									
										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(); | ||||||
							
								
								
									
										3
									
								
								cli.js
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								cli.js
									
									
									
									
									
								
							| @@ -1,3 +1,4 @@ | |||||||
| #!/usr/bin/env node | #!/usr/bin/env node | ||||||
| process.env.CLI_CALL = 'true'; | process.env.CLI_CALL = 'true'; | ||||||
| require('./dist/index'); | const cliTool = await import('./dist_ts/index.js'); | ||||||
|  | cliTool.runCli(); | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| #!/usr/bin/env node | #!/usr/bin/env node | ||||||
| process.env.CLI_CALL = 'true'; | process.env.CLI_CALL = 'true'; | ||||||
| require('@gitzone/tsrun'); |  | ||||||
| require('./ts/index'); | import * as tsrun from '@git.zone/tsrun'; | ||||||
|  | tsrun.runPath('./cli.child.js', import.meta.url); | ||||||
|   | |||||||
| @@ -9,13 +9,31 @@ | |||||||
|     "command": "npmci test stable" |     "command": "npmci test stable" | ||||||
|   }, |   }, | ||||||
|   "gitzone": { |   "gitzone": { | ||||||
|  |     "projectType": "npm", | ||||||
|     "module": { |     "module": { | ||||||
|       "githost": "gitlab.com", |       "githost": "gitlab.com", | ||||||
|       "gitscope": "shipzone", |       "gitscope": "ship.zone", | ||||||
|       "gitrepo": "npmci", |       "gitrepo": "npmci", | ||||||
|       "shortDescription": "node and docker in gitlab ci on steroids", |       "description": "A tool to streamline Node.js and Docker workflows within CI environments, particularly GitLab CI, providing various CI/CD utilities.", | ||||||
|       "npmPackagename": "@shipzone/npmci", |       "npmPackagename": "@ship.zone/npmci", | ||||||
|       "license": "MIT" |       "license": "MIT", | ||||||
|  |       "keywords": [ | ||||||
|  |         "Node.js", | ||||||
|  |         "Docker", | ||||||
|  |         "GitLab CI", | ||||||
|  |         "GitHub CI", | ||||||
|  |         "Gitea CI", | ||||||
|  |         "CI/CD", | ||||||
|  |         "automation", | ||||||
|  |         "npm", | ||||||
|  |         "TypeScript", | ||||||
|  |         "cloud", | ||||||
|  |         "SSH", | ||||||
|  |         "registry", | ||||||
|  |         "container management", | ||||||
|  |         "continuous integration", | ||||||
|  |         "continuous deployment" | ||||||
|  |       ] | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
							
								
								
									
										3794
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										3794
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										111
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										111
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,17 +1,19 @@ | |||||||
| { | { | ||||||
|   "name": "@shipzone/npmci", |   "name": "@ship.zone/npmci", | ||||||
|   "version": "3.1.49", |   "version": "4.1.36", | ||||||
|   "private": false, |   "private": false, | ||||||
|   "description": "node and docker in gitlab ci on steroids", |   "description": "A tool to streamline Node.js and Docker workflows within CI environments, particularly GitLab CI, providing various CI/CD utilities.", | ||||||
|   "main": "dist/index.js", |   "main": "dist_ts/index.js", | ||||||
|   "typings": "dist/index.d.ts", |   "typings": "dist_ts/index.d.ts", | ||||||
|  |   "type": "module", | ||||||
|   "bin": { |   "bin": { | ||||||
|     "npmci": "cli.js" |     "npmci": "cli.js" | ||||||
|   }, |   }, | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "test": "(rm -f config.json) && tstest test/", |     "test": "tstest test/", | ||||||
|     "build": "(rm -f config.json) && tsbuild && (npm run testVersion)", |     "build": "tsbuild --allowimplicitany && (npm run testVersion)", | ||||||
|     "testVersion": "(cd test/assets/ && node ../../cli.js -v)" |     "testVersion": "(cd test/assets/ && node ../../cli.js -v)", | ||||||
|  |     "buildDocs": "tsdoc" | ||||||
|   }, |   }, | ||||||
|   "repository": { |   "repository": { | ||||||
|     "type": "git", |     "type": "git", | ||||||
| @@ -24,48 +26,69 @@ | |||||||
|   }, |   }, | ||||||
|   "homepage": "https://gitlab.com/gitzone/npmci#README", |   "homepage": "https://gitlab.com/gitzone/npmci#README", | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "@gitzone/tsbuild": "^2.1.17", |     "@git.zone/tsbuild": "^2.2.0", | ||||||
|     "@gitzone/tsrun": "^1.2.6", |     "@git.zone/tsrun": "^1.3.3", | ||||||
|     "@gitzone/tstest": "^1.0.24", |     "@git.zone/tstest": "^1.0.77", | ||||||
|     "@pushrocks/tapbundle": "^3.0.13", |     "@push.rocks/tapbundle": "^5.5.0", | ||||||
|     "@types/node": "^12.7.3", |     "@types/node": "^22.9.0" | ||||||
|     "tslint": "^5.19.0", |  | ||||||
|     "tslint-config-prettier": "^1.18.0" |  | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@apiglobal/typedrequest": "^1.0.17", |     "@api.global/typedrequest": "^3.1.10", | ||||||
|     "@pushrocks/lik": "^3.0.11", |     "@push.rocks/lik": "^6.1.0", | ||||||
|     "@pushrocks/npmextra": "^3.0.5", |     "@push.rocks/npmextra": "^5.1.2", | ||||||
|     "@pushrocks/projectinfo": "^4.0.2", |     "@push.rocks/projectinfo": "^5.0.2", | ||||||
|     "@pushrocks/qenv": "^4.0.4", |     "@push.rocks/qenv": "^6.0.2", | ||||||
|     "@pushrocks/smartanalytics": "^2.0.15", |     "@push.rocks/smartanalytics": "^2.0.15", | ||||||
|     "@pushrocks/smartcli": "^3.0.7", |     "@push.rocks/smartcli": "^4.0.11", | ||||||
|     "@pushrocks/smartdelay": "^2.0.3", |     "@push.rocks/smartdelay": "^3.0.5", | ||||||
|     "@pushrocks/smartfile": "^7.0.2", |     "@push.rocks/smartenv": "^5.0.5", | ||||||
|     "@pushrocks/smartgit": "^1.0.13", |     "@push.rocks/smartfile": "^11.0.21", | ||||||
|     "@pushrocks/smartlog": "^2.0.19", |     "@push.rocks/smartgit": "^3.1.1", | ||||||
|     "@pushrocks/smartlog-destination-local": "^8.0.2", |     "@push.rocks/smartlog": "^3.0.7", | ||||||
|     "@pushrocks/smartparam": "^1.0.4", |     "@push.rocks/smartlog-destination-local": "^9.0.0", | ||||||
|     "@pushrocks/smartpromise": "^3.0.2", |     "@push.rocks/smartobject": "^1.0.12", | ||||||
|     "@pushrocks/smartrequest": "^1.1.23", |     "@push.rocks/smartpath": "^5.0.11", | ||||||
|     "@pushrocks/smartshell": "^2.0.25", |     "@push.rocks/smartpromise": "^4.0.4", | ||||||
|     "@pushrocks/smartsocket": "^1.1.45", |     "@push.rocks/smartrequest": "^2.0.23", | ||||||
|     "@pushrocks/smartssh": "^1.2.3", |     "@push.rocks/smartshell": "^3.0.6", | ||||||
|     "@pushrocks/smartstring": "^3.0.10", |     "@push.rocks/smartsocket": "^2.0.22", | ||||||
|     "@servezone/servezone-interfaces": "^2.0.29", |     "@push.rocks/smartssh": "^2.0.1", | ||||||
|     "@types/shelljs": "^0.8.5", |     "@push.rocks/smartstring": "^4.0.8", | ||||||
|     "@types/through2": "^2.0.34", |     "@serve.zone/api": "^4.3.11", | ||||||
|     "through2": "^3.0.1" |     "@tsclass/tsclass": "^4.1.2", | ||||||
|  |     "@types/through2": "^2.0.38", | ||||||
|  |     "through2": "^4.0.2" | ||||||
|   }, |   }, | ||||||
|   "files": [ |   "files": [ | ||||||
|     "ts/*", |     "ts/**/*", | ||||||
|     "ts_web/*", |     "ts_web/**/*", | ||||||
|     "dist/*", |     "dist/**/*", | ||||||
|     "dist_web/*", |     "dist_*/**/*", | ||||||
|     "dist_ts_web/*", |     "dist_ts/**/*", | ||||||
|     "assets/*", |     "dist_ts_web/**/*", | ||||||
|  |     "assets/**/*", | ||||||
|     "cli.js", |     "cli.js", | ||||||
|     "npmextra.json", |     "npmextra.json", | ||||||
|     "readme.md" |     "readme.md" | ||||||
|  |   ], | ||||||
|  |   "browserslist": [ | ||||||
|  |     "last 1 chrome versions" | ||||||
|  |   ], | ||||||
|  |   "keywords": [ | ||||||
|  |     "Node.js", | ||||||
|  |     "Docker", | ||||||
|  |     "GitLab CI", | ||||||
|  |     "GitHub CI", | ||||||
|  |     "Gitea CI", | ||||||
|  |     "CI/CD", | ||||||
|  |     "automation", | ||||||
|  |     "npm", | ||||||
|  |     "TypeScript", | ||||||
|  |     "cloud", | ||||||
|  |     "SSH", | ||||||
|  |     "registry", | ||||||
|  |     "container management", | ||||||
|  |     "continuous integration", | ||||||
|  |     "continuous deployment" | ||||||
|   ] |   ] | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										9740
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										9740
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2
									
								
								readme.hints.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								readme.hints.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | - focus on cli usage in CI environments. | ||||||
|  | - show Gitlab CI, GitHub CI and Gitea CI examples. | ||||||
							
								
								
									
										535
									
								
								readme.md
									
									
									
									
									
								
							
							
						
						
									
										535
									
								
								readme.md
									
									
									
									
									
								
							| @@ -1,101 +1,494 @@ | |||||||
| # @shipzone/npmci | # @ship.zone/npmci | ||||||
| node and docker in gitlab ci on steroids | A tool to enhance Node.js and Docker workflows within GitLab CI, providing various CI/CD utilities. | ||||||
|  |  | ||||||
| ## Availabililty and Links | ## Install | ||||||
| * [npmjs.org (npm package)](https://www.npmjs.com/package/@shipzone/npmci) |  | ||||||
| * [gitlab.com (source)](https://gitlab.com/shipzone/npmci) |  | ||||||
| * [github.com (source mirror)](https://github.com/shipzone/npmci) |  | ||||||
| * [docs (typedoc)](https://shipzone.gitlab.io/npmci/) |  | ||||||
|  |  | ||||||
| ## Status for master | To install `@ship.zone/npmci`, you can use npm or yarn: | ||||||
| [](https://gitlab.com/shipzone/npmci/commits/master) |  | ||||||
| [](https://gitlab.com/shipzone/npmci/commits/master) | ```sh | ||||||
| [](https://www.npmjs.com/package/@shipzone/npmci) | # Using npm | ||||||
| [](https://snyk.io/test/npm/@shipzone/npmci) | npm install @ship.zone/npmci | ||||||
| [](https://nodejs.org/dist/latest-v10.x/docs/api/) |  | ||||||
| [](https://nodejs.org/dist/latest-v10.x/docs/api/) | # Using yarn | ||||||
| [](https://prettier.io/) | yarn add @ship.zone/npmci | ||||||
|  | ``` | ||||||
|  |  | ||||||
| ## Usage | ## Usage | ||||||
|  |  | ||||||
| Use TypeScript for best in class instellisense. | `npmci` is designed to streamline CI/CD processes, particularly in Docker and Node.js environments. The following sections illustrate its usage in various scenarios, from handling Node versions to building Docker images and more. | ||||||
|  |  | ||||||
| npmci is designed to work in docker CI environments. The following docker images come with npmci presinstalled: | ### 1. Integration with GitLab CI, GitHub CI, and Gitea CI | ||||||
|  |  | ||||||
| Docker Hub: | #### GitLab CI | ||||||
|  |  | ||||||
| - [hosttoday/ht-docker-node:npmci](https://hub.docker.com/r/hosttoday/ht-docker-node/)   | An example of integrating `npmci` into a GitLab CI configuration could look like this: | ||||||
|   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: | ```yaml | ||||||
|  | image: hosttoday/ht-docker-node:npmci | ||||||
|  |  | ||||||
| ```shell | stages: | ||||||
| # Handle node versions |   - prepare | ||||||
| npmci node install stable # will install latest stable node version and update PATH for node and npm |   - build | ||||||
| npmci node install lts # will install latest LTS node version and update PATH for node and npm versions |   - test | ||||||
| npmci node install legacy # will install latest legacy node version and update PATH for node and npm |   - deploy | ||||||
| npmci node install x.x.x #  will install any specific node version. |  | ||||||
|  |  | ||||||
| # Handle npm and yarn tasks | default: | ||||||
| npmcu npm login # logs in npm using the auth key provided at env var "NPMCI_TOKEN_NPM" |   before_script: | ||||||
| npmci npm install  # installs dependencies using npm or yarn dependending on availablity |     - npmci node install stable | ||||||
| npmci npm test # tests the package |     - npmci npm install | ||||||
| npmci npm publish # builds a package and publishes it |  | ||||||
|  |  | ||||||
| # handle docker tasks | prepare: | ||||||
| npmci docker prepare |   stage: prepare | ||||||
| ## npmci test docker will look at all Dockerfiles and look for according tags on GitLab container registry |   script: | ||||||
|  |     - npmci prepare npm | ||||||
|  |     - npmci prepare docker | ||||||
|  |  | ||||||
|  | build: | ||||||
|  |   stage: build | ||||||
|  |   script: | ||||||
|  |     - npmci docker build | ||||||
|  |  | ||||||
| # prepare tools | test: | ||||||
| npmci prepare npm # will look for $NPMCI_TOKEN_NPM env var and create .npmrc, so npm is authenticated |   stage: test | ||||||
| npmci prepare docker # will look for $NPMCI_LOGIN_DOCKER in form username|password and authenticate docker |   script: | ||||||
| npmci prepare docker-gitlab # will authenticate docker for gitlab container registry |     - npmci npm test | ||||||
|  |  | ||||||
| # build containers | deploy: | ||||||
| npmci docker build # will build containers |   stage: deploy | ||||||
| ## all Dockerfiles named Dockerfile* are picked up. |   script: | ||||||
| ## specify tags like this Dockerfile_[tag] |     - npmci publish npm | ||||||
| ## uploads all built images as [username]/[reponame]:[tag]_test to GitLab |     - npmci docker push | ||||||
| ## then test in next step with "npmci test docker" |  | ||||||
|  |  | ||||||
| # publish npm module |   environment: | ||||||
| npmci publish npm # will look vor $NPMCI_TOKEN_NPM env var and push any module in cwd to npm |     name: production | ||||||
| npmci publish docker |     url: http://example.com | ||||||
|  |  | ||||||
| # trigger webhooks |  | ||||||
| npmci trigger # will look for NPMCI_TRIGGER_1 to NPMCI_TRIGGER_100 in form domain|id|token|ref|name |  | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ## Configuration | #### GitHub Actions | ||||||
|  |  | ||||||
| npmci supports the use of npmextra. | Similarly, you can set up `npmci` in GitHub Actions: | ||||||
|  |  | ||||||
| To configure npmci create a `npmextra.json` file at the root of your project | ```yaml | ||||||
|  | name: CI Pipeline | ||||||
|  |  | ||||||
| ```json | on: | ||||||
| { |   push: | ||||||
|   "npmci": { |     branches: | ||||||
|     "globalNpmTools": ["npm-check-updates", "protractor", "npmts", "gitzone"] |       - main | ||||||
|   } |  | ||||||
|  | jobs: | ||||||
|  |   prepare: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - uses: actions/checkout@v2 | ||||||
|  |       - name: Set up Node.js | ||||||
|  |         uses: actions/setup-node@v2 | ||||||
|  |         with: | ||||||
|  |           node-version: '14' | ||||||
|  |       - run: npm install -g @ship.zone/npmci | ||||||
|  |       - run: npmci node install stable | ||||||
|  |       - run: npmci npm install | ||||||
|  |  | ||||||
|  |   build: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     needs: prepare | ||||||
|  |     steps: | ||||||
|  |       - run: npmci docker build | ||||||
|  |  | ||||||
|  |   test: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     needs: build | ||||||
|  |     steps: | ||||||
|  |       - run: npmci npm test | ||||||
|  |  | ||||||
|  |   deploy: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     needs: test | ||||||
|  |     steps: | ||||||
|  |       - run: npmci publish npm | ||||||
|  |       - run: npmci docker push | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | #### Gitea CI | ||||||
|  |  | ||||||
|  | Lastly, for Gitea CI: | ||||||
|  |  | ||||||
|  | ```yaml | ||||||
|  | image: hosttoday/ht-docker-node:npmci | ||||||
|  |  | ||||||
|  | pipelines: | ||||||
|  |   default: | ||||||
|  |     - step: | ||||||
|  |         name: Prepare | ||||||
|  |         image: hosttoday/ht-docker-node:npmci | ||||||
|  |         commands: | ||||||
|  |           - npmci node install stable | ||||||
|  |           - npmci npm install | ||||||
|  |           - npmci prepare npm | ||||||
|  |           - npmci prepare docker | ||||||
|  |  | ||||||
|  |     - step: | ||||||
|  |         name: Build | ||||||
|  |         image: hosttoday/ht-docker-node:npmci | ||||||
|  |         commands: | ||||||
|  |           - npmci docker build | ||||||
|  |  | ||||||
|  |     - step: | ||||||
|  |         name: Test | ||||||
|  |         image: hosttoday/ht-docker-node:npmci | ||||||
|  |         commands: | ||||||
|  |           - npmci npm test | ||||||
|  |  | ||||||
|  |     - step: | ||||||
|  |         name: Deploy | ||||||
|  |         image: hosttoday/ht-docker-node:npmci | ||||||
|  |         commands: | ||||||
|  |           - npmci publish npm | ||||||
|  |           - npmci docker push | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### 2. Handle Node Versions | ||||||
|  |  | ||||||
|  | One of the core features of `npmci` is managing Node versions in your CI environment. You can specify which version of Node to install: | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { Npmci } from '@ship.zone/npmci'; | ||||||
|  |  | ||||||
|  | async function manageNodeVersions() { | ||||||
|  |   const npmciInstance = new Npmci(); | ||||||
|  |   await npmciInstance.start(); | ||||||
|  |  | ||||||
|  |   await npmciInstance.nodejsManager.handleCli({ | ||||||
|  |     _: ['node', 'install', 'stable'] // Installs the latest stable version | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   await npmciInstance.nodejsManager.handleCli({ | ||||||
|  |     _: ['node', 'install', 'lts'] // Installs the Long-Term Support (LTS) version | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   await npmciInstance.nodejsManager.handleCli({ | ||||||
|  |     _: ['node', 'install', 'legacy'] // Installs a legacy version | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   await npmciInstance.nodejsManager.handleCli({ | ||||||
|  |     _: ['node', 'install', '14.17.0'] // Install a specific version of Node | ||||||
|  |   }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | manageNodeVersions().then(() => console.log('Node versions managed successfully.')); | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| **Available options** | ### 3. Handling npm and Yarn Tasks | ||||||
|  |  | ||||||
| | setting        | example                       | description                                                                                       | | `npmci` provides numerous utilities to streamline npm and yarn workflow tasks within a CI/CD pipeline. | ||||||
| | -------------- | ----------------------------- | ------------------------------------------------------------------------------------------------- | |  | ||||||
| | 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. | ```typescript | ||||||
|  | import { Npmci } from '@ship.zone/npmci'; | ||||||
|  |  | ||||||
| Use TypeScript for best in class instellisense. | async function manageNpmTasks() { | ||||||
|  |   const npmciInstance = new Npmci(); | ||||||
|  |   await npmciInstance.start(); | ||||||
|  |  | ||||||
| For further information read the linked docs at the top of this readme. |   await npmciInstance.npmManager.handleCli({ _: ['npm', 'install'] }); // Installs dependencies | ||||||
|  |   await npmciInstance.npmManager.handleCli({ _: ['npm', 'test'] }); // Runs tests | ||||||
|  |   await npmciInstance.npmManager.handleCli({ _: ['npm', 'publish'] }); // Publishes the package | ||||||
|  | } | ||||||
|  |  | ||||||
| > MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh) | manageNpmTasks().then(() => console.log('Npm tasks handled successfully.')); | ||||||
| | By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy) | ``` | ||||||
|  |  | ||||||
| [](https://maintainedby.lossless.com) | ### 4. Docker Task Handling | ||||||
|  |  | ||||||
|  | `npmci` simplifies Docker operations, particularly in building, testing, and publishing Docker images. | ||||||
|  |  | ||||||
|  | **Prepare Docker Environment:** | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { Npmci } from '@ship.zone/npmci'; | ||||||
|  |  | ||||||
|  | async function prepareDocker() { | ||||||
|  |   const npmciInstance = new Npmci(); | ||||||
|  |   await npmciInstance.start(); | ||||||
|  |  | ||||||
|  |   await npmciInstance.dockerManager.handleCli({ _: ['docker', 'prepare'] }); // Prepares Docker environment | ||||||
|  | } | ||||||
|  |  | ||||||
|  | prepareDocker().then(() => console.log('Docker environment prepared successfully.')); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | **Building Docker Images:** | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { Npmci } from '@ship.zone/npmci'; | ||||||
|  |  | ||||||
|  | async function buildDockerImages() { | ||||||
|  |   const npmciInstance = new Npmci(); | ||||||
|  |   await npmciInstance.start(); | ||||||
|  |  | ||||||
|  |   await npmciInstance.dockerManager.handleCli({ _: ['docker', 'build'] }); // Builds Docker images | ||||||
|  | } | ||||||
|  |  | ||||||
|  | buildDockerImages().then(() => console.log('Docker images built successfully.')); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | **Testing Docker Images:** | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { Npmci } from '@ship.zone/npmci'; | ||||||
|  |  | ||||||
|  | async function testDockerImages() { | ||||||
|  |   const npmciInstance = new Npmci(); | ||||||
|  |   await npmciInstance.start(); | ||||||
|  |  | ||||||
|  |   await npmciInstance.dockerManager.handleCli({ _: ['docker', 'test'] }); // Tests Docker images | ||||||
|  | } | ||||||
|  |  | ||||||
|  | testDockerImages().then(() => console.log('Docker images tested successfully.')); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | **Publishing Docker Images:** | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { Npmci } from '@ship.zone/npmci'; | ||||||
|  |  | ||||||
|  | async function pushDockerImages() { | ||||||
|  |   const npmciInstance = new Npmci(); | ||||||
|  |   await npmciInstance.start(); | ||||||
|  |  | ||||||
|  |   await npmciInstance.dockerManager.handleCli({ _: ['docker', 'push'] }); // Pushes Docker images to registry | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pushDockerImages().then(() => console.log('Docker images pushed successfully.')); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### 5. Managing Docker Registries | ||||||
|  |  | ||||||
|  | `npmci` can handle multiple Docker registries and allows for easy integration within your CI pipeline. | ||||||
|  |  | ||||||
|  | **Logging in to Docker Registries:** | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { Npmci } from '@ship.zone/npmci'; | ||||||
|  |  | ||||||
|  | async function loginToDockerRegistries() { | ||||||
|  |   const npmciInstance = new Npmci(); | ||||||
|  |   await npmciInstance.start(); | ||||||
|  |  | ||||||
|  |   await npmciInstance.dockerManager.handleCli({ _: ['docker', 'login'] }); // Logs into all configured Docker registries | ||||||
|  | } | ||||||
|  |  | ||||||
|  | loginToDockerRegistries().then(() => console.log('Logged into Docker registries.')); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | **Pulling Docker Images:** | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { Npmci } from '@ship.zone/npmci'; | ||||||
|  |  | ||||||
|  | async function pullDockerImages() { | ||||||
|  |   const npmciInstance = new Npmci(); | ||||||
|  |   await npmciInstance.start(); | ||||||
|  |  | ||||||
|  |   await npmciInstance.dockerManager.handleCli({ _: ['docker', 'pull', 'registry.gitlab.com/mygroup/myrepo'] }); // Pulls Docker images from a registry | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pullDockerImages().then(() => console.log('Docker images pulled successfully.')); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### 6. SSH Key Management | ||||||
|  |  | ||||||
|  | `npmci` also simplifies the management of SSH keys, which is crucial for accessing private repositories and servers. | ||||||
|  |  | ||||||
|  | **Preparing SSH Keys:** | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { Npmci } from '@ship.zone/npmci'; | ||||||
|  |  | ||||||
|  | async function prepareSshKeys() { | ||||||
|  |   const npmciInstance = new Npmci(); | ||||||
|  |   await npmciInstance.start(); | ||||||
|  |  | ||||||
|  |   await npmciInstance.sshManager.handleCli({ _: ['ssh', 'prepare'] }); // Prepares SSH keys from environment variables | ||||||
|  | } | ||||||
|  |  | ||||||
|  | prepareSshKeys().then(() => console.log('SSH keys prepared successfully.')); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### 7. Cloudron Integration | ||||||
|  |  | ||||||
|  | For users deploying applications on Cloudron, `npmci` provides a set of utilities for automating Cloudron tasks. | ||||||
|  |  | ||||||
|  | **Deploying to Cloudron:** | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { Npmci } from '@ship.zone/npmci'; | ||||||
|  |  | ||||||
|  | async function deployToCloudron() { | ||||||
|  |   const npmciInstance = new Npmci(); | ||||||
|  |   await npmciInstance.start(); | ||||||
|  |  | ||||||
|  |   await npmciInstance.cloudronManager.handleCli({ | ||||||
|  |     _: ['cloudron', 'deploy'] | ||||||
|  |   }); // Deploys application to Cloudron platform | ||||||
|  | } | ||||||
|  |  | ||||||
|  | deployToCloudron().then(() => console.log('Deployment to Cloudron completed.')); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | **Preparing Cloudron Manifest:** | ||||||
|  | Before deployment, replace version placeholders in the Cloudron Manifest: | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { Npmci } from '@ship.zone/npmci'; | ||||||
|  | import * as fs from 'fs'; | ||||||
|  | import * as path from 'path'; | ||||||
|  |  | ||||||
|  | async function prepareCloudronManifest(version: string) { | ||||||
|  |   const manifestPath = path.join(process.cwd(), "CloudronManifest.json"); | ||||||
|  |   let manifestFile = fs.readFileSync(manifestPath, { encoding: 'utf-8' }); | ||||||
|  |   manifestFile = manifestFile.replace(/##version##/g, version); | ||||||
|  |   fs.writeFileSync(manifestPath, manifestFile); | ||||||
|  |   console.log('CloudronManifest prepared'); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function deployWithPreparedManifest() { | ||||||
|  |   const npmciInstance = new Npmci(); | ||||||
|  |   await npmciInstance.start(); | ||||||
|  |    | ||||||
|  |   await prepareCloudronManifest('1.0.0'); | ||||||
|  |   await npmciInstance.cloudronManager.handleCli({ | ||||||
|  |     _: ['cloudron', 'deploy'] | ||||||
|  |   }); // Deploys application to Cloudron platform | ||||||
|  | } | ||||||
|  |  | ||||||
|  | deployWithPreparedManifest().then(() => console.log('Deployment to Cloudron with manifest preparation completed.')); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### 8. Webhook Triggers | ||||||
|  |  | ||||||
|  | `npmci` supports webhook triggers, allowing you to trigger builds and other activities based on various conditions. | ||||||
|  |  | ||||||
|  | **Triggering Webhooks:** | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { Npmci } from '@ship.zone/npmci'; | ||||||
|  |  | ||||||
|  | async function triggerWebhooks() { | ||||||
|  |   const npmciInstance = new Npmci(); | ||||||
|  |   await npmciInstance.start(); | ||||||
|  |  | ||||||
|  |   await npmciInstance.triggerManager.handleCli({ | ||||||
|  |     _: ['trigger'] | ||||||
|  |   }); // Triggers webhooks based on environment variables | ||||||
|  | } | ||||||
|  |  | ||||||
|  | triggerWebhooks().then(() => console.log('Webhooks triggered successfully.')); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### 9. Using the bash Helper | ||||||
|  |  | ||||||
|  | `npmci` includes a bash helper for executing commands within a bash shell, useful for various custom tasks. | ||||||
|  |  | ||||||
|  | **Using bash to Execute Commands:** | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { bash } from '@ship.zone/npmci'; | ||||||
|  |  | ||||||
|  | async function runCustomBashCommand(command: string) { | ||||||
|  |   const output = await bash(command); | ||||||
|  |   console.log('Command output:', output); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | runCustomBashCommand('echo Hello World').then(() => console.log('Custom command executed successfully.')); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Full Features and Use Cases | ||||||
|  |  | ||||||
|  | Below is a comprehensive set of features and use cases supported by `npmci`. This section ensures you can take full advantage of the library's capabilities in multiple scenarios. | ||||||
|  |  | ||||||
|  | ### Comprehensive Docker Workflow | ||||||
|  |  | ||||||
|  | **Step-by-step Docker Image Handling:** | ||||||
|  |  | ||||||
|  | 1. **Detect and Build All Dockerfiles:** | ||||||
|  |  | ||||||
|  |    ```typescript | ||||||
|  |    import { Npmci } from '@ship.zone/npmci'; | ||||||
|  |  | ||||||
|  |    async function detectAndBuildDockerfiles() { | ||||||
|  |      const npmciInstance = new Npmci(); | ||||||
|  |      await npmciInstance.start(); | ||||||
|  |      const dockerfiles = await npmciInstance.dockerManager.getDockerfiles(); | ||||||
|  |      console.log('Dockerfiles detected:', dockerfiles.map(d => d.filePath)); | ||||||
|  |       | ||||||
|  |      await npmciInstance.dockerManager.handleCli({ _: ['docker', 'build'] }); | ||||||
|  |      console.log('Dockerfiles built successfully.'); | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |    detectAndBuildDockerfiles().then(() => console.log('Docker detection and build process completed.')); | ||||||
|  |    ``` | ||||||
|  |  | ||||||
|  | 2. **Test All Dockerfiles:** | ||||||
|  |  | ||||||
|  |    ```typescript | ||||||
|  |    import { Npmci } from '@ship.zone/npmci'; | ||||||
|  |  | ||||||
|  |    async function testAllDockerfiles() { | ||||||
|  |      const npmciInstance = new Npmci(); | ||||||
|  |      await npmciInstance.start(); | ||||||
|  |      await npmciInstance.dockerManager.handleCli({ _: ['docker', 'test'] }); | ||||||
|  |      console.log('Dockerfiles tested successfully.'); | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |    testAllDockerfiles().then(() => console.log('Docker testing process completed.')); | ||||||
|  |    ``` | ||||||
|  |  | ||||||
|  | 3. **Push Dockerfiles to a Registry:** | ||||||
|  |  | ||||||
|  |    ```typescript | ||||||
|  |    import { Npmci } from '@ship.zone/npmci'; | ||||||
|  |  | ||||||
|  |    async function pushDockerfilesToRegistry() { | ||||||
|  |      const npmciInstance = new Npmci(); | ||||||
|  |      await npmciInstance.start(); | ||||||
|  |       | ||||||
|  |      await npmciInstance.dockerManager.handleCli({ _: ['docker', 'push'] }); | ||||||
|  |      console.log('Dockerfiles pushed to registry successfully.'); | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |    pushDockerfilesToRegistry().then(() => console.log('Docker push process completed.')); | ||||||
|  |    ``` | ||||||
|  |  | ||||||
|  | **Dockerfile Class Example:** | ||||||
|  |  | ||||||
|  | Here's a snippet showcasing how the `Dockerfile` class can be used to handle Dockerfile-specific operations: | ||||||
|  |  | ||||||
|  | ```typescript | ||||||
|  | import { Dockerfile } from '@ship.zone/npmci'; | ||||||
|  |  | ||||||
|  | async function handleDockerfileOperations() { | ||||||
|  |   // Initialize Dockerfile instances | ||||||
|  |   const dockerfile1 = new Dockerfile(/* required parameters */); | ||||||
|  |   const dockerfile2 = new Dockerfile(/* required parameters */); | ||||||
|  |  | ||||||
|  |   // Read and sort Dockerfiles | ||||||
|  |   const dockerfiles = await Dockerfile.readDockerfiles(/* required parameters */); | ||||||
|  |   const sortedDockerfiles = await Dockerfile.sortDockerfiles(dockerfiles); | ||||||
|  |  | ||||||
|  |   // Build and Test Dockerfiles | ||||||
|  |   await Dockerfile.buildDockerfiles(sortedDockerfiles); | ||||||
|  |   await Dockerfile.testDockerfiles(sortedDockerfiles); | ||||||
|  |  | ||||||
|  |   // Push Dockerfile images to a registry | ||||||
|  |   for (const dockerfile of sortedDockerfiles) { | ||||||
|  |     await dockerfile.push(/* registry and tag parameters */); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   console.log('Dockerfile operations completed successfully.'); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | handleDockerfileOperations().then(() => console.log('Dockerfile processing flow completed.')); | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | This completes the comprehensive guide to `@ship.zone/npmci`. With the examples and explanations provided, you should be able to harness the full power and flexibility of the library to streamline your CI/CD processes effectively. | ||||||
|  | undefined | ||||||
							
								
								
									
										2
									
								
								test/assets/Dockerfile_hello_##version##
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								test/assets/Dockerfile_hello_##version##
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | FROM mygroup/myrepo:sometag2 | ||||||
|  | RUN apt-get update | ||||||
| @@ -1 +1,9 @@ | |||||||
| {} | { | ||||||
|  |   "gitzone": { | ||||||
|  |     "module": { | ||||||
|  |       "githost": "code.foss.global", | ||||||
|  |       "gitscope": "mygroup", | ||||||
|  |       "gitrepo": "myrepo" | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										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 '@push.rocks/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(); | ||||||
							
								
								
									
										54
									
								
								test/test.ts
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								test/test.ts
									
									
									
									
									
								
							| @@ -1,7 +1,9 @@ | |||||||
| import { tap, expect } from '@pushrocks/tapbundle'; | import { tap, expect } from '@push.rocks/tapbundle'; | ||||||
| import * as path from 'path'; | import * as path from 'path'; | ||||||
|  | import * as smartpath from '@push.rocks/smartpath'; | ||||||
|  |  | ||||||
| process.env.NPMTS_TEST = 'true'; | process.env.NPMTS_TEST = 'true'; | ||||||
|  | process.env.NPMCI_URL_CLOUDLY = 'localhost'; | ||||||
|  |  | ||||||
| // set up environment | // set up environment | ||||||
| process.env.CI_REPOSITORY_URL = 'https://yyyyyy:xxxxxxxx@gitlab.com/mygroup/myrepo.git'; | process.env.CI_REPOSITORY_URL = 'https://yyyyyy:xxxxxxxx@gitlab.com/mygroup/myrepo.git'; | ||||||
| @@ -14,46 +16,49 @@ process.env.NPMCI_LOGIN_DOCKER = 'docker.io|someuser|somepass'; | |||||||
| process.env.NPMCI_SSHKEY_1 = 'hostString|somePrivKey|##'; | process.env.NPMCI_SSHKEY_1 = 'hostString|somePrivKey|##'; | ||||||
|  |  | ||||||
| process.cwd = () => { | process.cwd = () => { | ||||||
|   return path.join(__dirname, 'assets/'); |   return path.join(smartpath.get.dirnameFromImportMetaUrl(import.meta.url), 'assets/'); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| import * as npmci from '../ts'; | import type * as npmciTypes from '../ts/index.js'; | ||||||
|  | const npmci = await import('../ts/index.js'); | ||||||
|  |  | ||||||
| // ====== | // ====== | ||||||
| // Docker | // Docker | ||||||
| // ====== | // ====== | ||||||
|  |  | ||||||
| let dockerfile1: npmci.Dockerfile; | let dockerfile1: npmciTypes.Dockerfile; | ||||||
| let dockerfile2: npmci.Dockerfile; | let dockerfile2: npmciTypes.Dockerfile; | ||||||
| let sortableArray: npmci.Dockerfile[]; | let sortableArray: npmciTypes.Dockerfile[]; | ||||||
|  |  | ||||||
| tap.test('should return valid Dockerfiles', async () => { | tap.test('should return valid Dockerfiles', async () => { | ||||||
|   const npmciInstance = new npmci.Npmci(); |   const npmciInstance = new npmci.Npmci(); | ||||||
|  |   await npmciInstance.start(); | ||||||
|   dockerfile1 = new npmci.Dockerfile(npmciInstance.dockerManager, { |   dockerfile1 = new npmci.Dockerfile(npmciInstance.dockerManager, { | ||||||
|     filePath: './Dockerfile', |     filePath: './Dockerfile', | ||||||
|     read: true |     read: true, | ||||||
|   }); |   }); | ||||||
|   dockerfile2 = new npmci.Dockerfile(npmciInstance.dockerManager, { |   dockerfile2 = new npmci.Dockerfile(npmciInstance.dockerManager, { | ||||||
|     filePath: './Dockerfile_sometag1', |     filePath: './Dockerfile_sometag1', | ||||||
|     read: true |     read: true, | ||||||
|   }); |   }); | ||||||
|   expect(dockerfile1.version).to.equal('latest'); |   expect(dockerfile1.version).toEqual('latest'); | ||||||
|   return expect(dockerfile2.version).to.equal('sometag1'); |   return expect(dockerfile2.version).toEqual('sometag1'); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| tap.test('should read a directory of Dockerfiles', async () => { | tap.test('should read a directory of Dockerfiles', async () => { | ||||||
|   const npmciInstance = new npmci.Npmci(); |   const npmciInstance = new npmci.Npmci(); | ||||||
|  |   await npmciInstance.start(); | ||||||
|   return npmci.Dockerfile.readDockerfiles(npmciInstance.dockerManager).then( |   return npmci.Dockerfile.readDockerfiles(npmciInstance.dockerManager).then( | ||||||
|     async (readDockerfilesArrayArg: npmci.Dockerfile[]) => { |     async (readDockerfilesArrayArg: npmciTypes.Dockerfile[]) => { | ||||||
|       sortableArray = readDockerfilesArrayArg; |       sortableArray = readDockerfilesArrayArg; | ||||||
|       return expect(readDockerfilesArrayArg[1].version).to.equal('sometag1'); |       return expect(readDockerfilesArrayArg[1].version).toEqual('sometag1'); | ||||||
|     } |     } | ||||||
|   ); |   ); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| tap.test('should sort an array of Dockerfiles', async () => { | tap.test('should sort an array of Dockerfiles', async () => { | ||||||
|   return npmci.Dockerfile.sortDockerfiles(sortableArray).then( |   return npmci.Dockerfile.sortDockerfiles(sortableArray).then( | ||||||
|     async (sortedArrayArg: npmci.Dockerfile[]) => { |     async (sortedArrayArg: npmciTypes.Dockerfile[]) => { | ||||||
|       console.log(sortedArrayArg); |       console.log(sortedArrayArg); | ||||||
|     } |     } | ||||||
|   ); |   ); | ||||||
| @@ -61,29 +66,33 @@ tap.test('should sort an array of Dockerfiles', async () => { | |||||||
|  |  | ||||||
| tap.test('should build all Dockerfiles', async () => { | tap.test('should build all Dockerfiles', async () => { | ||||||
|   const npmciInstance = new npmci.Npmci(); |   const npmciInstance = new npmci.Npmci(); | ||||||
|  |   await npmciInstance.start(); | ||||||
|   return npmciInstance.dockerManager.handleCli({ |   return npmciInstance.dockerManager.handleCli({ | ||||||
|     _: ['docker', 'build'] |     _: ['docker', 'build'], | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| tap.test('should test all Dockerfiles', async () => { | tap.test('should test all Dockerfiles', async () => { | ||||||
|   const npmciInstance = new npmci.Npmci(); |   const npmciInstance = new npmci.Npmci(); | ||||||
|  |   await npmciInstance.start(); | ||||||
|   return npmciInstance.dockerManager.handleCli({ |   return npmciInstance.dockerManager.handleCli({ | ||||||
|     _: ['docker', 'test'] |     _: ['docker', 'test'], | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| tap.test('should test dockerfiles', async () => { | tap.test('should test dockerfiles', async () => { | ||||||
|   const npmciInstance = new npmci.Npmci(); |   const npmciInstance = new npmci.Npmci(); | ||||||
|  |   await npmciInstance.start(); | ||||||
|   return npmciInstance.dockerManager.handleCli({ |   return npmciInstance.dockerManager.handleCli({ | ||||||
|     _: ['docker', 'test'] |     _: ['docker', 'test'], | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| tap.test('should login docker daemon', async () => { | tap.test('should login docker daemon', async () => { | ||||||
|   const npmciInstance = new npmci.Npmci(); |   const npmciInstance = new npmci.Npmci(); | ||||||
|  |   await npmciInstance.start(); | ||||||
|   return npmciInstance.dockerManager.handleCli({ |   return npmciInstance.dockerManager.handleCli({ | ||||||
|     _: ['docker', 'login'] |     _: ['docker', 'login'], | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| @@ -91,9 +100,9 @@ tap.test('should login docker daemon', async () => { | |||||||
| // SSH | // SSH | ||||||
| // === | // === | ||||||
| tap.test('should prepare SSH keys', async () => { | tap.test('should prepare SSH keys', async () => { | ||||||
|   const npmciModSsh = await import('../ts/mod_ssh'); |   const npmciModSsh = await import('../ts/mod_ssh/index.js'); | ||||||
|   return await npmciModSsh.handleCli({ |   return await npmciModSsh.handleCli({ | ||||||
|     _: ['ssh', 'prepare'] |     _: ['ssh', 'prepare'], | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| @@ -102,14 +111,15 @@ tap.test('should prepare SSH keys', async () => { | |||||||
| // ==== | // ==== | ||||||
| tap.test('should install a certain version of node', async () => { | tap.test('should install a certain version of node', async () => { | ||||||
|   const npmciInstance = new npmci.Npmci(); |   const npmciInstance = new npmci.Npmci(); | ||||||
|  |   await npmciInstance.start(); | ||||||
|   await npmciInstance.nodejsManager.handleCli({ |   await npmciInstance.nodejsManager.handleCli({ | ||||||
|     _: ['node', 'install', 'stable'] |     _: ['node', 'install', 'stable'], | ||||||
|   }); |   }); | ||||||
|   await npmciInstance.nodejsManager.handleCli({ |   await npmciInstance.nodejsManager.handleCli({ | ||||||
|     _: ['node', 'install', 'lts'] |     _: ['node', 'install', 'lts'], | ||||||
|   }); |   }); | ||||||
|   await npmciInstance.nodejsManager.handleCli({ |   await npmciInstance.nodejsManager.handleCli({ | ||||||
|     _: ['node', 'install', 'legacy'] |     _: ['node', 'install', 'legacy'], | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								ts/00_commitinfo_data.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								ts/00_commitinfo_data.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | /** | ||||||
|  |  * autocreated commitinfo by @push.rocks/commitinfo | ||||||
|  |  */ | ||||||
|  | export const commitinfo = { | ||||||
|  |   name: '@ship.zone/npmci', | ||||||
|  |   version: '4.1.36', | ||||||
|  |   description: 'A tool to streamline Node.js and Docker workflows within CI environments, particularly GitLab CI, providing various CI/CD utilities.' | ||||||
|  | } | ||||||
| @@ -1,7 +1,7 @@ | |||||||
| import * as plugins from '../npmci.plugins'; | import * as plugins from '../npmci.plugins.js'; | ||||||
|  |  | ||||||
| import {Npmci} from '../npmci.classes.npmci'; | import { Npmci } from '../npmci.classes.npmci.js'; | ||||||
| import { logger } from '../npmci.logging'; | import { logger } from '../npmci.logging.js'; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * connects to cloudly |  * connects to cloudly | ||||||
| @@ -13,18 +13,19 @@ export class CloudlyConnector { | |||||||
|     this.npmciRef = npmciRefArg; |     this.npmciRef = npmciRefArg; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   public async announceDockerContainer( | ||||||
|   public async announceDockerContainer(optionsArg: plugins.servezoneInterfaces.IVersionData) { |     optionsArg: plugins.tsclass.container.IContainer, | ||||||
|     const cloudlyUrl = this.npmciRef.npmciConfig.getConfig().urlCloudly; |     testCloudlyUrlArg?: string | ||||||
|  |   ) { | ||||||
|  |     const cloudlyUrl = testCloudlyUrlArg || this.npmciRef.npmciConfig.getConfig().urlCloudly; | ||||||
|     if (!cloudlyUrl) { |     if (!cloudlyUrl) { | ||||||
|       logger.log('warn', 'no cloudly url provided. Thus we cannot announce the newly built Dockerimage!'); |       logger.log( | ||||||
|  |         'warn', | ||||||
|  |         'no cloudly url provided. Thus we cannot announce the newly built Dockerimage!' | ||||||
|  |       ); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const typedrequest = new plugins.typedrequest.TypedRequest< |     // lets push to cloudly here | ||||||
|       plugins.servezoneInterfaces.IRequest_Any_Cloudly_VersionManager_Update |  | ||||||
|     >(`https://${cloudlyUrl}/versionmanager`, 'update'); |  | ||||||
|  |  | ||||||
|     const response = (await typedrequest.fire(optionsArg)); |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								ts/index.ts
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								ts/index.ts
									
									
									
									
									
								
							| @@ -1,10 +1,10 @@ | |||||||
| import { Npmci } from './npmci.classes.npmci'; | import { Npmci } from './npmci.classes.npmci.js'; | ||||||
| import { Dockerfile } from './manager.docker/mod.classes.dockerfile'; | import { Dockerfile } from './manager.docker/mod.classes.dockerfile.js'; | ||||||
|  |  | ||||||
| export const npmciInstance = new Npmci(); | export const npmciInstance = new Npmci(); | ||||||
|  |  | ||||||
| export { Dockerfile, Npmci }; | export { Dockerfile, Npmci }; | ||||||
|  |  | ||||||
| if (process.env.CLI_CALL) { | export const runCli = async () => { | ||||||
|   npmciInstance.start(); |   await npmciInstance.start(); | ||||||
| } | }; | ||||||
|   | |||||||
							
								
								
									
										67
									
								
								ts/manager.cloudron/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								ts/manager.cloudron/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | |||||||
|  | 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'; | ||||||
|  | import { Npmci } from '../npmci.classes.npmci.js'; | ||||||
|  |  | ||||||
|  | export class NpmciCloudronManager { | ||||||
|  |   public npmciRef: Npmci; | ||||||
|  |  | ||||||
|  |   constructor(npmciArg: Npmci) { | ||||||
|  |     this.npmciRef = npmciArg; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * handle cli input | ||||||
|  |    * @param argvArg | ||||||
|  |    */ | ||||||
|  |   public handleCli = async (argvArg: any) => { | ||||||
|  |     if (argvArg._.length >= 2) { | ||||||
|  |       const action: string = argvArg._[1]; | ||||||
|  |       switch (action) { | ||||||
|  |         case 'deploy': | ||||||
|  |           await this.deploy(); | ||||||
|  |           break; | ||||||
|  |         default: | ||||||
|  |           logger.log('error', `>>npmci cloudron ...<< action >>${action}<< not supported`); | ||||||
|  |       } | ||||||
|  |     } else { | ||||||
|  |       logger.log( | ||||||
|  |         'info', | ||||||
|  |         `>>npmci cloudron ...<< cli arguments invalid... Please read the documentation.` | ||||||
|  |       ); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * Replaces the version string in CloudronManifest file | ||||||
|  |    * @param versionArg | ||||||
|  |    */ | ||||||
|  |   public deploy = async () => { | ||||||
|  |     logger.log('info', 'now deploying to cloudron...'); | ||||||
|  |     logger.log('info', 'installing cloudron cli...'); | ||||||
|  |     await bash(`pnpm install -g cloudron`); | ||||||
|  |     logger.log('ok', 'cloudron cli installed'); | ||||||
|  |  | ||||||
|  |     // lets set the version in the CloudronManifest file | ||||||
|  |     await this.prepareCloudronManifest(this.npmciRef.npmciConfig.getConfig().projectInfo.npm.version); | ||||||
|  |     logger.log('ok', 'CloudronManifest prepared'); | ||||||
|  |  | ||||||
|  |     // lets figure out the docker image tag | ||||||
|  |     const dockerImageTag = await this.npmciRef.npmciConfig.kvStorage.readKey('latestPushedDockerTag'); | ||||||
|  |     const appName = this.npmciRef.npmciConfig.getConfig().cloudronAppName; | ||||||
|  |      | ||||||
|  |     const cloudronEnvVar = process.env.NPMCI_LOGIN_CLOUDRON; | ||||||
|  |     const cloudronServer = cloudronEnvVar.split('|')[0]; | ||||||
|  |     const cloudronToken = cloudronEnvVar.split('|')[1]; | ||||||
|  |     await bash(`cloudron update --server ${cloudronServer} --token ${cloudronToken} --image ${dockerImageTag} --app ${appName}`); | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   private prepareCloudronManifest = async (versionArg: string) => { | ||||||
|  |     const manifestPath = plugins.path.join(paths.cwd, 'CloudronManifest.json'); | ||||||
|  |     let manifestFile = plugins.smartfile.fs.toStringSync(manifestPath); | ||||||
|  |     manifestFile = manifestFile.replace(/##version##/g, versionArg); | ||||||
|  |     plugins.smartfile.memory.toFsSync(manifestFile, manifestPath); | ||||||
|  |     logger.log('info', 'Version replaced in CloudronManifest file'); | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										1
									
								
								ts/manager.cloudron/mod.plugins.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								ts/manager.cloudron/mod.plugins.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | export * from '../npmci.plugins.js'; | ||||||
| @@ -1,13 +1,13 @@ | |||||||
| import { logger } from '../npmci.logging'; | import { logger } from '../npmci.logging.js'; | ||||||
| import * as plugins from './mod.plugins'; | import * as plugins from './mod.plugins.js'; | ||||||
| import * as paths from '../npmci.paths'; | import * as paths from '../npmci.paths.js'; | ||||||
| import { bash } from '../npmci.bash'; | import { bash } from '../npmci.bash.js'; | ||||||
|  |  | ||||||
| // classes | // classes | ||||||
| import { Npmci } from '../npmci.classes.npmci'; | import { Npmci } from '../npmci.classes.npmci.js'; | ||||||
| import { Dockerfile } from './mod.classes.dockerfile'; | import { Dockerfile } from './mod.classes.dockerfile.js'; | ||||||
| import { DockerRegistry } from './mod.classes.dockerregistry'; | import { DockerRegistry } from './mod.classes.dockerregistry.js'; | ||||||
| import { RegistryStorage } from './mod.classes.registrystorage'; | import { RegistryStorage } from './mod.classes.registrystorage.js'; | ||||||
|  |  | ||||||
| export class NpmciDockerManager { | export class NpmciDockerManager { | ||||||
|   public npmciRef: Npmci; |   public npmciRef: Npmci; | ||||||
| @@ -21,7 +21,7 @@ export class NpmciDockerManager { | |||||||
|    * handle cli input |    * handle cli input | ||||||
|    * @param argvArg |    * @param argvArg | ||||||
|    */ |    */ | ||||||
|   public handleCli = async argvArg => { |   public handleCli = async (argvArg: any) => { | ||||||
|     if (argvArg._.length >= 2) { |     if (argvArg._.length >= 2) { | ||||||
|       const action: string = argvArg._[1]; |       const action: string = argvArg._[1]; | ||||||
|       switch (action) { |       switch (action) { | ||||||
| @@ -50,7 +50,7 @@ export class NpmciDockerManager { | |||||||
|         `>>npmci docker ...<< cli arguments invalid... Please read the documentation.` |         `>>npmci docker ...<< cli arguments invalid... Please read the documentation.` | ||||||
|       ); |       ); | ||||||
|     } |     } | ||||||
|   } |   }; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * builds a cwd of Dockerfiles by triggering a promisechain |    * builds a cwd of Dockerfiles by triggering a promisechain | ||||||
| @@ -62,7 +62,7 @@ export class NpmciDockerManager { | |||||||
|       .then(Dockerfile.sortDockerfiles) |       .then(Dockerfile.sortDockerfiles) | ||||||
|       .then(Dockerfile.mapDockerfiles) |       .then(Dockerfile.mapDockerfiles) | ||||||
|       .then(Dockerfile.buildDockerfiles); |       .then(Dockerfile.buildDockerfiles); | ||||||
|   } |   }; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * login to the DockerRegistries |    * login to the DockerRegistries | ||||||
| @@ -70,41 +70,44 @@ export class NpmciDockerManager { | |||||||
|   public login = async () => { |   public login = async () => { | ||||||
|     await this.prepare(); |     await this.prepare(); | ||||||
|     await this.npmciRegistryStorage.loginAll(); |     await this.npmciRegistryStorage.loginAll(); | ||||||
|   } |   }; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * logs in docker |    * logs in docker | ||||||
|    */ |    */ | ||||||
|   public prepare = async () => { |   public 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.GITLAB_CI) { | ||||||
|       logger.log('error', 'No registry token specified by gitlab!'); |       console.log('gitlab ci detected'); | ||||||
|       process.exit(1); |       if (!process.env.CI_JOB_TOKEN || process.env.CI_JOB_TOKEN === '') { | ||||||
|  |         logger.log('error', 'Running in Gitlab CI, but no registry token specified by gitlab!'); | ||||||
|  |         process.exit(1); | ||||||
|  |       } | ||||||
|  |       this.npmciRegistryStorage.addRegistry( | ||||||
|  |         new DockerRegistry({ | ||||||
|  |           registryUrl: 'registry.gitlab.com', | ||||||
|  |           username: 'gitlab-ci-token', | ||||||
|  |           password: process.env.CI_JOB_TOKEN, | ||||||
|  |         }) | ||||||
|  |       ); | ||||||
|     } |     } | ||||||
|     this.npmciRegistryStorage.addRegistry( |  | ||||||
|       new DockerRegistry({ |  | ||||||
|         registryUrl: 'registry.gitlab.com', |  | ||||||
|         username: 'gitlab-ci-token', |  | ||||||
|         password: process.env.CI_BUILD_TOKEN |  | ||||||
|       }) |  | ||||||
|     ); |  | ||||||
|  |  | ||||||
|     // handle registries |     // handle registries | ||||||
|     await plugins.smartparam.forEachMinimatch( |     await plugins.smartobject.forEachMinimatch( | ||||||
|       process.env, |       process.env, | ||||||
|       'NPMCI_LOGIN_DOCKER*', |       'NPMCI_LOGIN_DOCKER*', | ||||||
|       async envString => { |       async (envString: string) => { | ||||||
|         this.npmciRegistryStorage.addRegistry(DockerRegistry.fromEnvString(envString)); |         this.npmciRegistryStorage.addRegistry(DockerRegistry.fromEnvString(envString)); | ||||||
|       } |       } | ||||||
|     ); |     ); | ||||||
|     return; |     return; | ||||||
|   } |   }; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * pushes an image towards a registry |    * pushes an image towards a registry | ||||||
|    * @param argvArg |    * @param argvArg | ||||||
|    */ |    */ | ||||||
|   public push = async argvArg => { |   public push = async (argvArg: any) => { | ||||||
|     await this.prepare(); |     await this.prepare(); | ||||||
|     let dockerRegistryUrls: string[] = []; |     let dockerRegistryUrls: string[] = []; | ||||||
|  |  | ||||||
| @@ -134,7 +137,9 @@ export class NpmciDockerManager { | |||||||
|       const dockerfileArray = await Dockerfile.readDockerfiles(this) |       const dockerfileArray = await Dockerfile.readDockerfiles(this) | ||||||
|         .then(Dockerfile.sortDockerfiles) |         .then(Dockerfile.sortDockerfiles) | ||||||
|         .then(Dockerfile.mapDockerfiles); |         .then(Dockerfile.mapDockerfiles); | ||||||
|       const dockerRegistryToPushTo = this.npmciRegistryStorage.getRegistryByUrl(dockerRegistryUrl); |       const dockerRegistryToPushTo = await this.npmciRegistryStorage.getRegistryByUrl( | ||||||
|  |         dockerRegistryUrl | ||||||
|  |       ); | ||||||
|       if (!dockerRegistryToPushTo) { |       if (!dockerRegistryToPushTo) { | ||||||
|         logger.log( |         logger.log( | ||||||
|           'error', |           'error', | ||||||
| @@ -146,26 +151,26 @@ export class NpmciDockerManager { | |||||||
|         await dockerfile.push(dockerRegistryToPushTo, suffix); |         await dockerfile.push(dockerRegistryToPushTo, suffix); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   }; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * pulls an image |    * pulls an image | ||||||
|    */ |    */ | ||||||
|   public pull = async argvArg => { |   public pull = async (argvArg: any) => { | ||||||
|     await this.prepare(); |     await this.prepare(); | ||||||
|     const 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]; | ||||||
|     } |     } | ||||||
|     const localDockerRegistry = this.npmciRegistryStorage.getRegistryByUrl(registryUrlArg); |     const localDockerRegistry = await this.npmciRegistryStorage.getRegistryByUrl(registryUrlArg); | ||||||
|     const dockerfileArray = await Dockerfile.readDockerfiles(this) |     const dockerfileArray = await Dockerfile.readDockerfiles(this) | ||||||
|       .then(Dockerfile.sortDockerfiles) |       .then(Dockerfile.sortDockerfiles) | ||||||
|       .then(Dockerfile.mapDockerfiles); |       .then(Dockerfile.mapDockerfiles); | ||||||
|     for (const dockerfile of dockerfileArray) { |     for (const dockerfile of dockerfileArray) { | ||||||
|       await dockerfile.pull(localDockerRegistry, suffix); |       await dockerfile.pull(localDockerRegistry, suffix); | ||||||
|     } |     } | ||||||
|   } |   }; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * tests docker files |    * tests docker files | ||||||
| @@ -173,5 +178,13 @@ export class NpmciDockerManager { | |||||||
|   public test = async () => { |   public test = async () => { | ||||||
|     await this.prepare(); |     await this.prepare(); | ||||||
|     return await Dockerfile.readDockerfiles(this).then(Dockerfile.testDockerfiles); |     return await Dockerfile.readDockerfiles(this).then(Dockerfile.testDockerfiles); | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * can be used to get the Dockerfiles in the directory | ||||||
|  |    */ | ||||||
|  |   getDockerfiles = async () => { | ||||||
|  |     const dockerfiles = await Dockerfile.readDockerfiles(this); | ||||||
|  |     return dockerfiles; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,13 +1,13 @@ | |||||||
| import * as plugins from './mod.plugins'; | import * as plugins from './mod.plugins.js'; | ||||||
| import * as paths from '../npmci.paths'; | import * as paths from '../npmci.paths.js'; | ||||||
|  |  | ||||||
| import { logger } from '../npmci.logging'; | import { logger } from '../npmci.logging.js'; | ||||||
| import { bash } from '../npmci.bash'; | import { bash } from '../npmci.bash.js'; | ||||||
|  |  | ||||||
| import { DockerRegistry } from './mod.classes.dockerregistry'; | import { DockerRegistry } from './mod.classes.dockerregistry.js'; | ||||||
| import * as helpers from './mod.helpers'; | import * as helpers from './mod.helpers.js'; | ||||||
| import { NpmciDockerManager } from '.'; | import { NpmciDockerManager } from './index.js'; | ||||||
| import { Npmci } from '../npmci.classes.npmci'; | import { Npmci } from '../npmci.classes.npmci.js'; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * class Dockerfile represents a Dockerfile on disk in npmci |  * class Dockerfile represents a Dockerfile on disk in npmci | ||||||
| @@ -31,7 +31,7 @@ export class Dockerfile { | |||||||
|     for (const dockerfilePath of fileTree) { |     for (const dockerfilePath of fileTree) { | ||||||
|       const myDockerfile = new Dockerfile(npmciDockerManagerRefArg, { |       const myDockerfile = new Dockerfile(npmciDockerManagerRefArg, { | ||||||
|         filePath: dockerfilePath, |         filePath: dockerfilePath, | ||||||
|         read: true |         read: true, | ||||||
|       }); |       }); | ||||||
|       readDockerfilesArray.push(myDockerfile); |       readDockerfilesArray.push(myDockerfile); | ||||||
|     } |     } | ||||||
| @@ -40,50 +40,80 @@ export class Dockerfile { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * sorts Dockerfiles into a dependency chain |    * Sorts Dockerfiles into a build order based on dependencies. | ||||||
|    * @param sortableArrayArg an array of instances of class Dockerfile |    * @param dockerfiles An array of Dockerfile instances. | ||||||
|    * @returns Promise<Dockerfile[]> |    * @returns A Promise that resolves to a sorted array of Dockerfiles. | ||||||
|    */ |    */ | ||||||
|   public static async sortDockerfiles(sortableArrayArg: Dockerfile[]): Promise<Dockerfile[]> { |   public static async sortDockerfiles(dockerfiles: Dockerfile[]): Promise<Dockerfile[]> { | ||||||
|     const done = plugins.smartpromise.defer<Dockerfile[]>(); |     logger.log('info', 'Sorting Dockerfiles based on dependencies...'); | ||||||
|     logger.log('info', 'sorting Dockerfiles:'); |  | ||||||
|     const sortedArray: Dockerfile[] = []; |     // Map from cleanTag to Dockerfile instance for quick lookup | ||||||
|     const cleanTagsOriginal = Dockerfile.cleanTagsArrayFunction(sortableArrayArg, sortedArray); |     const tagToDockerfile = new Map<string, Dockerfile>(); | ||||||
|     let sorterFunctionCounter: number = 0; |     dockerfiles.forEach((dockerfile) => { | ||||||
|     const sorterFunction = () => { |       tagToDockerfile.set(dockerfile.cleanTag, dockerfile); | ||||||
|       sortableArrayArg.forEach(dockerfileArg => { |     }); | ||||||
|         const cleanTags = Dockerfile.cleanTagsArrayFunction(sortableArrayArg, sortedArray); |  | ||||||
|         if ( |     // Build the dependency graph | ||||||
|           cleanTags.indexOf(dockerfileArg.baseImage) === -1 && |     const graph = new Map<Dockerfile, Dockerfile[]>(); | ||||||
|           sortedArray.indexOf(dockerfileArg) === -1 |     dockerfiles.forEach((dockerfile) => { | ||||||
|         ) { |       const dependencies: Dockerfile[] = []; | ||||||
|           sortedArray.push(dockerfileArg); |       const baseImage = dockerfile.baseImage; | ||||||
|         } |  | ||||||
|         if (cleanTagsOriginal.indexOf(dockerfileArg.baseImage) !== -1) { |       // Check if the baseImage is among the local Dockerfiles | ||||||
|           dockerfileArg.localBaseImageDependent = true; |       if (tagToDockerfile.has(baseImage)) { | ||||||
|         } |         const baseDockerfile = tagToDockerfile.get(baseImage); | ||||||
|       }); |         dependencies.push(baseDockerfile); | ||||||
|       if (sortableArrayArg.length === sortedArray.length) { |         dockerfile.localBaseImageDependent = true; | ||||||
|         let counter = 1; |         dockerfile.localBaseDockerfile = baseDockerfile; | ||||||
|         for (const dockerfile of sortedArray) { |       } | ||||||
|           logger.log('info', `tag ${counter}: -> ${dockerfile.cleanTag}`); |  | ||||||
|           counter++; |       graph.set(dockerfile, dependencies); | ||||||
|         } |     }); | ||||||
|         done.resolve(sortedArray); |  | ||||||
|       } else if (sorterFunctionCounter < 10) { |     // Perform topological sort | ||||||
|         sorterFunctionCounter++; |     const sortedDockerfiles: Dockerfile[] = []; | ||||||
|         sorterFunction(); |     const visited = new Set<Dockerfile>(); | ||||||
|  |     const tempMarked = new Set<Dockerfile>(); | ||||||
|  |  | ||||||
|  |     const visit = (dockerfile: Dockerfile) => { | ||||||
|  |       if (tempMarked.has(dockerfile)) { | ||||||
|  |         throw new Error(`Circular dependency detected involving ${dockerfile.cleanTag}`); | ||||||
|  |       } | ||||||
|  |       if (!visited.has(dockerfile)) { | ||||||
|  |         tempMarked.add(dockerfile); | ||||||
|  |         const dependencies = graph.get(dockerfile) || []; | ||||||
|  |         dependencies.forEach((dep) => visit(dep)); | ||||||
|  |         tempMarked.delete(dockerfile); | ||||||
|  |         visited.add(dockerfile); | ||||||
|  |         sortedDockerfiles.push(dockerfile); | ||||||
|       } |       } | ||||||
|     }; |     }; | ||||||
|     sorterFunction(); |  | ||||||
|     return done.promise; |     try { | ||||||
|  |       dockerfiles.forEach((dockerfile) => { | ||||||
|  |         if (!visited.has(dockerfile)) { | ||||||
|  |           visit(dockerfile); | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |     } catch (error) { | ||||||
|  |       logger.log('error', error.message); | ||||||
|  |       throw error; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Log the sorted order | ||||||
|  |     sortedDockerfiles.forEach((dockerfile, index) => { | ||||||
|  |       logger.log('info', `Build order ${index + 1}: ${dockerfile.cleanTag} | ||||||
|  |       with base image ${dockerfile.baseImage}`); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     return sortedDockerfiles; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * maps local Dockerfiles dependencies to the correspoding Dockerfile class instances |    * maps local Dockerfiles dependencies to the correspoding Dockerfile class instances | ||||||
|    */ |    */ | ||||||
|   public static async mapDockerfiles(sortedDockerfileArray: Dockerfile[]): Promise<Dockerfile[]> { |   public static async mapDockerfiles(sortedDockerfileArray: Dockerfile[]): Promise<Dockerfile[]> { | ||||||
|     sortedDockerfileArray.forEach(dockerfileArg => { |     sortedDockerfileArray.forEach((dockerfileArg) => { | ||||||
|       if (dockerfileArg.localBaseImageDependent) { |       if (dockerfileArg.localBaseImageDependent) { | ||||||
|         sortedDockerfileArray.forEach((dockfile2: Dockerfile) => { |         sortedDockerfileArray.forEach((dockfile2: Dockerfile) => { | ||||||
|           if (dockfile2.cleanTag === dockerfileArg.baseImage) { |           if (dockfile2.cleanTag === dockerfileArg.baseImage) { | ||||||
| @@ -120,15 +150,23 @@ export class Dockerfile { | |||||||
|    * returns a version for a docker file |    * returns a version for a docker file | ||||||
|    * @execution SYNC |    * @execution SYNC | ||||||
|    */ |    */ | ||||||
|   public static dockerFileVersion(dockerfileNameArg: string): string { |   public static dockerFileVersion( | ||||||
|  |     dockerfileInstanceArg: Dockerfile, | ||||||
|  |     dockerfileNameArg: string | ||||||
|  |   ): string { | ||||||
|     let versionString: string; |     let versionString: string; | ||||||
|     const versionRegex = /Dockerfile_([a-zA-Z0-9\.]*)$/; |     const versionRegex = /Dockerfile_(.+)$/; | ||||||
|     const 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 { | ||||||
|       versionString = 'latest'; |       versionString = 'latest'; | ||||||
|     } |     } | ||||||
|  |     versionString = versionString.replace( | ||||||
|  |       '##version##', | ||||||
|  |       dockerfileInstanceArg.npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().projectInfo.npm | ||||||
|  |         .version | ||||||
|  |     ); | ||||||
|     return versionString; |     return versionString; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -152,9 +190,8 @@ export class Dockerfile { | |||||||
|     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 | ||||||
|     const mappedRepo = npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().dockerRegistryRepoMap[ |     const mappedRepo = | ||||||
|       registryArg |       npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().dockerRegistryRepoMap[registryArg]; | ||||||
|     ]; |  | ||||||
|     const repo = (() => { |     const repo = (() => { | ||||||
|       if (mappedRepo) { |       if (mappedRepo) { | ||||||
|         return mappedRepo; |         return mappedRepo; | ||||||
| @@ -178,34 +215,21 @@ export class Dockerfile { | |||||||
|   ): Promise<string> { |   ): Promise<string> { | ||||||
|     logger.log('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 (const key of Object.keys( |     for (const dockerArgKey of Object.keys( | ||||||
|       npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().dockerBuildargEnvMap |       npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().dockerBuildargEnvMap | ||||||
|     )) { |     )) { | ||||||
|       const targetValue = |       const dockerArgOuterEnvVar = | ||||||
|         process.env[ |         npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().dockerBuildargEnvMap[dockerArgKey]; | ||||||
|           npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().dockerBuildargEnvMap[key] |       logger.log( | ||||||
|         ]; |         'note', | ||||||
|       buildArgsString = `${buildArgsString} --build-arg ${key}="${targetValue}"`; |         `docker ARG "${dockerArgKey}" maps to outer env var "${dockerArgOuterEnvVar}"` | ||||||
|  |       ); | ||||||
|  |       const targetValue = process.env[dockerArgOuterEnvVar]; | ||||||
|  |       buildArgsString = `${buildArgsString} --build-arg ${dockerArgKey}="${targetValue}"`; | ||||||
|     } |     } | ||||||
|     return buildArgsString; |     return buildArgsString; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |  | ||||||
|    * |  | ||||||
|    */ |  | ||||||
|   public static cleanTagsArrayFunction( |  | ||||||
|     dockerfileArrayArg: Dockerfile[], |  | ||||||
|     trackingArrayArg: Dockerfile[] |  | ||||||
|   ): string[] { |  | ||||||
|     const cleanTagsArray: string[] = []; |  | ||||||
|     dockerfileArrayArg.forEach(dockerfileArg => { |  | ||||||
|       if (trackingArrayArg.indexOf(dockerfileArg) === -1) { |  | ||||||
|         cleanTagsArray.push(dockerfileArg.cleanTag); |  | ||||||
|       } |  | ||||||
|     }); |  | ||||||
|     return cleanTagsArray; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // INSTANCE |   // INSTANCE | ||||||
|   public npmciDockerManagerRef: NpmciDockerManager; |   public npmciDockerManagerRef: NpmciDockerManager; | ||||||
|  |  | ||||||
| @@ -231,7 +255,7 @@ export class Dockerfile { | |||||||
|       this.npmciDockerManagerRef.npmciRef.npmciEnv.repo.user + |       this.npmciDockerManagerRef.npmciRef.npmciEnv.repo.user + | ||||||
|       '/' + |       '/' + | ||||||
|       this.npmciDockerManagerRef.npmciRef.npmciEnv.repo.repo; |       this.npmciDockerManagerRef.npmciRef.npmciEnv.repo.repo; | ||||||
|     this.version = Dockerfile.dockerFileVersion(plugins.path.parse(options.filePath).base); |     this.version = Dockerfile.dockerFileVersion(this, plugins.path.parse(options.filePath).base); | ||||||
|     this.cleanTag = this.repo + ':' + this.version; |     this.cleanTag = this.repo + ':' + this.version; | ||||||
|     this.buildTag = this.cleanTag; |     this.buildTag = this.cleanTag; | ||||||
|  |  | ||||||
| @@ -269,17 +293,20 @@ export class Dockerfile { | |||||||
|     ); |     ); | ||||||
|     await bash(`docker tag ${this.buildTag} ${this.pushTag}`); |     await bash(`docker tag ${this.buildTag} ${this.pushTag}`); | ||||||
|     await bash(`docker push ${this.pushTag}`); |     await bash(`docker push ${this.pushTag}`); | ||||||
|     console.log('you can get the digest using this command'); |     const imageDigest = ( | ||||||
|     console.log(`docker inspect --format="{{index .RepoDigests 0}}" ${this.pushTag}`); |       await bash(`docker inspect --format="{{index .RepoDigests 0}}" ${this.pushTag}`) | ||||||
|     const imageDigest = await bash( |     ).split('@')[1]; | ||||||
|       `docker inspect --format="{{index .RepoDigests 0}}" ${this.pushTag}` |     console.log(`The image ${this.pushTag} has digest ${imageDigest}`); | ||||||
|     ); |  | ||||||
|     console.log(imageDigest); |  | ||||||
|     await this.npmciDockerManagerRef.npmciRef.cloudlyConnector.announceDockerContainer({ |     await this.npmciDockerManagerRef.npmciRef.cloudlyConnector.announceDockerContainer({ | ||||||
|       dockerImageUrl: this.pushTag, |       registryUrl: this.pushTag, | ||||||
|       dockerImageVersion: this.npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().projectInfo |       tag: this.buildTag, | ||||||
|         .npm.version |       labels: [], | ||||||
|  |       version: this.npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().projectInfo.npm.version, | ||||||
|     }); |     }); | ||||||
|  |     await this.npmciDockerManagerRef.npmciRef.npmciConfig.kvStorage.writeKey( | ||||||
|  |       'latestPushedDockerTag', | ||||||
|  |       this.pushTag | ||||||
|  |     ); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| import { logger } from '../npmci.logging'; | import { logger } from '../npmci.logging.js'; | ||||||
| import * as plugins from './mod.plugins'; | import * as plugins from './mod.plugins.js'; | ||||||
| import { bash } from '../npmci.bash'; | import { bash } from '../npmci.bash.js'; | ||||||
|  |  | ||||||
| export interface IDockerRegistryConstructorOptions { | export interface IDockerRegistryConstructorOptions { | ||||||
|   registryUrl: string; |   registryUrl: string; | ||||||
| @@ -26,13 +26,13 @@ export class DockerRegistry { | |||||||
|       process.exit(1); |       process.exit(1); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|     const registryUrl = dockerRegexResultArray[0]; |     const registryUrl = dockerRegexResultArray[0].replace('https://', '').replace('http://', ''); | ||||||
|     const username = dockerRegexResultArray[1]; |     const username = dockerRegexResultArray[1]; | ||||||
|     const password = dockerRegexResultArray[2]; |     const password = dockerRegexResultArray[2]; | ||||||
|     return new DockerRegistry({ |     return new DockerRegistry({ | ||||||
|       registryUrl: registryUrl, |       registryUrl: registryUrl, | ||||||
|       username: username, |       username: username, | ||||||
|       password: password |       password: password, | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,11 +1,10 @@ | |||||||
| import { logger } from '../npmci.logging'; | import { logger } from '../npmci.logging.js'; | ||||||
| import * as plugins from './mod.plugins'; | 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 { | export class RegistryStorage { | ||||||
|   objectMap = new Objectmap<DockerRegistry>(); |   objectMap = new plugins.lik.ObjectMap<DockerRegistry>(); | ||||||
|   constructor() { |   constructor() { | ||||||
|     // Nothing here |     // Nothing here | ||||||
|   } |   } | ||||||
| @@ -15,13 +14,13 @@ export class RegistryStorage { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   getRegistryByUrl(registryUrlArg: string) { |   getRegistryByUrl(registryUrlArg: string) { | ||||||
|     return this.objectMap.find(registryArg => { |     return this.objectMap.findSync((registryArg) => { | ||||||
|       return registryArg.registryUrl === registryUrlArg; |       return registryArg.registryUrl === registryUrlArg; | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   async loginAll() { |   async loginAll() { | ||||||
|     await this.objectMap.forEach(async registryArg => { |     await this.objectMap.forEach(async (registryArg) => { | ||||||
|       await registryArg.login(); |       await registryArg.login(); | ||||||
|     }); |     }); | ||||||
|     logger.log('success', 'logged in successfully into all available DockerRegistries!'); |     logger.log('success', 'logged in successfully into all available DockerRegistries!'); | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import { logger } from '../npmci.logging'; | import { logger } from '../npmci.logging.js'; | ||||||
| import * as plugins from './mod.plugins'; | import * as plugins from './mod.plugins.js'; | ||||||
| import * as paths from '../npmci.paths'; | 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 { logger } from '../npmci.logging.js'; | ||||||
| import * as plugins from './mod.plugins'; | import * as plugins from './mod.plugins.js'; | ||||||
| import { bash } from '../npmci.bash'; | import { bash, bashNoError } from '../npmci.bash.js'; | ||||||
| import { Npmci } from '../npmci.classes.npmci'; | import { Npmci } from '../npmci.classes.npmci.js'; | ||||||
|  |  | ||||||
| export class NpmciGitManager { | export class NpmciGitManager { | ||||||
|   public npmciRef: Npmci; |   public npmciRef: Npmci; | ||||||
| @@ -14,7 +14,7 @@ export class NpmciGitManager { | |||||||
|    * handle cli input |    * handle cli input | ||||||
|    * @param argvArg |    * @param argvArg | ||||||
|    */ |    */ | ||||||
|   public handleCli = async argvArg => { |   public handleCli = async (argvArg: any) => { | ||||||
|     if (argvArg._.length >= 2) { |     if (argvArg._.length >= 2) { | ||||||
|       const action: string = argvArg._[1]; |       const action: string = argvArg._[1]; | ||||||
|       switch (action) { |       switch (action) { | ||||||
| @@ -32,7 +32,7 @@ export class NpmciGitManager { | |||||||
|   public mirror = async () => { |   public mirror = async () => { | ||||||
|     const githubToken = process.env.NPMCI_GIT_GITHUBTOKEN; |     const githubToken = process.env.NPMCI_GIT_GITHUBTOKEN; | ||||||
|     const githubUser = process.env.NPMCI_GIT_GITHUBGROUP || this.npmciRef.npmciEnv.repo.user; |     const githubUser = process.env.NPMCI_GIT_GITHUBGROUP || this.npmciRef.npmciEnv.repo.user; | ||||||
|     const githubRepo = process.env.NPMCI_GIT_GITHUB || this.npmciRef.npmciEnv.repo; |     const githubRepo = process.env.NPMCI_GIT_GITHUB || this.npmciRef.npmciEnv.repo.repo; | ||||||
|     if ( |     if ( | ||||||
|       this.npmciRef.npmciConfig.getConfig().projectInfo.npm.packageJson.private === true || |       this.npmciRef.npmciConfig.getConfig().projectInfo.npm.packageJson.private === true || | ||||||
|       this.npmciRef.npmciConfig.getConfig().npmAccessLevel === 'private' |       this.npmciRef.npmciConfig.getConfig().npmAccessLevel === 'private' | ||||||
| @@ -47,16 +47,22 @@ export class NpmciGitManager { | |||||||
|       logger.log('info', 'found github token.'); |       logger.log('info', 'found github token.'); | ||||||
|       logger.log('info', 'attempting the mirror the repository to GitHub'); |       logger.log('info', 'attempting the mirror the repository to GitHub'); | ||||||
|  |  | ||||||
|       // plugins.smartgit.GitRepo; |       // remove old mirrors | ||||||
|  |       await bashNoError('git remote rm mirror'); | ||||||
|  |  | ||||||
|  |       await bash(`git fetch`); | ||||||
|       // add the mirror |       // add the mirror | ||||||
|       await bash( |       await bashNoError( | ||||||
|         `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 bashNoError(`git push mirror --all`); | ||||||
|  |       await bashNoError(`git checkout origin/master`); | ||||||
|  |       await bashNoError(`git push mirror master`); | ||||||
|       logger.log('ok', 'pushed all branches to mirror!'); |       logger.log('ok', 'pushed all branches to mirror!'); | ||||||
|       await bash(`git push mirror --tags`); |       await bashNoError(`git push mirror --tags`); | ||||||
|       logger.log('ok', 'pushed all tags to mirror!'); |       logger.log('ok', 'pushed all tags to mirror!'); | ||||||
|  |       // remove old mirrors | ||||||
|  |       await bashNoError('git remote rm mirror'); | ||||||
|     } else { |     } else { | ||||||
|       logger.log('error', `cannot find NPMCI_GIT_GITHUBTOKEN env var!`); |       logger.log('error', `cannot find NPMCI_GIT_GITHUBTOKEN env var!`); | ||||||
|       process.exit(1); |       process.exit(1); | ||||||
|   | |||||||
| @@ -1,5 +1 @@ | |||||||
| export * from '../npmci.plugins'; | export * from '../npmci.plugins.js'; | ||||||
|  |  | ||||||
| import * as smartgit from '@pushrocks/smartgit'; |  | ||||||
|  |  | ||||||
| export { smartgit }; |  | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| import * as plugins from '../npmci.plugins'; | import * as plugins from '../npmci.plugins.js'; | ||||||
| import * as paths from '../npmci.paths'; | import * as paths from '../npmci.paths.js'; | ||||||
|  |  | ||||||
| import { logger } from '../npmci.logging'; | import { logger } from '../npmci.logging.js'; | ||||||
| import { bash, bashNoError, nvmAvailable } from '../npmci.bash'; | import { bash, bashNoError, nvmAvailable } from '../npmci.bash.js'; | ||||||
| import { Npmci } from '../npmci.classes.npmci'; | import { Npmci } from '../npmci.classes.npmci.js'; | ||||||
|  |  | ||||||
| export class NpmciNodeJsManager { | export class NpmciNodeJsManager { | ||||||
|   public npmciRef: Npmci; |   public npmciRef: Npmci; | ||||||
| @@ -16,7 +16,7 @@ export class NpmciNodeJsManager { | |||||||
|    * handle cli input |    * handle cli input | ||||||
|    * @param argvArg |    * @param argvArg | ||||||
|    */ |    */ | ||||||
|   public async handleCli(argvArg) { |   public async handleCli(argvArg: any) { | ||||||
|     if (argvArg._.length >= 3) { |     if (argvArg._.length >= 3) { | ||||||
|       const action: string = argvArg._[1]; |       const action: string = argvArg._[1]; | ||||||
|       switch (action) { |       switch (action) { | ||||||
| @@ -40,15 +40,15 @@ export class NpmciNodeJsManager { | |||||||
|    * Install a specific version of node |    * Install a specific version of node | ||||||
|    * @param versionArg |    * @param versionArg | ||||||
|    */ |    */ | ||||||
|   public async install(versionArg) { |   public async install(versionArg: any) { | ||||||
|     logger.log('info', `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 = '12'; |       version = '18'; | ||||||
|     } else if (versionArg === 'lts') { |     } else if (versionArg === 'lts') { | ||||||
|       version = '10'; |       version = '16'; | ||||||
|     } else if (versionArg === 'legacy') { |     } else if (versionArg === 'legacy') { | ||||||
|       version = '8'; |       version = '14'; | ||||||
|     } else { |     } else { | ||||||
|       version = versionArg; |       version = versionArg; | ||||||
|     } |     } | ||||||
| @@ -62,7 +62,6 @@ export class NpmciNodeJsManager { | |||||||
|     await bash('npm install -g npm'); |     await bash('npm install -g npm'); | ||||||
|     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 | ||||||
|     const config = await this.npmciRef.npmciConfig.getConfig(); |     const config = await this.npmciRef.npmciConfig.getConfig(); | ||||||
|   | |||||||
| @@ -1,13 +1,14 @@ | |||||||
| import * as plugins from './mod.plugins'; | import * as plugins from './mod.plugins.js'; | ||||||
|  | import * as paths from '../npmci.paths.js'; | ||||||
|  |  | ||||||
| import { logger } from '../npmci.logging'; | import { logger } from '../npmci.logging.js'; | ||||||
| import { bash, bashNoError, nvmAvailable } from '../npmci.bash'; | import { bash, bashNoError, nvmAvailable } from '../npmci.bash.js'; | ||||||
| import { Npmci } from '../npmci.classes.npmci'; | import { Npmci } from '../npmci.classes.npmci.js'; | ||||||
|  |  | ||||||
| export class NpmciNpmManager { | export class NpmciNpmManager { | ||||||
|   public npmciRef: Npmci; |   public npmciRef: Npmci; | ||||||
|  |  | ||||||
|   constructor(npmciRefArg) { |   constructor(npmciRefArg: Npmci) { | ||||||
|     this.npmciRef = npmciRefArg; |     this.npmciRef = npmciRefArg; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -15,13 +16,16 @@ export class NpmciNpmManager { | |||||||
|    * handle cli input |    * handle cli input | ||||||
|    * @param argvArg |    * @param argvArg | ||||||
|    */ |    */ | ||||||
|   public async handleCli(argvArg) { |   public async handleCli(argvArg: any) { | ||||||
|     if (argvArg._.length >= 2) { |     if (argvArg._.length >= 2) { | ||||||
|       const action: string = argvArg._[1]; |       const action: string = argvArg._[1]; | ||||||
|       switch (action) { |       switch (action) { | ||||||
|         case 'install': |         case 'install': | ||||||
|           await this.install(); |           await this.install(); | ||||||
|           break; |           break; | ||||||
|  |         case 'build': | ||||||
|  |           await this.build(); | ||||||
|  |           break; | ||||||
|         case 'prepare': |         case 'prepare': | ||||||
|           await this.prepare(); |           await this.prepare(); | ||||||
|           break; |           break; | ||||||
| @@ -48,15 +52,29 @@ export class NpmciNpmManager { | |||||||
|    * authenticates npm with token from env var |    * authenticates npm with token from env var | ||||||
|    */ |    */ | ||||||
|   public async prepare() { |   public async prepare() { | ||||||
|  |     logger.log('info', 'running >>npm prepare<<'); | ||||||
|     const config = this.npmciRef.npmciConfig.getConfig(); |     const config = this.npmciRef.npmciConfig.getConfig(); | ||||||
|     let npmrcFileString: string = ''; |     let npmrcFileString: string = ''; | ||||||
|     await plugins.smartparam.forEachMinimatch(process.env, 'NPMCI_TOKEN_NPM*', npmEnvArg => { |     await plugins.smartobject.forEachMinimatch( | ||||||
|       const npmRegistryUrl = npmEnvArg.split('|')[0]; |       process.env, | ||||||
|       const npmToken = npmEnvArg.split('|')[1]; |       'NPMCI_TOKEN_NPM*', | ||||||
|       npmrcFileString += `//${npmRegistryUrl}/:_authToken="${plugins.smartstring.base64.decode( |       (npmEnvArg: string) => { | ||||||
|         npmToken |         if (!npmEnvArg) { | ||||||
|       )}"\n`; |           logger.log('note','found empty token...'); | ||||||
|     }); |           return; | ||||||
|  |         } | ||||||
|  |         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.'); | ||||||
|  |         } else { | ||||||
|  |           logger.log('ok', 'npm token base64 encoded.'); | ||||||
|  |           npmToken = plugins.smartstring.base64.decode(npmToken); | ||||||
|  |         } | ||||||
|  |         npmrcFileString += `//${npmRegistryUrl}/:_authToken="${npmToken}"\n`; | ||||||
|  |       } | ||||||
|  |     ); | ||||||
|     logger.log('info', `setting default npm registry to ${config.npmRegistryUrl}`); |     logger.log('info', `setting default npm registry to ${config.npmRegistryUrl}`); | ||||||
|     npmrcFileString += `registry=https://${config.npmRegistryUrl}\n`; |     npmrcFileString += `registry=https://${config.npmRegistryUrl}\n`; | ||||||
|  |  | ||||||
| @@ -70,6 +88,10 @@ export class NpmciNpmManager { | |||||||
|  |  | ||||||
|     // lets save it to disk |     // lets save it to disk | ||||||
|     plugins.smartfile.memory.toFsSync(npmrcFileString, '/root/.npmrc'); |     plugins.smartfile.memory.toFsSync(npmrcFileString, '/root/.npmrc'); | ||||||
|  |  | ||||||
|  |     // lets set the cache directory | ||||||
|  |     await bash(`npm config set cache ${paths.NpmciCacheDir}  --global `); | ||||||
|  |  | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -83,9 +105,13 @@ export class NpmciNpmManager { | |||||||
|       let publishVerdaccioAsWell = false; |       let publishVerdaccioAsWell = false; | ||||||
|       const config = this.npmciRef.npmciConfig.getConfig(); |       const config = this.npmciRef.npmciConfig.getConfig(); | ||||||
|       const availableRegistries: string[] = []; |       const availableRegistries: string[] = []; | ||||||
|       await plugins.smartparam.forEachMinimatch(process.env, 'NPMCI_TOKEN_NPM*', npmEnvArg => { |       await plugins.smartobject.forEachMinimatch( | ||||||
|         availableRegistries.push(npmEnvArg.split('|')[0]); |         process.env, | ||||||
|       }); |         'NPMCI_TOKEN_NPM*', | ||||||
|  |         (npmEnvArg: string) => { | ||||||
|  |           availableRegistries.push(npmEnvArg.split('|')[0]); | ||||||
|  |         } | ||||||
|  |       ); | ||||||
|  |  | ||||||
|       // -> configure package access level |       // -> configure package access level | ||||||
|       if (config.npmAccessLevel) { |       if (config.npmAccessLevel) { | ||||||
| @@ -108,7 +134,7 @@ export class NpmciNpmManager { | |||||||
|  |  | ||||||
|       // publishEverywhere |       // publishEverywhere | ||||||
|       if (publishVerdaccioAsWell) { |       if (publishVerdaccioAsWell) { | ||||||
|         const verdaccioRegistry = availableRegistries.find(registryString => |         const verdaccioRegistry = availableRegistries.find((registryString) => | ||||||
|           registryString.startsWith('verdaccio') |           registryString.startsWith('verdaccio') | ||||||
|         ); |         ); | ||||||
|         if (verdaccioRegistry) { |         if (verdaccioRegistry) { | ||||||
| @@ -131,10 +157,11 @@ export class NpmciNpmManager { | |||||||
|     logger.log('info', `now preparing environment:`); |     logger.log('info', `now preparing environment:`); | ||||||
|     this.prepare(); |     this.prepare(); | ||||||
|     await bash(`npm -v`); |     await bash(`npm -v`); | ||||||
|  |     await bash(`pnpm -v`); | ||||||
|  |  | ||||||
|     // -> build it |     // -> build it | ||||||
|     await bash(`npm install`); |     await this.install(); | ||||||
|     await bash(`npm run build`); |     await this.build(); | ||||||
|  |  | ||||||
|     logger.log('success', `Nice!!! The build for the publication was successfull!`); |     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:`); |     logger.log('info', `Lets clean up so we don't publish any packages that don't belong to us:`); | ||||||
| @@ -152,11 +179,16 @@ export class NpmciNpmManager { | |||||||
|  |  | ||||||
|   public async install(): Promise<void> { |   public async install(): Promise<void> { | ||||||
|     logger.log('info', 'now installing dependencies:'); |     logger.log('info', 'now installing dependencies:'); | ||||||
|     await bash('npm install'); |     await bash('pnpm install'); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public async build(): Promise<void> { | ||||||
|  |     logger.log('info', 'now building the project:'); | ||||||
|  |     await bash('pnpm run build'); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public async test(): Promise<void> { |   public async test(): Promise<void> { | ||||||
|     logger.log('info', 'now starting tests:'); |     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 plugins from './mod.plugins.js'; | ||||||
| import * as paths from '../npmci.paths'; | import * as paths from '../npmci.paths.js'; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * cleans npmci config files |  * 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 * as plugins from './mod.plugins.js'; | ||||||
| import { bash } from '../npmci.bash'; | import { bash } from '../npmci.bash.js'; | ||||||
|  |  | ||||||
| export let command = async () => { | export let command = async () => { | ||||||
|   let wrappedCommand: string = ''; |   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,8 +1,8 @@ | |||||||
| import { logger } from '../npmci.logging'; | import { logger } from '../npmci.logging.js'; | ||||||
| import * as plugins from './mod.plugins'; | import * as plugins from './mod.plugins.js'; | ||||||
| let sshInstance: plugins.smartssh.SshInstance; | let sshInstance: plugins.smartssh.SshInstance; | ||||||
|  |  | ||||||
| export let handleCli = async argvArg => { | export let handleCli = async (argvArg: any) => { | ||||||
|   if (argvArg._.length >= 2) { |   if (argvArg._.length >= 2) { | ||||||
|     const action: string = argvArg._[1]; |     const action: string = argvArg._[1]; | ||||||
|     switch (action) { |     switch (action) { | ||||||
| @@ -31,7 +31,7 @@ const notUndefined = (stringArg: string) => { | |||||||
|  */ |  */ | ||||||
| export let prepare = async () => { | export let prepare = async () => { | ||||||
|   sshInstance = new plugins.smartssh.SshInstance(); // init ssh instance |   sshInstance = new plugins.smartssh.SshInstance(); // init ssh instance | ||||||
|   plugins.smartparam.forEachMinimatch(process.env, 'NPMCI_SSHKEY_*', evaluateSshEnv); |   plugins.smartobject.forEachMinimatch(process.env, 'NPMCI_SSHKEY_*', evaluateSshEnv); | ||||||
|   if (!process.env.NPMTS_TEST) { |   if (!process.env.NPMTS_TEST) { | ||||||
|     sshInstance.writeToDisk(); |     sshInstance.writeToDisk(); | ||||||
|   } else { |   } else { | ||||||
|   | |||||||
| @@ -1 +1 @@ | |||||||
| export * from '../npmci.plugins'; | export * from '../npmci.plugins.js'; | ||||||
|   | |||||||
| @@ -1,15 +1,16 @@ | |||||||
| import * as plugins from './mod.plugins'; | import * as plugins from './mod.plugins.js'; | ||||||
| import { bash } from '../npmci.bash'; | import { bash } from '../npmci.bash.js'; | ||||||
| import { logger } from '../npmci.logging'; | 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\.\-\/]*)/; | 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 () => { | ||||||
|   logger.log('info', 'now running triggers'); |   logger.log('info', 'now running triggers'); | ||||||
|   await plugins.smartparam.forEachMinimatch(process.env, 'NPMCI_TRIGGER_*', evaluateTrigger); |   await plugins.smartobject.forEachMinimatch(process.env, 'NPMCI_TRIGGER_*', evaluateTrigger); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| const evaluateTrigger = async triggerEnvVarArg => { | const evaluateTrigger = async (triggerEnvVarArg) => { | ||||||
|   const triggerRegexResultArray = triggerValueRegex.exec(triggerEnvVarArg); |   const triggerRegexResultArray = triggerValueRegex.exec(triggerEnvVarArg); | ||||||
|   const regexDomain = triggerRegexResultArray[1]; |   const regexDomain = triggerRegexResultArray[1]; | ||||||
|   const regexProjectId = triggerRegexResultArray[2]; |   const regexProjectId = triggerRegexResultArray[2]; | ||||||
| @@ -30,13 +31,13 @@ const evaluateTrigger = async triggerEnvVarArg => { | |||||||
|       { |       { | ||||||
|         name: 'token', |         name: 'token', | ||||||
|         payload: regexProjectTriggerToken, |         payload: regexProjectTriggerToken, | ||||||
|         type: 'string' |         type: 'string', | ||||||
|       }, |       }, | ||||||
|       { |       { | ||||||
|         name: 'ref', |         name: 'ref', | ||||||
|         payload: regexRefName, |         payload: regexRefName, | ||||||
|         type: 'string' |         type: 'string', | ||||||
|       } |       }, | ||||||
|     ] |     ] | ||||||
|   ); |   ); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -1 +1 @@ | |||||||
| export * from '../npmci.plugins'; | export * from '../npmci.plugins.js'; | ||||||
|   | |||||||
| @@ -1,19 +1,17 @@ | |||||||
| import { logger } from './npmci.logging'; | import { logger } from './npmci.logging.js'; | ||||||
| import * as plugins from './npmci.plugins'; | import * as plugins from './npmci.plugins.js'; | ||||||
| import * as paths from './npmci.paths'; | import * as paths from './npmci.paths.js'; | ||||||
|  |  | ||||||
| import * as smartpromise from '@pushrocks/smartpromise'; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * wether nvm is available or not |  * wether nvm is available or not | ||||||
|  */ |  */ | ||||||
| export let nvmAvailable = smartpromise.defer<boolean>(); | export let nvmAvailable = plugins.smartpromise.defer<boolean>(); | ||||||
| /** | /** | ||||||
|  * the smartshell instance for npmci |  * the smartshell instance for npmci | ||||||
|  */ |  */ | ||||||
| const npmciSmartshell = new plugins.smartshell.Smartshell({ | const npmciSmartshell = new plugins.smartshell.Smartshell({ | ||||||
|   executor: 'bash', |   executor: 'bash', | ||||||
|   sourceFilePaths: [] |   sourceFilePaths: [], | ||||||
| }); | }); | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -84,7 +82,7 @@ export let bash = async (commandArg: string, retryArg: number = 2): Promise<stri | |||||||
|     logger.log('info', 'ShellExec would be: ' + commandArg); |     logger.log('info', 'ShellExec would be: ' + commandArg); | ||||||
|     execResult = { |     execResult = { | ||||||
|       exitCode: 0, |       exitCode: 0, | ||||||
|       stdout: 'testOutput' |       stdout: 'testOutput', | ||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
|   return execResult.stdout; |   return execResult.stdout; | ||||||
|   | |||||||
| @@ -1,17 +1,21 @@ | |||||||
| import * as plugins from './npmci.plugins'; | import * as plugins from './npmci.plugins.js'; | ||||||
|  |  | ||||||
| import { CloudlyConnector } from './connector.cloudly/cloudlyconnector'; |  | ||||||
|  |  | ||||||
| import { NpmciInfo } from './npmci.classes.npmciinfo'; | // env | ||||||
| import { NpmciCli } from './npmci.classes.npmcicli'; | import { NpmciEnv } from './npmci.classes.npmcienv.js'; | ||||||
| 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 | // connectors | ||||||
| import { NpmciDockerManager } from './manager.docker'; | import { CloudlyConnector } from './connector.cloudly/cloudlyconnector.js'; | ||||||
| import { NpmciGitManager } from './manager.git'; |  | ||||||
| import { NpmciNodeJsManager } from './manager.nodejs'; | // managers | ||||||
| import { NpmciNpmManager } from './manager.npm'; | import { NpmciCloudronManager } from './manager.cloudron/index.js'; | ||||||
| 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'; | ||||||
|  |  | ||||||
| export class Npmci { | export class Npmci { | ||||||
|   public analytics: plugins.smartanalytics.Analytics; |   public analytics: plugins.smartanalytics.Analytics; | ||||||
| @@ -23,6 +27,7 @@ export class Npmci { | |||||||
|   public npmciCli: NpmciCli; |   public npmciCli: NpmciCli; | ||||||
|  |  | ||||||
|   // managers |   // managers | ||||||
|  |   public cloudronManager: NpmciCloudronManager; | ||||||
|   public dockerManager: NpmciDockerManager; |   public dockerManager: NpmciDockerManager; | ||||||
|   public gitManager: NpmciGitManager; |   public gitManager: NpmciGitManager; | ||||||
|   public nodejsManager: NpmciNodeJsManager; |   public nodejsManager: NpmciNodeJsManager; | ||||||
| @@ -32,24 +37,25 @@ export class Npmci { | |||||||
|     this.analytics = new plugins.smartanalytics.Analytics({ |     this.analytics = new plugins.smartanalytics.Analytics({ | ||||||
|       apiEndPoint: 'https://pubapi.lossless.one/analytics', |       apiEndPoint: 'https://pubapi.lossless.one/analytics', | ||||||
|       projectId: 'gitzone', |       projectId: 'gitzone', | ||||||
|       appName: 'npmci' |       appName: 'npmci', | ||||||
|     }); |     }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public async start() { | ||||||
|     this.cloudlyConnector = new CloudlyConnector(this); |     this.cloudlyConnector = new CloudlyConnector(this); | ||||||
|     this.npmciEnv = new NpmciEnv(this); |     this.npmciEnv = new NpmciEnv(this); | ||||||
|     this.npmciInfo = new NpmciInfo(this); |     this.npmciInfo = new NpmciInfo(this); | ||||||
|  |     await this.npmciInfo.printToConsole(); | ||||||
|     this.npmciCli = new NpmciCli(this); |     this.npmciCli = new NpmciCli(this); | ||||||
|     this.npmciConfig = new NpmciConfig(this); |     this.npmciConfig = new NpmciConfig(this); | ||||||
|  |     await this.npmciConfig.init(); | ||||||
|  |  | ||||||
|     // managers |     // managers | ||||||
|  |     this.cloudronManager = new NpmciCloudronManager(this); | ||||||
|     this.dockerManager = new NpmciDockerManager(this); |     this.dockerManager = new NpmciDockerManager(this); | ||||||
|     this.gitManager = new NpmciGitManager(this); |     this.gitManager = new NpmciGitManager(this); | ||||||
|     this.nodejsManager = new NpmciNodeJsManager(this); |     this.nodejsManager = new NpmciNodeJsManager(this); | ||||||
|     this.npmManager = new NpmciNpmManager(this); |     this.npmManager = new NpmciNpmManager(this); | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public async start() { |  | ||||||
|     await this.npmciInfo.printToConsole(); |  | ||||||
|     await this.npmciConfig.init(); |  | ||||||
|     this.npmciCli.startParse(); |     this.npmciCli.startParse(); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| import { logger } from './npmci.logging'; | import { logger } from './npmci.logging.js'; | ||||||
| import * as plugins from './npmci.plugins'; | import * as plugins from './npmci.plugins.js'; | ||||||
| import * as paths from './npmci.paths'; | import * as paths from './npmci.paths.js'; | ||||||
| import { Npmci } from './npmci.classes.npmci'; | import { Npmci } from './npmci.classes.npmci.js'; | ||||||
|  |  | ||||||
| export class NpmciCli { | export class NpmciCli { | ||||||
|   public npmciRef: Npmci; |   public npmciRef: Npmci; | ||||||
| @@ -14,11 +14,22 @@ export class NpmciCli { | |||||||
|  |  | ||||||
|     // clean |     // clean | ||||||
|     this.smartcli.addCommand('clean').subscribe( |     this.smartcli.addCommand('clean').subscribe( | ||||||
|       async argv => { |       async (argv) => { | ||||||
|         const modClean = await import('./mod_clean/index'); |         const modClean = await import('./mod_clean/index.js'); | ||||||
|         await modClean.clean(); |         await modClean.clean(); | ||||||
|       }, |       }, | ||||||
|       err => { |       (err) => { | ||||||
|  |         console.log(err); | ||||||
|  |         process.exit(1); | ||||||
|  |       } | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     // cloudron | ||||||
|  |     this.smartcli.addCommand('cloudron').subscribe( | ||||||
|  |       async (argv) => { | ||||||
|  |         await this.npmciRef.cloudronManager.handleCli(argv); | ||||||
|  |       }, | ||||||
|  |       (err) => { | ||||||
|         console.log(err); |         console.log(err); | ||||||
|         process.exit(1); |         process.exit(1); | ||||||
|       } |       } | ||||||
| @@ -26,22 +37,22 @@ export class NpmciCli { | |||||||
|  |  | ||||||
|     // command |     // command | ||||||
|     this.smartcli.addCommand('command').subscribe( |     this.smartcli.addCommand('command').subscribe( | ||||||
|       async argv => { |       async (argv) => { | ||||||
|         const modCommand = await import('./mod_command/index'); |         const modCommand = await import('./mod_command/index.js'); | ||||||
|         await modCommand.command(); |         await modCommand.command(); | ||||||
|       }, |       }, | ||||||
|       err => { |       (err) => { | ||||||
|         console.log(err); |         console.log(err); | ||||||
|         process.exit(1); |         process.exit(1); | ||||||
|       } |       } | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|     // command |     // git | ||||||
|     this.smartcli.addCommand('git').subscribe( |     this.smartcli.addCommand('git').subscribe( | ||||||
|       async argvArg => { |       async (argvArg) => { | ||||||
|         await this.npmciRef.gitManager.handleCli(argvArg); |         await this.npmciRef.gitManager.handleCli(argvArg); | ||||||
|       }, |       }, | ||||||
|       err => { |       (err) => { | ||||||
|         console.log(err); |         console.log(err); | ||||||
|         process.exit(1); |         process.exit(1); | ||||||
|       } |       } | ||||||
| @@ -49,10 +60,10 @@ export class NpmciCli { | |||||||
|  |  | ||||||
|     // build |     // build | ||||||
|     this.smartcli.addCommand('docker').subscribe( |     this.smartcli.addCommand('docker').subscribe( | ||||||
|       async argvArg => { |       async (argvArg) => { | ||||||
|         await this.npmciRef.dockerManager.handleCli(argvArg); |         await this.npmciRef.dockerManager.handleCli(argvArg); | ||||||
|       }, |       }, | ||||||
|       err => { |       (err) => { | ||||||
|         console.log(err); |         console.log(err); | ||||||
|         process.exit(1); |         process.exit(1); | ||||||
|       } |       } | ||||||
| @@ -60,10 +71,10 @@ export class NpmciCli { | |||||||
|  |  | ||||||
|     // node |     // node | ||||||
|     this.smartcli.addCommand('node').subscribe( |     this.smartcli.addCommand('node').subscribe( | ||||||
|       async argvArg => { |       async (argvArg) => { | ||||||
|         await this.npmciRef.nodejsManager.handleCli(argvArg); |         await this.npmciRef.nodejsManager.handleCli(argvArg); | ||||||
|       }, |       }, | ||||||
|       err => { |       (err) => { | ||||||
|         console.log(err); |         console.log(err); | ||||||
|         process.exit(1); |         process.exit(1); | ||||||
|       } |       } | ||||||
| @@ -71,33 +82,32 @@ export class NpmciCli { | |||||||
|  |  | ||||||
|     // npm |     // npm | ||||||
|     this.smartcli.addCommand('npm').subscribe( |     this.smartcli.addCommand('npm').subscribe( | ||||||
|       async argvArg => { |       async (argvArg) => { | ||||||
|         await this.npmciRef.npmManager.handleCli(argvArg); |         await this.npmciRef.npmManager.handleCli(argvArg); | ||||||
|       }, |       }, | ||||||
|       err => { |       (err) => { | ||||||
|         console.log(err); |         console.log(err); | ||||||
|       } |       } | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|  |     this.smartcli.addCommand('precheck').subscribe(async (argvArg) => { | ||||||
|  |       const modPrecheck = await import('./mod_precheck/index.js'); | ||||||
|  |       await modPrecheck.handleCli(this.npmciRef, argvArg); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|     // trigger |     // trigger | ||||||
|     this.smartcli.addCommand('ssh').subscribe( |     this.smartcli.addCommand('ssh').subscribe(async (argvArg) => { | ||||||
|       async argvArg => { |       const modSsh = await import('./mod_ssh/index.js'); | ||||||
|         const modSsh = await import('./mod_ssh/index'); |       await modSsh.handleCli(argvArg); | ||||||
|         await modSsh.handleCli(argvArg); |     }); | ||||||
|       }, |  | ||||||
|       err => { |  | ||||||
|         console.log(err); |  | ||||||
|         process.exit(1); |  | ||||||
|       } |  | ||||||
|     ); |  | ||||||
|  |  | ||||||
|     // trigger |     // trigger | ||||||
|     this.smartcli.addCommand('trigger').subscribe( |     this.smartcli.addCommand('trigger').subscribe( | ||||||
|       async argv => { |       async (argv) => { | ||||||
|         const modTrigger = await import('./mod_trigger/index'); |         const modTrigger = await import('./mod_trigger/index.js'); | ||||||
|         await modTrigger.trigger(); |         await modTrigger.trigger(); | ||||||
|       }, |       }, | ||||||
|       err => { |       (err) => { | ||||||
|         console.log(err); |         console.log(err); | ||||||
|         process.exit(1); |         process.exit(1); | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| import * as plugins from './npmci.plugins'; | import * as plugins from './npmci.plugins.js'; | ||||||
| import * as paths from './npmci.paths'; | import * as paths from './npmci.paths.js'; | ||||||
|  |  | ||||||
| import { logger } from './npmci.logging'; | import { logger } from './npmci.logging.js'; | ||||||
| import { Npmci } from './npmci.classes.npmci'; | import { Npmci } from './npmci.classes.npmci.js'; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * the main config interface for npmci |  * the main config interface for npmci | ||||||
| @@ -20,8 +20,14 @@ export interface INpmciOptions { | |||||||
|   dockerRegistryRepoMap: { [key: string]: string }; |   dockerRegistryRepoMap: { [key: string]: string }; | ||||||
|   dockerBuildargEnvMap: { [key: string]: string }; |   dockerBuildargEnvMap: { [key: string]: string }; | ||||||
|  |  | ||||||
|  |   // gitlab | ||||||
|  |   gitlabRunnerTags: string[]; | ||||||
|  |  | ||||||
|   // urls |   // urls | ||||||
|   urlCloudly: string; |   urlCloudly: string; | ||||||
|  |  | ||||||
|  |   // cloudron | ||||||
|  |   cloudronAppName?: string; | ||||||
| } | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -38,17 +44,18 @@ export class NpmciConfig { | |||||||
|  |  | ||||||
|   constructor(npmciRefArg: Npmci) { |   constructor(npmciRefArg: Npmci) { | ||||||
|     this.npmciRef = npmciRefArg; |     this.npmciRef = npmciRefArg; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public async init() { | ||||||
|     this.npmciNpmextra = new plugins.npmextra.Npmextra(paths.cwd); |     this.npmciNpmextra = new plugins.npmextra.Npmextra(paths.cwd); | ||||||
|     this.kvStorage = new plugins.npmextra.KeyValueStore( |     this.kvStorage = new plugins.npmextra.KeyValueStore({ | ||||||
|       'custom', |       typeArg: 'userHomeDir', | ||||||
|       `${this.npmciRef.npmciEnv.repo.user}_${this.npmciRef.npmciEnv.repo.repo}` |       identityArg: `.npmci_${this.npmciRef.npmciEnv.repo.user}_${this.npmciRef.npmciEnv.repo.repo}`, | ||||||
|     ); |     }); | ||||||
|     this.npmciQenv = new plugins.qenv.Qenv( |     this.npmciQenv = new plugins.qenv.Qenv( | ||||||
|       paths.NpmciProjectDir, |       paths.NpmciProjectDir, | ||||||
|       paths.NpmciProjectNogitDir, |       paths.NpmciProjectNogitDir, | ||||||
|       false, |       false | ||||||
|       logger |  | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|     this.configObject = { |     this.configObject = { | ||||||
| @@ -58,12 +65,10 @@ export class NpmciConfig { | |||||||
|       dockerRegistryRepoMap: {}, |       dockerRegistryRepoMap: {}, | ||||||
|       npmAccessLevel: 'private', |       npmAccessLevel: 'private', | ||||||
|       npmRegistryUrl: 'registry.npmjs.org', |       npmRegistryUrl: 'registry.npmjs.org', | ||||||
|  |       gitlabRunnerTags: [], | ||||||
|       dockerBuildargEnvMap: {}, |       dockerBuildargEnvMap: {}, | ||||||
|       urlCloudly: this.npmciQenv.getEnvVarOnDemand('NPMCI_URL_CLOUDLY') |       urlCloudly: await this.npmciQenv.getEnvVarOnDemand('NPMCI_URL_CLOUDLY'), | ||||||
|     }; |     }; | ||||||
|   } |  | ||||||
|  |  | ||||||
|   public async init() { |  | ||||||
|     this.configObject = this.npmciNpmextra.dataFor<INpmciOptions>('npmci', this.configObject); |     this.configObject = this.npmciNpmextra.dataFor<INpmciOptions>('npmci', this.configObject); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import * as plugins from './npmci.plugins'; | import * as plugins from './npmci.plugins.js'; | ||||||
| import { Npmci } from './npmci.classes.npmci'; | import { Npmci } from './npmci.classes.npmci.js'; | ||||||
|  |  | ||||||
| export class NpmciEnv { | export class NpmciEnv { | ||||||
|   public npmciRef: Npmci; |   public npmciRef: Npmci; | ||||||
| @@ -9,7 +9,12 @@ export class NpmciEnv { | |||||||
|  |  | ||||||
|   constructor(npmciRefArg: Npmci) { |   constructor(npmciRefArg: Npmci) { | ||||||
|     this.npmciRef = npmciRefArg; |     this.npmciRef = npmciRefArg; | ||||||
|     this.repoString = process.env.CI_REPOSITORY_URL; |     if (!this.repoString && process.env.GITLAB_CI) { | ||||||
|  |       this.repoString = process.env.CI_REPOSITORY_URL; | ||||||
|  |     } | ||||||
|  |     if (!this.repoString && process.env.NPMCI_COMPUTED_REPOURL) { | ||||||
|  |       this.repoString = process.env.NPMCI_COMPUTED_REPOURL; | ||||||
|  |     } | ||||||
|     if (!this.repoString) { |     if (!this.repoString) { | ||||||
|       this.repoString = 'https://undefined:undefined@github.com/undefined/undefined.git'; |       this.repoString = 'https://undefined:undefined@github.com/undefined/undefined.git'; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| import * as plugins from './npmci.plugins'; | import * as plugins from './npmci.plugins.js'; | ||||||
| import * as paths from './npmci.paths'; | import * as paths from './npmci.paths.js'; | ||||||
| import { logger } from './npmci.logging'; | import { logger } from './npmci.logging.js'; | ||||||
| import { Npmci } from './npmci.classes.npmci'; | import { Npmci } from './npmci.classes.npmci.js'; | ||||||
|  |  | ||||||
| export class NpmciInfo { | export class NpmciInfo { | ||||||
|   public npmciRef: Npmci; |   public npmciRef: Npmci; | ||||||
| @@ -11,7 +11,7 @@ export class NpmciInfo { | |||||||
|     this.npmciRef = npmciArg; |     this.npmciRef = npmciArg; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public printToConsole() { |   public async printToConsole() { | ||||||
|     logger.log('info', `npmci version: ${this.projectInfo.version}`); |     await logger.log('info', `npmci version: ${this.projectInfo.version}`); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import * as plugins from './npmci.plugins'; | import * as plugins from './npmci.plugins.js'; | ||||||
|  |  | ||||||
| export const logger = new plugins.smartlog.Smartlog({ | export const logger = new plugins.smartlog.Smartlog({ | ||||||
|   logContext: { |   logContext: { | ||||||
| @@ -7,8 +7,8 @@ export const logger = new plugins.smartlog.Smartlog({ | |||||||
|     containerName: 'Some ContainerName', |     containerName: 'Some ContainerName', | ||||||
|     environment: 'test', |     environment: 'test', | ||||||
|     runtime: 'node', |     runtime: 'node', | ||||||
|     zone: 'Some Zone' |     zone: 'Some Zone', | ||||||
|   } |   }, | ||||||
| }); | }); | ||||||
|  |  | ||||||
| logger.addLogDestination(new plugins.smartlogDestinationLocal.DestinationLocal()); | logger.addLogDestination(new plugins.smartlogDestinationLocal.DestinationLocal()); | ||||||
|   | |||||||
| @@ -1,9 +1,12 @@ | |||||||
| import * as plugins from './npmci.plugins'; | import * as plugins from './npmci.plugins.js'; | ||||||
|  |  | ||||||
| export const cwd = process.cwd(); | export const cwd = process.cwd(); | ||||||
|  |  | ||||||
| // package paths | // 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'); | export const NpmciPackageConfig = plugins.path.join(NpmciPackageRoot, './config.json'); | ||||||
|  |  | ||||||
| // project paths | // project paths | ||||||
|   | |||||||
| @@ -4,54 +4,64 @@ import * as path from 'path'; | |||||||
| export { path }; | export { path }; | ||||||
|  |  | ||||||
| // @apiglobal | // @apiglobal | ||||||
| import * as typedrequest from '@apiglobal/typedrequest'; | import * as typedrequest from '@api.global/typedrequest'; | ||||||
|  |  | ||||||
| export { | export { typedrequest }; | ||||||
|   typedrequest |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| // @servezone | // @servezone | ||||||
| import * as servezoneInterfaces from '@servezone/servezone-interfaces'; | import * as servezoneApi from '@serve.zone/api'; | ||||||
|  |  | ||||||
| export { servezoneInterfaces }; | export { servezoneApi }; | ||||||
|  |  | ||||||
| // @pushrocks | // @push.rocks | ||||||
| import * as npmextra from '@pushrocks/npmextra'; | import * as lik from '@push.rocks/lik'; | ||||||
| import * as projectinfo from '@pushrocks/projectinfo'; | import * as npmextra from '@push.rocks/npmextra'; | ||||||
| import * as qenv from '@pushrocks/qenv'; | import * as projectinfo from '@push.rocks/projectinfo'; | ||||||
| import * as smartanalytics from '@pushrocks/smartanalytics'; | import * as qenv from '@push.rocks/qenv'; | ||||||
| import * as smartdelay from '@pushrocks/smartdelay'; | import * as smartanalytics from '@push.rocks/smartanalytics'; | ||||||
| import * as smartfile from '@pushrocks/smartfile'; | import * as smartdelay from '@push.rocks/smartdelay'; | ||||||
| import * as smartcli from '@pushrocks/smartcli'; | import * as smartfile from '@push.rocks/smartfile'; | ||||||
| import * as smartlog from '@pushrocks/smartlog'; | import * as smartcli from '@push.rocks/smartcli'; | ||||||
| import * as smartlogDestinationLocal from '@pushrocks/smartlog-destination-local'; | import * as smartgit from '@push.rocks/smartgit'; | ||||||
| import * as smartparam from '@pushrocks/smartparam'; | import * as smartlog from '@push.rocks/smartlog'; | ||||||
| import * as smartpromise from '@pushrocks/smartpromise'; | import * as smartlogDestinationLocal from '@push.rocks/smartlog-destination-local'; | ||||||
| import * as smartrequest from '@pushrocks/smartrequest'; | import * as smartobject from '@push.rocks/smartobject'; | ||||||
| import * as smartshell from '@pushrocks/smartshell'; | import * as smartpath from '@push.rocks/smartpath'; | ||||||
| import * as smartsocket from '@pushrocks/smartsocket'; | import * as smartpromise from '@push.rocks/smartpromise'; | ||||||
| import * as smartssh from '@pushrocks/smartssh'; | import * as smartrequest from '@push.rocks/smartrequest'; | ||||||
| import * as smartstring from '@pushrocks/smartstring'; | import * as smartshell from '@push.rocks/smartshell'; | ||||||
|  | import * as smartsocket from '@push.rocks/smartsocket'; | ||||||
|  | import * as smartssh from '@push.rocks/smartssh'; | ||||||
|  | import * as smartstring from '@push.rocks/smartstring'; | ||||||
|  |  | ||||||
| export { | export { | ||||||
|  |   lik, | ||||||
|   npmextra, |   npmextra, | ||||||
|   projectinfo, |   projectinfo, | ||||||
|   qenv, |   qenv, | ||||||
|   smartanalytics, |   smartanalytics, | ||||||
|   smartdelay, |   smartdelay, | ||||||
|   smartfile, |   smartfile, | ||||||
|  |   smartgit, | ||||||
|   smartcli, |   smartcli, | ||||||
|   smartlog, |   smartlog, | ||||||
|   smartlogDestinationLocal, |   smartlogDestinationLocal, | ||||||
|   smartparam, |   smartobject, | ||||||
|  |   smartpath, | ||||||
|   smartpromise, |   smartpromise, | ||||||
|   smartrequest, |   smartrequest, | ||||||
|   smartshell, |   smartshell, | ||||||
|   smartsocket, |   smartsocket, | ||||||
|   smartssh, |   smartssh, | ||||||
|   smartstring |   smartstring, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | // @tsclass scope | ||||||
|  | import * as tsclass from '@tsclass/tsclass'; | ||||||
|  |  | ||||||
|  | export { tsclass }; | ||||||
|  |  | ||||||
|  | // third party | ||||||
| import * as through2 from 'through2'; | import * as through2 from 'through2'; | ||||||
|  |  | ||||||
| export { through2 }; | export { through2 }; | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | { | ||||||
|  |   "compilerOptions": { | ||||||
|  |     "experimentalDecorators": true, | ||||||
|  |     "useDefineForClassFields": false, | ||||||
|  |     "target": "ES2022", | ||||||
|  |     "module": "NodeNext", | ||||||
|  |     "moduleResolution": "NodeNext", | ||||||
|  |     "esModuleInterop": true, | ||||||
|  |     "verbatimModuleSyntax": true | ||||||
|  |   }, | ||||||
|  |   "exclude": [ | ||||||
|  |     "dist_*/**/*.d.ts" | ||||||
|  |   ] | ||||||
|  | } | ||||||
							
								
								
									
										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