Compare commits
	
		
			118 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 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 | 
							
								
								
									
										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 | ||||
| dist/ | ||||
| dist_web/ | ||||
| dist_serve/ | ||||
| dist_ts_web/ | ||||
| dist_*/ | ||||
|  | ||||
| # 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"] | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										81
									
								
								changelog.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								changelog.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| # Changelog | ||||
|  | ||||
| ## 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 | ||||
| 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 | ||||
| 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" | ||||
|   }, | ||||
|   "gitzone": { | ||||
|     "projectType": "npm", | ||||
|     "module": { | ||||
|       "githost": "gitlab.com", | ||||
|       "gitscope": "shipzone", | ||||
|       "gitscope": "ship.zone", | ||||
|       "gitrepo": "npmci", | ||||
|       "shortDescription": "node and docker in gitlab ci on steroids", | ||||
|       "npmPackagename": "@shipzone/npmci", | ||||
|       "license": "MIT" | ||||
|       "description": "A tool to streamline Node.js and Docker workflows within CI environments, particularly GitLab CI, providing various CI/CD utilities.", | ||||
|       "npmPackagename": "@ship.zone/npmci", | ||||
|       "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" | ||||
|       ] | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										3875
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										3875
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										108
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										108
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,17 +1,19 @@ | ||||
| { | ||||
|   "name": "@shipzone/npmci", | ||||
|   "version": "3.1.71", | ||||
|   "name": "@ship.zone/npmci", | ||||
|   "version": "4.1.35", | ||||
|   "private": false, | ||||
|   "description": "node and docker in gitlab ci on steroids", | ||||
|   "main": "dist/index.js", | ||||
|   "typings": "dist/index.d.ts", | ||||
|   "description": "A tool to streamline Node.js and Docker workflows within CI environments, particularly GitLab CI, providing various CI/CD utilities.", | ||||
|   "main": "dist_ts/index.js", | ||||
|   "typings": "dist_ts/index.d.ts", | ||||
|   "type": "module", | ||||
|   "bin": { | ||||
|     "npmci": "cli.js" | ||||
|   }, | ||||
|   "scripts": { | ||||
|     "test": "tstest test/", | ||||
|     "build": "tsbuild && (npm run testVersion)", | ||||
|     "testVersion": "(cd test/assets/ && node ../../cli.js -v)" | ||||
|     "build": "tsbuild --allowimplicitany && (npm run testVersion)", | ||||
|     "testVersion": "(cd test/assets/ && node ../../cli.js -v)", | ||||
|     "buildDocs": "tsdoc" | ||||
|   }, | ||||
|   "repository": { | ||||
|     "type": "git", | ||||
| @@ -24,47 +26,69 @@ | ||||
|   }, | ||||
|   "homepage": "https://gitlab.com/gitzone/npmci#README", | ||||
|   "devDependencies": { | ||||
|     "@gitzone/tsbuild": "^2.1.17", | ||||
|     "@gitzone/tsrun": "^1.2.6", | ||||
|     "@gitzone/tstest": "^1.0.28", | ||||
|     "@pushrocks/tapbundle": "^3.2.0", | ||||
|     "@types/node": "^12.12.12", | ||||
|     "tslint": "^5.20.1", | ||||
|     "tslint-config-prettier": "^1.18.0" | ||||
|     "@git.zone/tsbuild": "^2.2.0", | ||||
|     "@git.zone/tsrun": "^1.3.3", | ||||
|     "@git.zone/tstest": "^1.0.77", | ||||
|     "@push.rocks/tapbundle": "^5.5.0", | ||||
|     "@types/node": "^22.9.0" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@apiglobal/typedrequest": "^1.0.24", | ||||
|     "@pushrocks/lik": "^3.0.11", | ||||
|     "@pushrocks/npmextra": "^3.0.7", | ||||
|     "@pushrocks/projectinfo": "^4.0.2", | ||||
|     "@pushrocks/qenv": "^4.0.6", | ||||
|     "@pushrocks/smartanalytics": "^2.0.15", | ||||
|     "@pushrocks/smartcli": "^3.0.7", | ||||
|     "@pushrocks/smartdelay": "^2.0.6", | ||||
|     "@pushrocks/smartfile": "^7.0.6", | ||||
|     "@pushrocks/smartgit": "^1.0.13", | ||||
|     "@pushrocks/smartlog": "^2.0.21", | ||||
|     "@pushrocks/smartlog-destination-local": "^8.0.2", | ||||
|     "@pushrocks/smartparam": "^1.0.4", | ||||
|     "@pushrocks/smartpromise": "^3.0.6", | ||||
|     "@pushrocks/smartrequest": "^1.1.43", | ||||
|     "@pushrocks/smartshell": "^2.0.25", | ||||
|     "@pushrocks/smartsocket": "^1.1.58", | ||||
|     "@pushrocks/smartssh": "^1.2.3", | ||||
|     "@pushrocks/smartstring": "^3.0.14", | ||||
|     "@servezone/servezone-interfaces": "^2.0.51", | ||||
|     "@types/through2": "^2.0.34", | ||||
|     "through2": "^3.0.1" | ||||
|     "@api.global/typedrequest": "^3.1.10", | ||||
|     "@push.rocks/lik": "^6.1.0", | ||||
|     "@push.rocks/npmextra": "^5.1.2", | ||||
|     "@push.rocks/projectinfo": "^5.0.2", | ||||
|     "@push.rocks/qenv": "^6.0.2", | ||||
|     "@push.rocks/smartanalytics": "^2.0.15", | ||||
|     "@push.rocks/smartcli": "^4.0.11", | ||||
|     "@push.rocks/smartdelay": "^3.0.5", | ||||
|     "@push.rocks/smartenv": "^5.0.5", | ||||
|     "@push.rocks/smartfile": "^11.0.21", | ||||
|     "@push.rocks/smartgit": "^3.1.1", | ||||
|     "@push.rocks/smartlog": "^3.0.7", | ||||
|     "@push.rocks/smartlog-destination-local": "^9.0.0", | ||||
|     "@push.rocks/smartobject": "^1.0.12", | ||||
|     "@push.rocks/smartpath": "^5.0.11", | ||||
|     "@push.rocks/smartpromise": "^4.0.4", | ||||
|     "@push.rocks/smartrequest": "^2.0.23", | ||||
|     "@push.rocks/smartshell": "^3.0.6", | ||||
|     "@push.rocks/smartsocket": "^2.0.22", | ||||
|     "@push.rocks/smartssh": "^2.0.1", | ||||
|     "@push.rocks/smartstring": "^4.0.8", | ||||
|     "@serve.zone/api": "^4.3.11", | ||||
|     "@tsclass/tsclass": "^4.1.2", | ||||
|     "@types/through2": "^2.0.38", | ||||
|     "through2": "^4.0.2" | ||||
|   }, | ||||
|   "files": [ | ||||
|     "ts/*", | ||||
|     "ts_web/*", | ||||
|     "dist/*", | ||||
|     "dist_web/*", | ||||
|     "dist_ts_web/*", | ||||
|     "assets/*", | ||||
|     "ts/**/*", | ||||
|     "ts_web/**/*", | ||||
|     "dist/**/*", | ||||
|     "dist_*/**/*", | ||||
|     "dist_ts/**/*", | ||||
|     "dist_ts_web/**/*", | ||||
|     "assets/**/*", | ||||
|     "cli.js", | ||||
|     "npmextra.json", | ||||
|     "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. | ||||
							
								
								
									
										537
									
								
								readme.md
									
									
									
									
									
								
							
							
						
						
									
										537
									
								
								readme.md
									
									
									
									
									
								
							| @@ -1,101 +1,494 @@ | ||||
| # @shipzone/npmci | ||||
| node and docker in gitlab ci on steroids | ||||
| # @ship.zone/npmci | ||||
| A tool to enhance Node.js and Docker workflows within GitLab CI, providing various CI/CD utilities. | ||||
|  | ||||
| ## Availabililty and Links | ||||
| * [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/) | ||||
| ## Install | ||||
|  | ||||
| ## Status for master | ||||
| [](https://gitlab.com/shipzone/npmci/commits/master) | ||||
| [](https://gitlab.com/shipzone/npmci/commits/master) | ||||
| [](https://www.npmjs.com/package/@shipzone/npmci) | ||||
| [](https://snyk.io/test/npm/@shipzone/npmci) | ||||
| [](https://nodejs.org/dist/latest-v10.x/docs/api/) | ||||
| [](https://nodejs.org/dist/latest-v10.x/docs/api/) | ||||
| [](https://prettier.io/) | ||||
| To install `@ship.zone/npmci`, you can use npm or yarn: | ||||
|  | ||||
| ```sh | ||||
| # Using npm | ||||
| npm install @ship.zone/npmci | ||||
|  | ||||
| # Using yarn | ||||
| yarn add @ship.zone/npmci | ||||
| ``` | ||||
|  | ||||
| ## 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/)   | ||||
|   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 | ||||
| An example of integrating `npmci` into a GitLab CI configuration could look like this: | ||||
|  | ||||
| npmci can be called from commandline and handle a lot of tasks durug ci: | ||||
| ```yaml | ||||
| image: hosttoday/ht-docker-node:npmci | ||||
|  | ||||
| ```shell | ||||
| # Handle node versions | ||||
| npmci node install stable # will install latest stable node version and update PATH for node and npm | ||||
| npmci node install lts # will install latest LTS node version and update PATH for node and npm versions | ||||
| npmci node install legacy # will install latest legacy node version and update PATH for node and npm | ||||
| npmci node install x.x.x #  will install any specific node version. | ||||
| stages: | ||||
|   - prepare | ||||
|   - build | ||||
|   - test | ||||
|   - deploy | ||||
|  | ||||
| # Handle npm and yarn tasks | ||||
| npmcu npm login # logs in npm using the auth key provided at env var "NPMCI_TOKEN_NPM" | ||||
| npmci npm install  # installs dependencies using npm or yarn dependending on availablity | ||||
| npmci npm test # tests the package | ||||
| npmci npm publish # builds a package and publishes it | ||||
| default: | ||||
|   before_script: | ||||
|     - npmci node install stable | ||||
|     - npmci npm install | ||||
|  | ||||
| # handle docker tasks | ||||
| npmci docker prepare | ||||
| ## npmci test docker will look at all Dockerfiles and look for according tags on GitLab container registry | ||||
| prepare: | ||||
|   stage: prepare | ||||
|   script: | ||||
|     - npmci prepare npm | ||||
|     - npmci prepare docker | ||||
|  | ||||
| build: | ||||
|   stage: build | ||||
|   script: | ||||
|     - npmci docker build | ||||
|  | ||||
| # prepare tools | ||||
| npmci prepare npm # will look for $NPMCI_TOKEN_NPM env var and create .npmrc, so npm is authenticated | ||||
| npmci prepare docker # will look for $NPMCI_LOGIN_DOCKER in form username|password and authenticate docker | ||||
| npmci prepare docker-gitlab # will authenticate docker for gitlab container registry | ||||
| test: | ||||
|   stage: test | ||||
|   script: | ||||
|     - npmci npm test | ||||
|  | ||||
| # build containers | ||||
| npmci docker build # will build containers | ||||
| ## all Dockerfiles named Dockerfile* are picked up. | ||||
| ## specify tags like this Dockerfile_[tag] | ||||
| ## uploads all built images as [username]/[reponame]:[tag]_test to GitLab | ||||
| ## then test in next step with "npmci test docker" | ||||
| deploy: | ||||
|   stage: deploy | ||||
|   script: | ||||
|     - npmci publish npm | ||||
|     - npmci docker push | ||||
|  | ||||
| # publish npm module | ||||
| npmci publish npm # will look vor $NPMCI_TOKEN_NPM env var and push any module in cwd to npm | ||||
| npmci publish docker | ||||
|  | ||||
| # trigger webhooks | ||||
| npmci trigger # will look for NPMCI_TRIGGER_1 to NPMCI_TRIGGER_100 in form domain|id|token|ref|name | ||||
|   environment: | ||||
|     name: production | ||||
|     url: http://example.com | ||||
| ``` | ||||
|  | ||||
| ## 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 | ||||
| { | ||||
|   "npmci": { | ||||
|     "globalNpmTools": ["npm-check-updates", "protractor", "npmts", "gitzone"] | ||||
|   } | ||||
| } | ||||
| on: | ||||
|   push: | ||||
|     branches: | ||||
|       - 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 | ||||
| ``` | ||||
|  | ||||
| **Available options** | ||||
| #### Gitea CI | ||||
|  | ||||
| | setting        | example                       | description                                                                                       | | ||||
| | -------------- | ----------------------------- | ------------------------------------------------------------------------------------------------- | | ||||
| | globalNpmTools | "globalNpmTools": ["gitbook"] | Will look for the specified package names locally and (if not yet present) install them from npm. | | ||||
| Lastly, for Gitea CI: | ||||
|  | ||||
| For further information read the linked docs at the top of this README. | ||||
| ```yaml | ||||
| image: hosttoday/ht-docker-node:npmci | ||||
|  | ||||
| Use TypeScript for best in class instellisense. | ||||
| 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 | ||||
|  | ||||
| For further information read the linked docs at the top of this readme. | ||||
|     - step: | ||||
|         name: Build | ||||
|         image: hosttoday/ht-docker-node:npmci | ||||
|         commands: | ||||
|           - npmci docker build | ||||
|  | ||||
| > MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh) | ||||
| | By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy) | ||||
|     - step: | ||||
|         name: Test | ||||
|         image: hosttoday/ht-docker-node:npmci | ||||
|         commands: | ||||
|           - npmci npm test | ||||
|  | ||||
| [](https://maintainedby.lossless.com) | ||||
|     - 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.')); | ||||
| ``` | ||||
|  | ||||
| ### 3. Handling npm and Yarn Tasks | ||||
|  | ||||
| `npmci` provides numerous utilities to streamline npm and yarn workflow tasks within a CI/CD pipeline. | ||||
|  | ||||
| ```typescript | ||||
| import { Npmci } from '@ship.zone/npmci'; | ||||
|  | ||||
| async function manageNpmTasks() { | ||||
|   const npmciInstance = new Npmci(); | ||||
|   await npmciInstance.start(); | ||||
|  | ||||
|   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 | ||||
| } | ||||
|  | ||||
| manageNpmTasks().then(() => console.log('Npm tasks handled successfully.')); | ||||
| ``` | ||||
|  | ||||
| ### 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 smartpath from '@push.rocks/smartpath'; | ||||
|  | ||||
| process.env.NPMTS_TEST = 'true'; | ||||
| process.env.NPMCI_URL_CLOUDLY = 'localhost'; | ||||
|  | ||||
| // set up environment | ||||
| process.env.CI_REPOSITORY_URL = 'https://yyyyyy:xxxxxxxx@gitlab.com/mygroup/myrepo.git'; | ||||
| @@ -14,46 +16,49 @@ process.env.NPMCI_LOGIN_DOCKER = 'docker.io|someuser|somepass'; | ||||
| process.env.NPMCI_SSHKEY_1 = 'hostString|somePrivKey|##'; | ||||
|  | ||||
| process.cwd = () => { | ||||
|   return path.join(__dirname, 'assets/'); | ||||
|   return path.join(smartpath.get.dirnameFromImportMetaUrl(import.meta.url), 'assets/'); | ||||
| }; | ||||
|  | ||||
| import * as npmci from '../ts'; | ||||
| import type * as npmciTypes from '../ts/index.js'; | ||||
| const npmci = await import('../ts/index.js'); | ||||
|  | ||||
| // ====== | ||||
| // Docker | ||||
| // ====== | ||||
|  | ||||
| let dockerfile1: npmci.Dockerfile; | ||||
| let dockerfile2: npmci.Dockerfile; | ||||
| let sortableArray: npmci.Dockerfile[]; | ||||
| let dockerfile1: npmciTypes.Dockerfile; | ||||
| let dockerfile2: npmciTypes.Dockerfile; | ||||
| let sortableArray: npmciTypes.Dockerfile[]; | ||||
|  | ||||
| tap.test('should return valid Dockerfiles', async () => { | ||||
|   const npmciInstance = new npmci.Npmci(); | ||||
|   await npmciInstance.start(); | ||||
|   dockerfile1 = new npmci.Dockerfile(npmciInstance.dockerManager, { | ||||
|     filePath: './Dockerfile', | ||||
|     read: true | ||||
|     read: true, | ||||
|   }); | ||||
|   dockerfile2 = new npmci.Dockerfile(npmciInstance.dockerManager, { | ||||
|     filePath: './Dockerfile_sometag1', | ||||
|     read: true | ||||
|     read: true, | ||||
|   }); | ||||
|   expect(dockerfile1.version).to.equal('latest'); | ||||
|   return expect(dockerfile2.version).to.equal('sometag1'); | ||||
|   expect(dockerfile1.version).toEqual('latest'); | ||||
|   return expect(dockerfile2.version).toEqual('sometag1'); | ||||
| }); | ||||
|  | ||||
| tap.test('should read a directory of Dockerfiles', async () => { | ||||
|   const npmciInstance = new npmci.Npmci(); | ||||
|   await npmciInstance.start(); | ||||
|   return npmci.Dockerfile.readDockerfiles(npmciInstance.dockerManager).then( | ||||
|     async (readDockerfilesArrayArg: npmci.Dockerfile[]) => { | ||||
|     async (readDockerfilesArrayArg: npmciTypes.Dockerfile[]) => { | ||||
|       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 () => { | ||||
|   return npmci.Dockerfile.sortDockerfiles(sortableArray).then( | ||||
|     async (sortedArrayArg: npmci.Dockerfile[]) => { | ||||
|     async (sortedArrayArg: npmciTypes.Dockerfile[]) => { | ||||
|       console.log(sortedArrayArg); | ||||
|     } | ||||
|   ); | ||||
| @@ -61,29 +66,33 @@ tap.test('should sort an array of Dockerfiles', async () => { | ||||
|  | ||||
| tap.test('should build all Dockerfiles', async () => { | ||||
|   const npmciInstance = new npmci.Npmci(); | ||||
|   await npmciInstance.start(); | ||||
|   return npmciInstance.dockerManager.handleCli({ | ||||
|     _: ['docker', 'build'] | ||||
|     _: ['docker', 'build'], | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| tap.test('should test all Dockerfiles', async () => { | ||||
|   const npmciInstance = new npmci.Npmci(); | ||||
|   await npmciInstance.start(); | ||||
|   return npmciInstance.dockerManager.handleCli({ | ||||
|     _: ['docker', 'test'] | ||||
|     _: ['docker', 'test'], | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| tap.test('should test dockerfiles', async () => { | ||||
|   const npmciInstance = new npmci.Npmci(); | ||||
|   await npmciInstance.start(); | ||||
|   return npmciInstance.dockerManager.handleCli({ | ||||
|     _: ['docker', 'test'] | ||||
|     _: ['docker', 'test'], | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| tap.test('should login docker daemon', async () => { | ||||
|   const npmciInstance = new npmci.Npmci(); | ||||
|   await npmciInstance.start(); | ||||
|   return npmciInstance.dockerManager.handleCli({ | ||||
|     _: ['docker', 'login'] | ||||
|     _: ['docker', 'login'], | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| @@ -91,9 +100,9 @@ tap.test('should login docker daemon', async () => { | ||||
| // SSH | ||||
| // === | ||||
| tap.test('should prepare SSH keys', async () => { | ||||
|   const npmciModSsh = await import('../ts/mod_ssh'); | ||||
|   const npmciModSsh = await import('../ts/mod_ssh/index.js'); | ||||
|   return await npmciModSsh.handleCli({ | ||||
|     _: ['ssh', 'prepare'] | ||||
|     _: ['ssh', 'prepare'], | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| @@ -102,14 +111,15 @@ tap.test('should prepare SSH keys', async () => { | ||||
| // ==== | ||||
| tap.test('should install a certain version of node', async () => { | ||||
|   const npmciInstance = new npmci.Npmci(); | ||||
|   await npmciInstance.start(); | ||||
|   await npmciInstance.nodejsManager.handleCli({ | ||||
|     _: ['node', 'install', 'stable'] | ||||
|     _: ['node', 'install', 'stable'], | ||||
|   }); | ||||
|   await npmciInstance.nodejsManager.handleCli({ | ||||
|     _: ['node', 'install', 'lts'] | ||||
|     _: ['node', 'install', 'lts'], | ||||
|   }); | ||||
|   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.35', | ||||
|   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 { logger } from '../npmci.logging'; | ||||
| import { Npmci } from '../npmci.classes.npmci.js'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
|  | ||||
| /** | ||||
|  * connects to cloudly | ||||
| @@ -13,8 +13,11 @@ export class CloudlyConnector { | ||||
|     this.npmciRef = npmciRefArg; | ||||
|   } | ||||
|  | ||||
|   public async announceDockerContainer(optionsArg: plugins.servezoneInterfaces.version.IVersionData) { | ||||
|     const cloudlyUrl = this.npmciRef.npmciConfig.getConfig().urlCloudly; | ||||
|   public async announceDockerContainer( | ||||
|     optionsArg: plugins.tsclass.container.IContainer, | ||||
|     testCloudlyUrlArg?: string | ||||
|   ) { | ||||
|     const cloudlyUrl = testCloudlyUrlArg || this.npmciRef.npmciConfig.getConfig().urlCloudly; | ||||
|     if (!cloudlyUrl) { | ||||
|       logger.log( | ||||
|         'warn', | ||||
| @@ -23,10 +26,6 @@ export class CloudlyConnector { | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     const typedrequest = new plugins.typedrequest.TypedRequest< | ||||
|       plugins.servezoneInterfaces.request.version.IRequest_Any_Cloudly_VersionManager_Update | ||||
|     >(`https://${cloudlyUrl}/versionmanager`, 'update'); | ||||
|  | ||||
|     const response = await typedrequest.fire(optionsArg); | ||||
|     // lets push to cloudly here | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										10
									
								
								ts/index.ts
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								ts/index.ts
									
									
									
									
									
								
							| @@ -1,10 +1,10 @@ | ||||
| import { Npmci } from './npmci.classes.npmci'; | ||||
| import { Dockerfile } from './manager.docker/mod.classes.dockerfile'; | ||||
| import { Npmci } from './npmci.classes.npmci.js'; | ||||
| import { Dockerfile } from './manager.docker/mod.classes.dockerfile.js'; | ||||
|  | ||||
| export const npmciInstance = new Npmci(); | ||||
|  | ||||
| export { Dockerfile, Npmci }; | ||||
|  | ||||
| if (process.env.CLI_CALL) { | ||||
|   npmciInstance.start(); | ||||
| } | ||||
| export const runCli = async () => { | ||||
|   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 * as plugins from './mod.plugins'; | ||||
| import * as paths from '../npmci.paths'; | ||||
| import { bash } from '../npmci.bash'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
| import * as paths from '../npmci.paths.js'; | ||||
| import { bash } from '../npmci.bash.js'; | ||||
|  | ||||
| // classes | ||||
| import { Npmci } from '../npmci.classes.npmci'; | ||||
| import { Dockerfile } from './mod.classes.dockerfile'; | ||||
| import { DockerRegistry } from './mod.classes.dockerregistry'; | ||||
| import { RegistryStorage } from './mod.classes.registrystorage'; | ||||
| import { Npmci } from '../npmci.classes.npmci.js'; | ||||
| import { Dockerfile } from './mod.classes.dockerfile.js'; | ||||
| import { DockerRegistry } from './mod.classes.dockerregistry.js'; | ||||
| import { RegistryStorage } from './mod.classes.registrystorage.js'; | ||||
|  | ||||
| export class NpmciDockerManager { | ||||
|   public npmciRef: Npmci; | ||||
| @@ -21,7 +21,7 @@ export class NpmciDockerManager { | ||||
|    * handle cli input | ||||
|    * @param argvArg | ||||
|    */ | ||||
|   public handleCli = async argvArg => { | ||||
|   public handleCli = async (argvArg: any) => { | ||||
|     if (argvArg._.length >= 2) { | ||||
|       const action: string = argvArg._[1]; | ||||
|       switch (action) { | ||||
| @@ -77,23 +77,26 @@ export class NpmciDockerManager { | ||||
|    */ | ||||
|   public prepare = async () => { | ||||
|     // Always login to GitLab Registry | ||||
|     if (!process.env.CI_BUILD_TOKEN || process.env.CI_BUILD_TOKEN === '') { | ||||
|       logger.log('error', 'No registry token specified by gitlab!'); | ||||
|     if (process.env.GITLAB_CI) { | ||||
|       console.log('gitlab ci detected'); | ||||
|       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_BUILD_TOKEN | ||||
|           password: process.env.CI_JOB_TOKEN, | ||||
|         }) | ||||
|       ); | ||||
|     } | ||||
|  | ||||
|     // handle registries | ||||
|     await plugins.smartparam.forEachMinimatch( | ||||
|     await plugins.smartobject.forEachMinimatch( | ||||
|       process.env, | ||||
|       'NPMCI_LOGIN_DOCKER*', | ||||
|       async envString => { | ||||
|       async (envString: string) => { | ||||
|         this.npmciRegistryStorage.addRegistry(DockerRegistry.fromEnvString(envString)); | ||||
|       } | ||||
|     ); | ||||
| @@ -104,7 +107,7 @@ export class NpmciDockerManager { | ||||
|    * pushes an image towards a registry | ||||
|    * @param argvArg | ||||
|    */ | ||||
|   public push = async argvArg => { | ||||
|   public push = async (argvArg: any) => { | ||||
|     await this.prepare(); | ||||
|     let dockerRegistryUrls: string[] = []; | ||||
|  | ||||
| @@ -134,7 +137,9 @@ export class NpmciDockerManager { | ||||
|       const dockerfileArray = await Dockerfile.readDockerfiles(this) | ||||
|         .then(Dockerfile.sortDockerfiles) | ||||
|         .then(Dockerfile.mapDockerfiles); | ||||
|       const dockerRegistryToPushTo = this.npmciRegistryStorage.getRegistryByUrl(dockerRegistryUrl); | ||||
|       const dockerRegistryToPushTo = await this.npmciRegistryStorage.getRegistryByUrl( | ||||
|         dockerRegistryUrl | ||||
|       ); | ||||
|       if (!dockerRegistryToPushTo) { | ||||
|         logger.log( | ||||
|           'error', | ||||
| @@ -151,14 +156,14 @@ export class NpmciDockerManager { | ||||
|   /** | ||||
|    * pulls an image | ||||
|    */ | ||||
|   public pull = async argvArg => { | ||||
|   public pull = async (argvArg: any) => { | ||||
|     await this.prepare(); | ||||
|     const registryUrlArg = argvArg._[2]; | ||||
|     let suffix = null; | ||||
|     if (argvArg._.length >= 4) { | ||||
|       suffix = argvArg._[3]; | ||||
|     } | ||||
|     const localDockerRegistry = this.npmciRegistryStorage.getRegistryByUrl(registryUrlArg); | ||||
|     const localDockerRegistry = await this.npmciRegistryStorage.getRegistryByUrl(registryUrlArg); | ||||
|     const dockerfileArray = await Dockerfile.readDockerfiles(this) | ||||
|       .then(Dockerfile.sortDockerfiles) | ||||
|       .then(Dockerfile.mapDockerfiles); | ||||
| @@ -174,4 +179,12 @@ export class NpmciDockerManager { | ||||
|     await this.prepare(); | ||||
|     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 paths from '../npmci.paths'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
| import * as paths from '../npmci.paths.js'; | ||||
|  | ||||
| import { logger } from '../npmci.logging'; | ||||
| import { bash } from '../npmci.bash'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
| import { bash } from '../npmci.bash.js'; | ||||
|  | ||||
| import { DockerRegistry } from './mod.classes.dockerregistry'; | ||||
| import * as helpers from './mod.helpers'; | ||||
| import { NpmciDockerManager } from '.'; | ||||
| import { Npmci } from '../npmci.classes.npmci'; | ||||
| import { DockerRegistry } from './mod.classes.dockerregistry.js'; | ||||
| import * as helpers from './mod.helpers.js'; | ||||
| import { NpmciDockerManager } from './index.js'; | ||||
| import { Npmci } from '../npmci.classes.npmci.js'; | ||||
|  | ||||
| /** | ||||
|  * class Dockerfile represents a Dockerfile on disk in npmci | ||||
| @@ -31,7 +31,7 @@ export class Dockerfile { | ||||
|     for (const dockerfilePath of fileTree) { | ||||
|       const myDockerfile = new Dockerfile(npmciDockerManagerRefArg, { | ||||
|         filePath: dockerfilePath, | ||||
|         read: true | ||||
|         read: true, | ||||
|       }); | ||||
|       readDockerfilesArray.push(myDockerfile); | ||||
|     } | ||||
| @@ -40,50 +40,79 @@ export class Dockerfile { | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * sorts Dockerfiles into a dependency chain | ||||
|    * @param sortableArrayArg an array of instances of class Dockerfile | ||||
|    * @returns Promise<Dockerfile[]> | ||||
|    * Sorts Dockerfiles into a build order based on dependencies. | ||||
|    * @param dockerfiles An array of Dockerfile instances. | ||||
|    * @returns A Promise that resolves to a sorted array of Dockerfiles. | ||||
|    */ | ||||
|   public static async sortDockerfiles(sortableArrayArg: Dockerfile[]): Promise<Dockerfile[]> { | ||||
|     const done = plugins.smartpromise.defer<Dockerfile[]>(); | ||||
|     logger.log('info', 'sorting Dockerfiles:'); | ||||
|     const sortedArray: Dockerfile[] = []; | ||||
|     const cleanTagsOriginal = Dockerfile.cleanTagsArrayFunction(sortableArrayArg, sortedArray); | ||||
|     let sorterFunctionCounter: number = 0; | ||||
|     const sorterFunction = () => { | ||||
|       sortableArrayArg.forEach(dockerfileArg => { | ||||
|         const cleanTags = Dockerfile.cleanTagsArrayFunction(sortableArrayArg, sortedArray); | ||||
|         if ( | ||||
|           cleanTags.indexOf(dockerfileArg.baseImage) === -1 && | ||||
|           sortedArray.indexOf(dockerfileArg) === -1 | ||||
|         ) { | ||||
|           sortedArray.push(dockerfileArg); | ||||
|         } | ||||
|         if (cleanTagsOriginal.indexOf(dockerfileArg.baseImage) !== -1) { | ||||
|           dockerfileArg.localBaseImageDependent = true; | ||||
|         } | ||||
|   public static async sortDockerfiles(dockerfiles: Dockerfile[]): Promise<Dockerfile[]> { | ||||
|     logger.log('info', 'Sorting Dockerfiles based on dependencies...'); | ||||
|  | ||||
|     // Map from cleanTag to Dockerfile instance for quick lookup | ||||
|     const tagToDockerfile = new Map<string, Dockerfile>(); | ||||
|     dockerfiles.forEach((dockerfile) => { | ||||
|       tagToDockerfile.set(dockerfile.cleanTag, dockerfile); | ||||
|     }); | ||||
|       if (sortableArrayArg.length === sortedArray.length) { | ||||
|         let counter = 1; | ||||
|         for (const dockerfile of sortedArray) { | ||||
|           logger.log('info', `tag ${counter}: -> ${dockerfile.cleanTag}`); | ||||
|           counter++; | ||||
|  | ||||
|     // Build the dependency graph | ||||
|     const graph = new Map<Dockerfile, Dockerfile[]>(); | ||||
|     dockerfiles.forEach((dockerfile) => { | ||||
|       const dependencies: Dockerfile[] = []; | ||||
|       const baseImage = dockerfile.baseImage; | ||||
|  | ||||
|       // Check if the baseImage is among the local Dockerfiles | ||||
|       if (tagToDockerfile.has(baseImage)) { | ||||
|         const baseDockerfile = tagToDockerfile.get(baseImage); | ||||
|         dependencies.push(baseDockerfile); | ||||
|         dockerfile.localBaseImageDependent = true; | ||||
|         dockerfile.localBaseDockerfile = baseDockerfile; | ||||
|       } | ||||
|         done.resolve(sortedArray); | ||||
|       } else if (sorterFunctionCounter < 10) { | ||||
|         sorterFunctionCounter++; | ||||
|         sorterFunction(); | ||||
|  | ||||
|       graph.set(dockerfile, dependencies); | ||||
|     }); | ||||
|  | ||||
|     // Perform topological sort | ||||
|     const sortedDockerfiles: Dockerfile[] = []; | ||||
|     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}`); | ||||
|     }); | ||||
|  | ||||
|     return sortedDockerfiles; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * maps local Dockerfiles dependencies to the correspoding Dockerfile class instances | ||||
|    */ | ||||
|   public static async mapDockerfiles(sortedDockerfileArray: Dockerfile[]): Promise<Dockerfile[]> { | ||||
|     sortedDockerfileArray.forEach(dockerfileArg => { | ||||
|     sortedDockerfileArray.forEach((dockerfileArg) => { | ||||
|       if (dockerfileArg.localBaseImageDependent) { | ||||
|         sortedDockerfileArray.forEach((dockfile2: Dockerfile) => { | ||||
|           if (dockfile2.cleanTag === dockerfileArg.baseImage) { | ||||
| @@ -120,15 +149,23 @@ export class Dockerfile { | ||||
|    * returns a version for a docker file | ||||
|    * @execution SYNC | ||||
|    */ | ||||
|   public static dockerFileVersion(dockerfileNameArg: string): string { | ||||
|   public static dockerFileVersion( | ||||
|     dockerfileInstanceArg: Dockerfile, | ||||
|     dockerfileNameArg: string | ||||
|   ): string { | ||||
|     let versionString: string; | ||||
|     const versionRegex = /Dockerfile_([a-zA-Z0-9\.]*)$/; | ||||
|     const versionRegex = /Dockerfile_(.+)$/; | ||||
|     const regexResultArray = versionRegex.exec(dockerfileNameArg); | ||||
|     if (regexResultArray && regexResultArray.length === 2) { | ||||
|       versionString = regexResultArray[1]; | ||||
|     } else { | ||||
|       versionString = 'latest'; | ||||
|     } | ||||
|     versionString = versionString.replace( | ||||
|       '##version##', | ||||
|       dockerfileInstanceArg.npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().projectInfo.npm | ||||
|         .version | ||||
|     ); | ||||
|     return versionString; | ||||
|   } | ||||
|  | ||||
| @@ -152,9 +189,8 @@ export class Dockerfile { | ||||
|     suffixArg?: string | ||||
|   ): string { | ||||
|     // determine wether the repo should be mapped accordingly to the registry | ||||
|     const mappedRepo = npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().dockerRegistryRepoMap[ | ||||
|       registryArg | ||||
|     ]; | ||||
|     const mappedRepo = | ||||
|       npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().dockerRegistryRepoMap[registryArg]; | ||||
|     const repo = (() => { | ||||
|       if (mappedRepo) { | ||||
|         return mappedRepo; | ||||
| @@ -178,34 +214,21 @@ export class Dockerfile { | ||||
|   ): Promise<string> { | ||||
|     logger.log('info', 'checking for env vars to be supplied to the docker build'); | ||||
|     let buildArgsString: string = ''; | ||||
|     for (const key of Object.keys( | ||||
|     for (const dockerArgKey of Object.keys( | ||||
|       npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().dockerBuildargEnvMap | ||||
|     )) { | ||||
|       const targetValue = | ||||
|         process.env[ | ||||
|           npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().dockerBuildargEnvMap[key] | ||||
|         ]; | ||||
|       buildArgsString = `${buildArgsString} --build-arg ${key}="${targetValue}"`; | ||||
|       const dockerArgOuterEnvVar = | ||||
|         npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().dockerBuildargEnvMap[dockerArgKey]; | ||||
|       logger.log( | ||||
|         'note', | ||||
|         `docker ARG "${dockerArgKey}" maps to outer env var "${dockerArgOuterEnvVar}"` | ||||
|       ); | ||||
|       const targetValue = process.env[dockerArgOuterEnvVar]; | ||||
|       buildArgsString = `${buildArgsString} --build-arg ${dockerArgKey}="${targetValue}"`; | ||||
|     } | ||||
|     return buildArgsString; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * | ||||
|    */ | ||||
|   public static cleanTagsArrayFunction( | ||||
|     dockerfileArrayArg: Dockerfile[], | ||||
|     trackingArrayArg: Dockerfile[] | ||||
|   ): string[] { | ||||
|     const cleanTagsArray: string[] = []; | ||||
|     dockerfileArrayArg.forEach(dockerfileArg => { | ||||
|       if (trackingArrayArg.indexOf(dockerfileArg) === -1) { | ||||
|         cleanTagsArray.push(dockerfileArg.cleanTag); | ||||
|       } | ||||
|     }); | ||||
|     return cleanTagsArray; | ||||
|   } | ||||
|  | ||||
|   // INSTANCE | ||||
|   public npmciDockerManagerRef: NpmciDockerManager; | ||||
|  | ||||
| @@ -231,7 +254,7 @@ export class Dockerfile { | ||||
|       this.npmciDockerManagerRef.npmciRef.npmciEnv.repo.user + | ||||
|       '/' + | ||||
|       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.buildTag = this.cleanTag; | ||||
|  | ||||
| @@ -269,15 +292,20 @@ export class Dockerfile { | ||||
|     ); | ||||
|     await bash(`docker tag ${this.buildTag} ${this.pushTag}`); | ||||
|     await bash(`docker push ${this.pushTag}`); | ||||
|     const imageDigest = (await bash( | ||||
|       `docker inspect --format="{{index .RepoDigests 0}}" ${this.pushTag}` | ||||
|     )).split('@')[1]; | ||||
|     const imageDigest = ( | ||||
|       await bash(`docker inspect --format="{{index .RepoDigests 0}}" ${this.pushTag}`) | ||||
|     ).split('@')[1]; | ||||
|     console.log(`The image ${this.pushTag} has digest ${imageDigest}`); | ||||
|     await this.npmciDockerManagerRef.npmciRef.cloudlyConnector.announceDockerContainer({ | ||||
|       dockerImageUrl: this.pushTag, | ||||
|       dockerImageVersion: this.npmciDockerManagerRef.npmciRef.npmciConfig.getConfig().projectInfo | ||||
|         .npm.version | ||||
|       registryUrl: this.pushTag, | ||||
|       tag: this.buildTag, | ||||
|       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 * as plugins from './mod.plugins'; | ||||
| import { bash } from '../npmci.bash'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
| import { bash } from '../npmci.bash.js'; | ||||
|  | ||||
| export interface IDockerRegistryConstructorOptions { | ||||
|   registryUrl: string; | ||||
| @@ -26,13 +26,13 @@ export class DockerRegistry { | ||||
|       process.exit(1); | ||||
|       return; | ||||
|     } | ||||
|     const registryUrl = dockerRegexResultArray[0]; | ||||
|     const registryUrl = dockerRegexResultArray[0].replace('https://', '').replace('http://', ''); | ||||
|     const username = dockerRegexResultArray[1]; | ||||
|     const password = dockerRegexResultArray[2]; | ||||
|     return new DockerRegistry({ | ||||
|       registryUrl: registryUrl, | ||||
|       username: username, | ||||
|       password: password | ||||
|       password: password, | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -1,11 +1,10 @@ | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from './mod.plugins'; | ||||
| import { Objectmap } from '@pushrocks/lik'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
|  | ||||
| import { DockerRegistry } from './mod.classes.dockerregistry'; | ||||
| import { DockerRegistry } from './mod.classes.dockerregistry.js'; | ||||
|  | ||||
| export class RegistryStorage { | ||||
|   objectMap = new Objectmap<DockerRegistry>(); | ||||
|   objectMap = new plugins.lik.ObjectMap<DockerRegistry>(); | ||||
|   constructor() { | ||||
|     // Nothing here | ||||
|   } | ||||
| @@ -15,13 +14,13 @@ export class RegistryStorage { | ||||
|   } | ||||
|  | ||||
|   getRegistryByUrl(registryUrlArg: string) { | ||||
|     return this.objectMap.find(registryArg => { | ||||
|     return this.objectMap.findSync((registryArg) => { | ||||
|       return registryArg.registryUrl === registryUrlArg; | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   async loginAll() { | ||||
|     await this.objectMap.forEach(async registryArg => { | ||||
|     await this.objectMap.forEach(async (registryArg) => { | ||||
|       await registryArg.login(); | ||||
|     }); | ||||
|     logger.log('success', 'logged in successfully into all available DockerRegistries!'); | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from './mod.plugins'; | ||||
| import * as paths from '../npmci.paths'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
| import * as paths from '../npmci.paths.js'; | ||||
|  | ||||
| import { Dockerfile } from './mod.classes.dockerfile'; | ||||
| import { Dockerfile } from './mod.classes.dockerfile.js'; | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| export * from '../npmci.plugins'; | ||||
| export * from '../npmci.plugins.js'; | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from './mod.plugins'; | ||||
| import { bash, bashNoError } from '../npmci.bash'; | ||||
| import { Npmci } from '../npmci.classes.npmci'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
| import { bash, bashNoError } from '../npmci.bash.js'; | ||||
| import { Npmci } from '../npmci.classes.npmci.js'; | ||||
|  | ||||
| export class NpmciGitManager { | ||||
|   public npmciRef: Npmci; | ||||
| @@ -14,7 +14,7 @@ export class NpmciGitManager { | ||||
|    * handle cli input | ||||
|    * @param argvArg | ||||
|    */ | ||||
|   public handleCli = async argvArg => { | ||||
|   public handleCli = async (argvArg: any) => { | ||||
|     if (argvArg._.length >= 2) { | ||||
|       const action: string = argvArg._[1]; | ||||
|       switch (action) { | ||||
|   | ||||
| @@ -1,5 +1 @@ | ||||
| export * from '../npmci.plugins'; | ||||
|  | ||||
| import * as smartgit from '@pushrocks/smartgit'; | ||||
|  | ||||
| export { smartgit }; | ||||
| export * from '../npmci.plugins.js'; | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| import * as plugins from '../npmci.plugins'; | ||||
| import * as paths from '../npmci.paths'; | ||||
| import * as plugins from '../npmci.plugins.js'; | ||||
| import * as paths from '../npmci.paths.js'; | ||||
|  | ||||
| import { logger } from '../npmci.logging'; | ||||
| import { bash, bashNoError, nvmAvailable } from '../npmci.bash'; | ||||
| import { Npmci } from '../npmci.classes.npmci'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
| import { bash, bashNoError, nvmAvailable } from '../npmci.bash.js'; | ||||
| import { Npmci } from '../npmci.classes.npmci.js'; | ||||
|  | ||||
| export class NpmciNodeJsManager { | ||||
|   public npmciRef: Npmci; | ||||
| @@ -16,7 +16,7 @@ export class NpmciNodeJsManager { | ||||
|    * handle cli input | ||||
|    * @param argvArg | ||||
|    */ | ||||
|   public async handleCli(argvArg) { | ||||
|   public async handleCli(argvArg: any) { | ||||
|     if (argvArg._.length >= 3) { | ||||
|       const action: string = argvArg._[1]; | ||||
|       switch (action) { | ||||
| @@ -40,15 +40,15 @@ export class NpmciNodeJsManager { | ||||
|    * Install a specific version of node | ||||
|    * @param versionArg | ||||
|    */ | ||||
|   public async install(versionArg) { | ||||
|   public async install(versionArg: any) { | ||||
|     logger.log('info', `now installing node version ${versionArg}`); | ||||
|     let version: string; | ||||
|     if (versionArg === 'stable') { | ||||
|       version = '12'; | ||||
|       version = '18'; | ||||
|     } else if (versionArg === 'lts') { | ||||
|       version = '10'; | ||||
|       version = '16'; | ||||
|     } else if (versionArg === 'legacy') { | ||||
|       version = '8'; | ||||
|       version = '14'; | ||||
|     } else { | ||||
|       version = versionArg; | ||||
|     } | ||||
| @@ -62,7 +62,6 @@ export class NpmciNodeJsManager { | ||||
|     await bash('npm install -g npm'); | ||||
|     await bash('node -v'); | ||||
|     await bash('npm -v'); | ||||
|     await bash(`npm config set cache ${paths.NpmciCacheDir}  --global `); | ||||
|  | ||||
|     // lets look for further config | ||||
|     const config = await this.npmciRef.npmciConfig.getConfig(); | ||||
|   | ||||
| @@ -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 { bash, bashNoError, nvmAvailable } from '../npmci.bash'; | ||||
| import { Npmci } from '../npmci.classes.npmci'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
| import { bash, bashNoError, nvmAvailable } from '../npmci.bash.js'; | ||||
| import { Npmci } from '../npmci.classes.npmci.js'; | ||||
|  | ||||
| export class NpmciNpmManager { | ||||
|   public npmciRef: Npmci; | ||||
|  | ||||
|   constructor(npmciRefArg) { | ||||
|   constructor(npmciRefArg: Npmci) { | ||||
|     this.npmciRef = npmciRefArg; | ||||
|   } | ||||
|  | ||||
| @@ -15,7 +16,7 @@ export class NpmciNpmManager { | ||||
|    * handle cli input | ||||
|    * @param argvArg | ||||
|    */ | ||||
|   public async handleCli(argvArg) { | ||||
|   public async handleCli(argvArg: any) { | ||||
|     if (argvArg._.length >= 2) { | ||||
|       const action: string = argvArg._[1]; | ||||
|       switch (action) { | ||||
| @@ -51,15 +52,29 @@ export class NpmciNpmManager { | ||||
|    * authenticates npm with token from env var | ||||
|    */ | ||||
|   public async prepare() { | ||||
|     logger.log('info', 'running >>npm prepare<<'); | ||||
|     const config = this.npmciRef.npmciConfig.getConfig(); | ||||
|     let npmrcFileString: string = ''; | ||||
|     await plugins.smartparam.forEachMinimatch(process.env, 'NPMCI_TOKEN_NPM*', npmEnvArg => { | ||||
|     await plugins.smartobject.forEachMinimatch( | ||||
|       process.env, | ||||
|       'NPMCI_TOKEN_NPM*', | ||||
|       (npmEnvArg: string) => { | ||||
|         if (!npmEnvArg) { | ||||
|           logger.log('note','found empty token...'); | ||||
|           return; | ||||
|         } | ||||
|         const npmRegistryUrl = npmEnvArg.split('|')[0]; | ||||
|       const npmToken = npmEnvArg.split('|')[1]; | ||||
|       npmrcFileString += `//${npmRegistryUrl}/:_authToken="${plugins.smartstring.base64.decode( | ||||
|         npmToken | ||||
|       )}"\n`; | ||||
|     }); | ||||
|         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}`); | ||||
|     npmrcFileString += `registry=https://${config.npmRegistryUrl}\n`; | ||||
|  | ||||
| @@ -73,6 +88,10 @@ export class NpmciNpmManager { | ||||
|  | ||||
|     // lets save it to disk | ||||
|     plugins.smartfile.memory.toFsSync(npmrcFileString, '/root/.npmrc'); | ||||
|  | ||||
|     // lets set the cache directory | ||||
|     await bash(`npm config set cache ${paths.NpmciCacheDir}  --global `); | ||||
|  | ||||
|     return; | ||||
|   } | ||||
|  | ||||
| @@ -86,9 +105,13 @@ export class NpmciNpmManager { | ||||
|       let publishVerdaccioAsWell = false; | ||||
|       const config = this.npmciRef.npmciConfig.getConfig(); | ||||
|       const availableRegistries: string[] = []; | ||||
|       await plugins.smartparam.forEachMinimatch(process.env, 'NPMCI_TOKEN_NPM*', npmEnvArg => { | ||||
|       await plugins.smartobject.forEachMinimatch( | ||||
|         process.env, | ||||
|         'NPMCI_TOKEN_NPM*', | ||||
|         (npmEnvArg: string) => { | ||||
|           availableRegistries.push(npmEnvArg.split('|')[0]); | ||||
|       }); | ||||
|         } | ||||
|       ); | ||||
|  | ||||
|       // -> configure package access level | ||||
|       if (config.npmAccessLevel) { | ||||
| @@ -111,7 +134,7 @@ export class NpmciNpmManager { | ||||
|  | ||||
|       // publishEverywhere | ||||
|       if (publishVerdaccioAsWell) { | ||||
|         const verdaccioRegistry = availableRegistries.find(registryString => | ||||
|         const verdaccioRegistry = availableRegistries.find((registryString) => | ||||
|           registryString.startsWith('verdaccio') | ||||
|         ); | ||||
|         if (verdaccioRegistry) { | ||||
| @@ -134,6 +157,7 @@ export class NpmciNpmManager { | ||||
|     logger.log('info', `now preparing environment:`); | ||||
|     this.prepare(); | ||||
|     await bash(`npm -v`); | ||||
|     await bash(`pnpm -v`); | ||||
|  | ||||
|     // -> build it | ||||
|     await this.install(); | ||||
| @@ -155,16 +179,16 @@ export class NpmciNpmManager { | ||||
|  | ||||
|   public async install(): Promise<void> { | ||||
|     logger.log('info', 'now installing dependencies:'); | ||||
|     await bash('npm ci'); | ||||
|     await bash('pnpm install'); | ||||
|   } | ||||
|  | ||||
|   public async build(): Promise<void> { | ||||
|     logger.log('info', 'now building the project:'); | ||||
|     await bash('npm run build'); | ||||
|     await bash('pnpm run build'); | ||||
|   } | ||||
|  | ||||
|   public async test(): Promise<void> { | ||||
|     logger.log('info', 'now starting tests:'); | ||||
|     await bash('npm test'); | ||||
|     await bash('pnpm test'); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| export * from '../npmci.plugins'; | ||||
| export * from '../npmci.plugins.js'; | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import * as plugins from './mod.plugins'; | ||||
| import * as paths from '../npmci.paths'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
| import * as paths from '../npmci.paths.js'; | ||||
|  | ||||
| /** | ||||
|  * cleans npmci config files | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| export * from '../npmci.plugins'; | ||||
| export * from '../npmci.plugins.js'; | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import * as plugins from './mod.plugins'; | ||||
| import { bash } from '../npmci.bash'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
| import { bash } from '../npmci.bash.js'; | ||||
|  | ||||
| export let command = async () => { | ||||
|   let wrappedCommand: string = ''; | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| export * from '../npmci.plugins'; | ||||
| export * from '../npmci.plugins.js'; | ||||
|   | ||||
							
								
								
									
										24
									
								
								ts/mod_precheck/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								ts/mod_precheck/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| import * as plugins from './plugins.js'; | ||||
| import * as paths from '../npmci.paths.js'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
| import { Npmci } from '../npmci.classes.npmci.js'; | ||||
|  | ||||
| export const handleCli = async (npmciRefArg: Npmci, argvArg: any) => { | ||||
|   logger.log('info', 'checking execution context'); | ||||
|   const presentRunnerTags = process.env.CI_RUNNER_TAGS.split(',').map((stringArg) => | ||||
|     stringArg.trim() | ||||
|   ); | ||||
|   let allDesiredGitlabRunnerTagsPresent = true; | ||||
|   for (const desiredRunnerTag of npmciRefArg.npmciConfig.getConfig().gitlabRunnerTags) { | ||||
|     if (!presentRunnerTags.includes(desiredRunnerTag)) { | ||||
|       allDesiredGitlabRunnerTagsPresent = false; | ||||
|       logger.log( | ||||
|         'error', | ||||
|         `Desired runnerRag ${desiredRunnerTag} is missing in current execution context.` | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
|   if (!allDesiredGitlabRunnerTagsPresent) { | ||||
|     process.exit(1); | ||||
|   } | ||||
| }; | ||||
							
								
								
									
										1
									
								
								ts/mod_precheck/plugins.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								ts/mod_precheck/plugins.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| export * from '../npmci.plugins.js'; | ||||
| @@ -1,8 +1,8 @@ | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from './mod.plugins'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
| let sshInstance: plugins.smartssh.SshInstance; | ||||
|  | ||||
| export let handleCli = async argvArg => { | ||||
| export let handleCli = async (argvArg: any) => { | ||||
|   if (argvArg._.length >= 2) { | ||||
|     const action: string = argvArg._[1]; | ||||
|     switch (action) { | ||||
| @@ -31,7 +31,7 @@ const notUndefined = (stringArg: string) => { | ||||
|  */ | ||||
| export let prepare = async () => { | ||||
|   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) { | ||||
|     sshInstance.writeToDisk(); | ||||
|   } else { | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| export * from '../npmci.plugins'; | ||||
| export * from '../npmci.plugins.js'; | ||||
|   | ||||
| @@ -1,15 +1,16 @@ | ||||
| import * as plugins from './mod.plugins'; | ||||
| import { bash } from '../npmci.bash'; | ||||
| import { logger } from '../npmci.logging'; | ||||
| import * as plugins from './mod.plugins.js'; | ||||
| import { bash } from '../npmci.bash.js'; | ||||
| import { logger } from '../npmci.logging.js'; | ||||
|  | ||||
| const triggerValueRegex = /^([a-zA-Z0-9\.]*)\|([a-zA-Z0-9\.]*)\|([a-zA-Z0-9\.]*)\|([a-zA-Z0-9\.]*)\|?([a-zA-Z0-9\.\-\/]*)/; | ||||
| 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 () => { | ||||
|   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 regexDomain = triggerRegexResultArray[1]; | ||||
|   const regexProjectId = triggerRegexResultArray[2]; | ||||
| @@ -30,13 +31,13 @@ const evaluateTrigger = async triggerEnvVarArg => { | ||||
|       { | ||||
|         name: 'token', | ||||
|         payload: regexProjectTriggerToken, | ||||
|         type: 'string' | ||||
|         type: 'string', | ||||
|       }, | ||||
|       { | ||||
|         name: 'ref', | ||||
|         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 * as plugins from './npmci.plugins'; | ||||
| import * as paths from './npmci.paths'; | ||||
|  | ||||
| import * as smartpromise from '@pushrocks/smartpromise'; | ||||
| import { logger } from './npmci.logging.js'; | ||||
| import * as plugins from './npmci.plugins.js'; | ||||
| import * as paths from './npmci.paths.js'; | ||||
|  | ||||
| /** | ||||
|  * wether nvm is available or not | ||||
|  */ | ||||
| export let nvmAvailable = smartpromise.defer<boolean>(); | ||||
| export let nvmAvailable = plugins.smartpromise.defer<boolean>(); | ||||
| /** | ||||
|  * the smartshell instance for npmci | ||||
|  */ | ||||
| const npmciSmartshell = new plugins.smartshell.Smartshell({ | ||||
|   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); | ||||
|     execResult = { | ||||
|       exitCode: 0, | ||||
|       stdout: 'testOutput' | ||||
|       stdout: 'testOutput', | ||||
|     }; | ||||
|   } | ||||
|   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'; | ||||
| import { NpmciCli } from './npmci.classes.npmcicli'; | ||||
| import { NpmciConfig } from './npmci.classes.npmciconfig'; | ||||
| // env | ||||
| import { NpmciEnv } from './npmci.classes.npmcienv.js'; | ||||
| import { NpmciInfo } from './npmci.classes.npmciinfo.js'; | ||||
| import { NpmciCli } from './npmci.classes.npmcicli.js'; | ||||
| import { NpmciConfig } from './npmci.classes.npmciconfig.js'; | ||||
|  | ||||
| // mods | ||||
| import { NpmciDockerManager } from './manager.docker'; | ||||
| import { NpmciGitManager } from './manager.git'; | ||||
| import { NpmciNodeJsManager } from './manager.nodejs'; | ||||
| import { NpmciNpmManager } from './manager.npm'; | ||||
| import { NpmciEnv } from './npmci.classes.npmcienv'; | ||||
| // connectors | ||||
| import { CloudlyConnector } from './connector.cloudly/cloudlyconnector.js'; | ||||
|  | ||||
| // managers | ||||
| import { NpmciCloudronManager } from './manager.cloudron/index.js'; | ||||
| 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 { | ||||
|   public analytics: plugins.smartanalytics.Analytics; | ||||
| @@ -23,6 +27,7 @@ export class Npmci { | ||||
|   public npmciCli: NpmciCli; | ||||
|  | ||||
|   // managers | ||||
|   public cloudronManager: NpmciCloudronManager; | ||||
|   public dockerManager: NpmciDockerManager; | ||||
|   public gitManager: NpmciGitManager; | ||||
|   public nodejsManager: NpmciNodeJsManager; | ||||
| @@ -32,24 +37,25 @@ export class Npmci { | ||||
|     this.analytics = new plugins.smartanalytics.Analytics({ | ||||
|       apiEndPoint: 'https://pubapi.lossless.one/analytics', | ||||
|       projectId: 'gitzone', | ||||
|       appName: 'npmci' | ||||
|       appName: 'npmci', | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   public async start() { | ||||
|     this.cloudlyConnector = new CloudlyConnector(this); | ||||
|     this.npmciEnv = new NpmciEnv(this); | ||||
|     this.npmciInfo = new NpmciInfo(this); | ||||
|     await this.npmciInfo.printToConsole(); | ||||
|     this.npmciCli = new NpmciCli(this); | ||||
|     this.npmciConfig = new NpmciConfig(this); | ||||
|     await this.npmciConfig.init(); | ||||
|  | ||||
|     // managers | ||||
|     this.cloudronManager = new NpmciCloudronManager(this); | ||||
|     this.dockerManager = new NpmciDockerManager(this); | ||||
|     this.gitManager = new NpmciGitManager(this); | ||||
|     this.nodejsManager = new NpmciNodeJsManager(this); | ||||
|     this.npmManager = new NpmciNpmManager(this); | ||||
|   } | ||||
|  | ||||
|   public async start() { | ||||
|     await this.npmciInfo.printToConsole(); | ||||
|     await this.npmciConfig.init(); | ||||
|     this.npmciCli.startParse(); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import { logger } from './npmci.logging'; | ||||
| import * as plugins from './npmci.plugins'; | ||||
| import * as paths from './npmci.paths'; | ||||
| import { Npmci } from './npmci.classes.npmci'; | ||||
| import { logger } from './npmci.logging.js'; | ||||
| import * as plugins from './npmci.plugins.js'; | ||||
| import * as paths from './npmci.paths.js'; | ||||
| import { Npmci } from './npmci.classes.npmci.js'; | ||||
|  | ||||
| export class NpmciCli { | ||||
|   public npmciRef: Npmci; | ||||
| @@ -14,11 +14,22 @@ export class NpmciCli { | ||||
|  | ||||
|     // clean | ||||
|     this.smartcli.addCommand('clean').subscribe( | ||||
|       async argv => { | ||||
|         const modClean = await import('./mod_clean/index'); | ||||
|       async (argv) => { | ||||
|         const modClean = await import('./mod_clean/index.js'); | ||||
|         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); | ||||
|         process.exit(1); | ||||
|       } | ||||
| @@ -26,22 +37,22 @@ export class NpmciCli { | ||||
|  | ||||
|     // command | ||||
|     this.smartcli.addCommand('command').subscribe( | ||||
|       async argv => { | ||||
|         const modCommand = await import('./mod_command/index'); | ||||
|       async (argv) => { | ||||
|         const modCommand = await import('./mod_command/index.js'); | ||||
|         await modCommand.command(); | ||||
|       }, | ||||
|       err => { | ||||
|       (err) => { | ||||
|         console.log(err); | ||||
|         process.exit(1); | ||||
|       } | ||||
|     ); | ||||
|  | ||||
|     // command | ||||
|     // git | ||||
|     this.smartcli.addCommand('git').subscribe( | ||||
|       async argvArg => { | ||||
|       async (argvArg) => { | ||||
|         await this.npmciRef.gitManager.handleCli(argvArg); | ||||
|       }, | ||||
|       err => { | ||||
|       (err) => { | ||||
|         console.log(err); | ||||
|         process.exit(1); | ||||
|       } | ||||
| @@ -49,10 +60,10 @@ export class NpmciCli { | ||||
|  | ||||
|     // build | ||||
|     this.smartcli.addCommand('docker').subscribe( | ||||
|       async argvArg => { | ||||
|       async (argvArg) => { | ||||
|         await this.npmciRef.dockerManager.handleCli(argvArg); | ||||
|       }, | ||||
|       err => { | ||||
|       (err) => { | ||||
|         console.log(err); | ||||
|         process.exit(1); | ||||
|       } | ||||
| @@ -60,10 +71,10 @@ export class NpmciCli { | ||||
|  | ||||
|     // node | ||||
|     this.smartcli.addCommand('node').subscribe( | ||||
|       async argvArg => { | ||||
|       async (argvArg) => { | ||||
|         await this.npmciRef.nodejsManager.handleCli(argvArg); | ||||
|       }, | ||||
|       err => { | ||||
|       (err) => { | ||||
|         console.log(err); | ||||
|         process.exit(1); | ||||
|       } | ||||
| @@ -71,33 +82,32 @@ export class NpmciCli { | ||||
|  | ||||
|     // npm | ||||
|     this.smartcli.addCommand('npm').subscribe( | ||||
|       async argvArg => { | ||||
|       async (argvArg) => { | ||||
|         await this.npmciRef.npmManager.handleCli(argvArg); | ||||
|       }, | ||||
|       err => { | ||||
|       (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 | ||||
|     this.smartcli.addCommand('ssh').subscribe( | ||||
|       async argvArg => { | ||||
|         const modSsh = await import('./mod_ssh/index'); | ||||
|     this.smartcli.addCommand('ssh').subscribe(async (argvArg) => { | ||||
|       const modSsh = await import('./mod_ssh/index.js'); | ||||
|       await modSsh.handleCli(argvArg); | ||||
|       }, | ||||
|       err => { | ||||
|         console.log(err); | ||||
|         process.exit(1); | ||||
|       } | ||||
|     ); | ||||
|     }); | ||||
|  | ||||
|     // trigger | ||||
|     this.smartcli.addCommand('trigger').subscribe( | ||||
|       async argv => { | ||||
|         const modTrigger = await import('./mod_trigger/index'); | ||||
|       async (argv) => { | ||||
|         const modTrigger = await import('./mod_trigger/index.js'); | ||||
|         await modTrigger.trigger(); | ||||
|       }, | ||||
|       err => { | ||||
|       (err) => { | ||||
|         console.log(err); | ||||
|         process.exit(1); | ||||
|       } | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| import * as plugins from './npmci.plugins'; | ||||
| import * as paths from './npmci.paths'; | ||||
| import * as plugins from './npmci.plugins.js'; | ||||
| import * as paths from './npmci.paths.js'; | ||||
|  | ||||
| import { logger } from './npmci.logging'; | ||||
| import { Npmci } from './npmci.classes.npmci'; | ||||
| import { logger } from './npmci.logging.js'; | ||||
| import { Npmci } from './npmci.classes.npmci.js'; | ||||
|  | ||||
| /** | ||||
|  * the main config interface for npmci | ||||
| @@ -20,8 +20,14 @@ export interface INpmciOptions { | ||||
|   dockerRegistryRepoMap: { [key: string]: string }; | ||||
|   dockerBuildargEnvMap: { [key: string]: string }; | ||||
|  | ||||
|   // gitlab | ||||
|   gitlabRunnerTags: string[]; | ||||
|  | ||||
|   // urls | ||||
|   urlCloudly: string; | ||||
|  | ||||
|   // cloudron | ||||
|   cloudronAppName?: string; | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -38,17 +44,18 @@ export class NpmciConfig { | ||||
|  | ||||
|   constructor(npmciRefArg: Npmci) { | ||||
|     this.npmciRef = npmciRefArg; | ||||
|   } | ||||
|  | ||||
|   public async init() { | ||||
|     this.npmciNpmextra = new plugins.npmextra.Npmextra(paths.cwd); | ||||
|     this.kvStorage = new plugins.npmextra.KeyValueStore( | ||||
|       'custom', | ||||
|       `${this.npmciRef.npmciEnv.repo.user}_${this.npmciRef.npmciEnv.repo.repo}` | ||||
|     ); | ||||
|     this.kvStorage = new plugins.npmextra.KeyValueStore({ | ||||
|       typeArg: 'userHomeDir', | ||||
|       identityArg: `.npmci_${this.npmciRef.npmciEnv.repo.user}_${this.npmciRef.npmciEnv.repo.repo}`, | ||||
|     }); | ||||
|     this.npmciQenv = new plugins.qenv.Qenv( | ||||
|       paths.NpmciProjectDir, | ||||
|       paths.NpmciProjectNogitDir, | ||||
|       false, | ||||
|       logger | ||||
|       false | ||||
|     ); | ||||
|  | ||||
|     this.configObject = { | ||||
| @@ -58,12 +65,10 @@ export class NpmciConfig { | ||||
|       dockerRegistryRepoMap: {}, | ||||
|       npmAccessLevel: 'private', | ||||
|       npmRegistryUrl: 'registry.npmjs.org', | ||||
|       gitlabRunnerTags: [], | ||||
|       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); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import * as plugins from './npmci.plugins'; | ||||
| import { Npmci } from './npmci.classes.npmci'; | ||||
| import * as plugins from './npmci.plugins.js'; | ||||
| import { Npmci } from './npmci.classes.npmci.js'; | ||||
|  | ||||
| export class NpmciEnv { | ||||
|   public npmciRef: Npmci; | ||||
| @@ -9,7 +9,12 @@ export class NpmciEnv { | ||||
|  | ||||
|   constructor(npmciRefArg: Npmci) { | ||||
|     this.npmciRef = npmciRefArg; | ||||
|     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) { | ||||
|       this.repoString = 'https://undefined:undefined@github.com/undefined/undefined.git'; | ||||
|     } | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import * as plugins from './npmci.plugins'; | ||||
| import * as paths from './npmci.paths'; | ||||
| import { logger } from './npmci.logging'; | ||||
| import { Npmci } from './npmci.classes.npmci'; | ||||
| import * as plugins from './npmci.plugins.js'; | ||||
| import * as paths from './npmci.paths.js'; | ||||
| import { logger } from './npmci.logging.js'; | ||||
| import { Npmci } from './npmci.classes.npmci.js'; | ||||
|  | ||||
| export class NpmciInfo { | ||||
|   public npmciRef: Npmci; | ||||
| @@ -11,7 +11,7 @@ export class NpmciInfo { | ||||
|     this.npmciRef = npmciArg; | ||||
|   } | ||||
|  | ||||
|   public printToConsole() { | ||||
|     logger.log('info', `npmci version: ${this.projectInfo.version}`); | ||||
|   public async printToConsole() { | ||||
|     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({ | ||||
|   logContext: { | ||||
| @@ -7,8 +7,8 @@ export const logger = new plugins.smartlog.Smartlog({ | ||||
|     containerName: 'Some ContainerName', | ||||
|     environment: 'test', | ||||
|     runtime: 'node', | ||||
|     zone: 'Some Zone' | ||||
|   } | ||||
|     zone: 'Some Zone', | ||||
|   }, | ||||
| }); | ||||
|  | ||||
| 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(); | ||||
|  | ||||
| // package paths | ||||
| export const NpmciPackageRoot = plugins.path.join(__dirname, '../'); | ||||
| export const NpmciPackageRoot = plugins.path.join( | ||||
|   plugins.smartpath.get.dirnameFromImportMetaUrl(import.meta.url), | ||||
|   '../' | ||||
| ); | ||||
| export const NpmciPackageConfig = plugins.path.join(NpmciPackageRoot, './config.json'); | ||||
|  | ||||
| // project paths | ||||
|   | ||||
| @@ -4,52 +4,64 @@ import * as path from 'path'; | ||||
| export { path }; | ||||
|  | ||||
| // @apiglobal | ||||
| import * as typedrequest from '@apiglobal/typedrequest'; | ||||
| import * as typedrequest from '@api.global/typedrequest'; | ||||
|  | ||||
| export { typedrequest }; | ||||
|  | ||||
| // @servezone | ||||
| import * as servezoneInterfaces from '@servezone/servezone-interfaces'; | ||||
| import * as servezoneApi from '@serve.zone/api'; | ||||
|  | ||||
| export { servezoneInterfaces }; | ||||
| export { servezoneApi }; | ||||
|  | ||||
| // @pushrocks | ||||
| import * as npmextra from '@pushrocks/npmextra'; | ||||
| import * as projectinfo from '@pushrocks/projectinfo'; | ||||
| import * as qenv from '@pushrocks/qenv'; | ||||
| import * as smartanalytics from '@pushrocks/smartanalytics'; | ||||
| import * as smartdelay from '@pushrocks/smartdelay'; | ||||
| import * as smartfile from '@pushrocks/smartfile'; | ||||
| import * as smartcli from '@pushrocks/smartcli'; | ||||
| import * as smartlog from '@pushrocks/smartlog'; | ||||
| import * as smartlogDestinationLocal from '@pushrocks/smartlog-destination-local'; | ||||
| import * as smartparam from '@pushrocks/smartparam'; | ||||
| import * as smartpromise from '@pushrocks/smartpromise'; | ||||
| import * as smartrequest from '@pushrocks/smartrequest'; | ||||
| import * as smartshell from '@pushrocks/smartshell'; | ||||
| import * as smartsocket from '@pushrocks/smartsocket'; | ||||
| import * as smartssh from '@pushrocks/smartssh'; | ||||
| import * as smartstring from '@pushrocks/smartstring'; | ||||
| // @push.rocks | ||||
| import * as lik from '@push.rocks/lik'; | ||||
| import * as npmextra from '@push.rocks/npmextra'; | ||||
| import * as projectinfo from '@push.rocks/projectinfo'; | ||||
| import * as qenv from '@push.rocks/qenv'; | ||||
| import * as smartanalytics from '@push.rocks/smartanalytics'; | ||||
| import * as smartdelay from '@push.rocks/smartdelay'; | ||||
| import * as smartfile from '@push.rocks/smartfile'; | ||||
| import * as smartcli from '@push.rocks/smartcli'; | ||||
| import * as smartgit from '@push.rocks/smartgit'; | ||||
| import * as smartlog from '@push.rocks/smartlog'; | ||||
| import * as smartlogDestinationLocal from '@push.rocks/smartlog-destination-local'; | ||||
| import * as smartobject from '@push.rocks/smartobject'; | ||||
| import * as smartpath from '@push.rocks/smartpath'; | ||||
| import * as smartpromise from '@push.rocks/smartpromise'; | ||||
| import * as smartrequest from '@push.rocks/smartrequest'; | ||||
| 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 { | ||||
|   lik, | ||||
|   npmextra, | ||||
|   projectinfo, | ||||
|   qenv, | ||||
|   smartanalytics, | ||||
|   smartdelay, | ||||
|   smartfile, | ||||
|   smartgit, | ||||
|   smartcli, | ||||
|   smartlog, | ||||
|   smartlogDestinationLocal, | ||||
|   smartparam, | ||||
|   smartobject, | ||||
|   smartpath, | ||||
|   smartpromise, | ||||
|   smartrequest, | ||||
|   smartshell, | ||||
|   smartsocket, | ||||
|   smartssh, | ||||
|   smartstring | ||||
|   smartstring, | ||||
| }; | ||||
|  | ||||
| // @tsclass scope | ||||
| import * as tsclass from '@tsclass/tsclass'; | ||||
|  | ||||
| export { tsclass }; | ||||
|  | ||||
| // third party | ||||
| import * as through2 from '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