feat(core): Enhance package publication workflow with dependency handling and CLI improvements.
This commit is contained in:
		| @@ -1,5 +1,13 @@ | ||||
| # Changelog | ||||
|  | ||||
| ## 2024-10-21 - 1.2.0 - feat(core) | ||||
| Enhance package publication workflow with dependency handling and CLI improvements. | ||||
|  | ||||
| - Updated package description and keywords in package.json and npmextra.json. | ||||
| - Integrated dependency extraction from root package.json into sub-package tspublish.json during initialization. | ||||
| - Added build and publish script executions for each submodule. | ||||
| - Improved CLI documentation and usage guidance in readme.md. | ||||
|  | ||||
| ## 2024-10-21 - 1.1.0 - feat(core) | ||||
| Add runCli function to execute TsPublish process | ||||
|  | ||||
|   | ||||
| @@ -5,10 +5,22 @@ | ||||
|       "githost": "code.foss.global", | ||||
|       "gitscope": "git.zone", | ||||
|       "gitrepo": "tspublish", | ||||
|       "description": "publish multiple, concise and small packages from monorepos", | ||||
|       "description": "A tool to publish multiple, concise, and small packages from monorepos, specifically for TypeScript projects within a git environment.", | ||||
|       "npmPackagename": "@git.zone/tspublish", | ||||
|       "license": "MIT", | ||||
|       "projectDomain": "git.zone" | ||||
|       "projectDomain": "git.zone", | ||||
|       "keywords": [ | ||||
|         "typescript", | ||||
|         "monorepo", | ||||
|         "package", | ||||
|         "publish", | ||||
|         "npm", | ||||
|         "automation", | ||||
|         "git", | ||||
|         "modularity", | ||||
|         "module-management", | ||||
|         "developer-tools" | ||||
|       ] | ||||
|     } | ||||
|   }, | ||||
|   "npmci": { | ||||
|   | ||||
							
								
								
									
										21
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								package.json
									
									
									
									
									
								
							| @@ -2,7 +2,7 @@ | ||||
|   "name": "@git.zone/tspublish", | ||||
|   "version": "1.1.0", | ||||
|   "private": false, | ||||
|   "description": "publish multiple, concise and small packages from monorepos", | ||||
|   "description": "A tool to publish multiple, concise, and small packages from monorepos, specifically for TypeScript projects within a git environment.", | ||||
|   "main": "dist_ts/index.js", | ||||
|   "typings": "dist_ts/index.d.ts", | ||||
|   "type": "module", | ||||
| @@ -49,6 +49,19 @@ | ||||
|     "@push.rocks/smartfile": "^11.0.21", | ||||
|     "@push.rocks/smartlog": "^3.0.7", | ||||
|     "@push.rocks/smartnpm": "^2.0.4", | ||||
|     "@push.rocks/smartpath": "^5.0.18" | ||||
|   } | ||||
| } | ||||
|     "@push.rocks/smartpath": "^5.0.18", | ||||
|     "@push.rocks/smartshell": "^3.0.6" | ||||
|   }, | ||||
|   "keywords": [ | ||||
|     "typescript", | ||||
|     "monorepo", | ||||
|     "package", | ||||
|     "publish", | ||||
|     "npm", | ||||
|     "automation", | ||||
|     "git", | ||||
|     "modularity", | ||||
|     "module-management", | ||||
|     "developer-tools" | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										3
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										3
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							| @@ -23,6 +23,9 @@ importers: | ||||
|       '@push.rocks/smartpath': | ||||
|         specifier: ^5.0.18 | ||||
|         version: 5.0.18 | ||||
|       '@push.rocks/smartshell': | ||||
|         specifier: ^3.0.6 | ||||
|         version: 3.0.6 | ||||
|     devDependencies: | ||||
|       '@git.zone/tsbuild': | ||||
|         specifier: ^2.1.25 | ||||
|   | ||||
							
								
								
									
										188
									
								
								readme.md
									
									
									
									
									
								
							
							
						
						
									
										188
									
								
								readme.md
									
									
									
									
									
								
							| @@ -2,6 +2,190 @@ | ||||
|  | ||||
| publish multiple, concise and small packages from monorepos | ||||
|  | ||||
| ## How to create the docs | ||||
| ## Install | ||||
|  | ||||
| To create docs run gitzone aidoc. | ||||
| To install `@git.zone/tspublish`, you can use npm. To use the latest stable version, run: | ||||
|  | ||||
| ```bash | ||||
| npm install @git.zone/tspublish | ||||
| ``` | ||||
|  | ||||
| Alternatively, if you are using yarn, the equivalent command would be: | ||||
|  | ||||
| ```bash | ||||
| yarn add @git.zone/tspublish | ||||
| ``` | ||||
|  | ||||
| These commands will add `@git.zone/tspublish` as a dependency in your `package.json` file and install the package into your `node_modules` directory. | ||||
|  | ||||
| ## Usage | ||||
|  | ||||
| `@git.zone/tspublish` is designed to manage the publishing of multiple, small-scale packages within monorepos. The following sections will guide you through its usage, from setting up your environment to effectively publishing packages. | ||||
|  | ||||
| ### Getting Started with TypeScript and Module Setup | ||||
|  | ||||
| `@git.zone/tspublish` works with monorepos that are organized using TypeScript. The package structure should follow a convention where each submodule intended for publishing is located in a directory prefixed with `ts`, for example, `tsModuleName`. Each submodule directory should contain a `tspublish.json` file to correctly configure the package to be published separately. This file is critical for the `tspublish` process to identify valid package directories and should also include necessary metadata for the package. | ||||
|  | ||||
| Your monorepo structure might resemble: | ||||
|  | ||||
| ``` | ||||
| my-monorepo/ | ||||
| ├── ts-package1/ | ||||
| │   ├── src/ | ||||
| │   ├── tspublish.json | ||||
| ├── ts-package2/ | ||||
| │   ├── src/ | ||||
| │   ├── tspublish.json | ||||
| ``` | ||||
|  | ||||
| ### Configuring `tspublish.json` | ||||
|  | ||||
| Each submodule must include a `tspublish.json` within its directory. This JSON file should include essential details for your publishable package, including its dependencies. Here's a basic example of what `tspublish.json` could look like: | ||||
|  | ||||
| ```json | ||||
| { | ||||
|   "name": "@myorg/ts-package1", | ||||
|   "dependencies": { | ||||
|     "some-dependency": "^1.0.0" | ||||
|   } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ### Running the CLI | ||||
|  | ||||
| `@git.zone/tspublish` includes a CLI that simplifies the publishing process. Begin by importing the CLI runner in a script within your project: | ||||
|  | ||||
| ```typescript | ||||
| import { runCli } from '@git.zone/tspublish'; | ||||
|  | ||||
| runCli(); | ||||
| ``` | ||||
|  | ||||
| This function call orchestrates the publishing operation. It reads each directory prefixed with `ts`, looks for a `tspublish.json`, and creates an individual package based on the gathered data. | ||||
|  | ||||
| ### Core Features | ||||
|  | ||||
| #### Publishing Modules | ||||
|  | ||||
| The core functionality provided by `@git.zone/tspublish` involves processing directories to check for valid submodules that are ready to be published. This occurs via the `publish` method in `TsPublish` class. This method does the following: | ||||
|  | ||||
| - **Reads all directories** within the specified monorepo path. | ||||
| - **Identifies directories** that start with `ts` and validates the presence of `tspublish.json`. | ||||
| - **Logs** information about found packages for user awareness and debugging. | ||||
| - **Checks for collisions** with existing versions on the npm registry to prevent overriding published versions. | ||||
|  | ||||
| ```typescript | ||||
| import { TsPublish } from '@git.zone/tspublish'; | ||||
|  | ||||
| const tspublish = new TsPublish(); | ||||
| await tspublish.publish('/path/to/your/monorepo'); | ||||
| ``` | ||||
|  | ||||
| #### Package Initialization | ||||
|  | ||||
| Once valid submodules are identified, the `init` method in the `PublishModule` class initializes the publish module. This includes: | ||||
|  | ||||
| - Parsing `tspublish.json` for metadata. | ||||
| - Constructing full paths for necessary operations. | ||||
| - Verifying package existence to avoid duplication. | ||||
|  | ||||
| ```typescript | ||||
| import { PublishModule } from '@git.zone/tspublish'; | ||||
|  | ||||
| const publishModule = new PublishModule({ | ||||
|   monoRepoDir: '/path/to/monorepo', | ||||
|   packageSubFolder: 'ts-package1', | ||||
| }); | ||||
|  | ||||
| await publishModule.init(); | ||||
| ``` | ||||
|  | ||||
| #### Creating `package.json` | ||||
|  | ||||
| Part of the publishing process involves automatically creating a `package.json` tailored to each submodule. This dynamically generated JSON will incorporate dependencies from `tspublish.json` and associate them with the latest version of `tsbuild` from the registry: | ||||
|  | ||||
| ```typescript | ||||
| await publishModule.createPackageJson(); | ||||
| ``` | ||||
|  | ||||
| This creates a structured `package.json` which includes scripts to build your TypeScript files before publishing. | ||||
|  | ||||
| #### Constructing Publish-ready Directory | ||||
|  | ||||
| After all configurations are verified and the `package.json` is created, the submodule is ready to be published. This step involves setting up a `dist_publish_` directory specific to each module: | ||||
|  | ||||
| ```typescript | ||||
| await publishModule.createPublishModuleDir(); | ||||
| ``` | ||||
|  | ||||
| The above method ensures that each module's source files are copied and prepared under a dedicated directory meant for packaging and distribution. | ||||
|  | ||||
| ### Logging and Debugging | ||||
|  | ||||
| The package includes a structured logging mechanism using `smartlog` which provides insights into the publishing process, helping in runtime debugging and status tracking of operations: | ||||
|  | ||||
| ```typescript | ||||
| import { logger } from '@git.zone/tspublish/logging'; | ||||
|  | ||||
| logger.log('info', 'Publishing process initialized'); | ||||
| ``` | ||||
|  | ||||
| This powerful logging helps in tracking the status of each step and understanding potential issues during the operations. | ||||
|  | ||||
| ### Testing with tapbundle | ||||
|  | ||||
| To ensure that your publishing workflow is functioning correctly, you can utilize the test suite set up with `tapbundle`. This library facilitates behavior-driven testing for your monorepo. Below is a basic test setup to verify the import and initial function accessibility of `@git.zone/tspublish`: | ||||
|  | ||||
| ```typescript | ||||
| import { expect, tap } from '@push.rocks/tapbundle'; | ||||
| import * as tspublish from '@git.zone/tspublish'; | ||||
|  | ||||
| tap.test('Should run the CLI without errors', async () => { | ||||
|   await tspublish.runCli(); | ||||
|   expect(tspublish).toBeTruthy(); | ||||
| }); | ||||
|  | ||||
| tap.start(); | ||||
| ``` | ||||
|  | ||||
| ### Comprehensive usage example | ||||
|  | ||||
| Let's combine all the steps into a complete example where you prepare a monorepo, configure each module, and execute the publishing workflow. | ||||
|  | ||||
| Suppose you have a project structure as follows: | ||||
|  | ||||
| ```plaintext | ||||
| my-monorepo/ | ||||
| ├── ts-package1/ | ||||
| │   ├── src/ | ||||
| │   ├── tspublish.json | ||||
| ├── ts-package2/ | ||||
| │   ├── src/ | ||||
| │   ├── tspublish.json | ||||
| ``` | ||||
|  | ||||
| Follow these steps: | ||||
|  | ||||
| 1. Ensure each package has `tspublish.json` properly configured with necessary metadata. | ||||
| 2. Create a CLI script such as `publish.js`: | ||||
|  | ||||
| ```typescript | ||||
| import { runCli } from '@git.zone/tspublish'; | ||||
|  | ||||
| runCli().then(() => { | ||||
|   console.log('Publishing completed successfully'); | ||||
| }).catch((error) => { | ||||
|   console.error('Error during publishing:', error); | ||||
| }); | ||||
| ``` | ||||
|  | ||||
| 3. Execute your CLI script: | ||||
|  | ||||
| ```bash | ||||
| node publish.js | ||||
| ``` | ||||
|  | ||||
| Your script will call `runCli`, which will traverse each `ts-package`, verify their publish readiness, and handle individual publishing processes. | ||||
|  | ||||
| By following these comprehensive guidelines and utilizing the structured approach provided by `@git.zone/tspublish`, you can efficiently manage and publish multiple sub-packages from within a monorepo, facilitating organized, modular package management in projects of any scale. | ||||
| undefined | ||||
| @@ -3,6 +3,6 @@ | ||||
|  */ | ||||
| export const commitinfo = { | ||||
|   name: '@git.zone/tspublish', | ||||
|   version: '1.1.0', | ||||
|   description: 'publish multiple, concise and small packages from monorepos' | ||||
|   version: '1.2.0', | ||||
|   description: 'A tool to publish multiple, concise, and small packages from monorepos, specifically for TypeScript projects within a git environment.' | ||||
| } | ||||
|   | ||||
| @@ -31,15 +31,21 @@ export class PublishModule { | ||||
|     const jsonData = plugins.smartfile.fs.toObjectSync( | ||||
|       plugins.path.join(this.options.packageSubFolderFullPath, 'tspublish.json') | ||||
|     ); | ||||
|     this.options.dependencies = this.options.dependencies || {}; | ||||
|     const monoRepoPackageJson = JSON.parse( | ||||
|       plugins.smartfile.fs.toStringSync(plugins.path.join(this.options.monoRepoDir, 'package.json')) | ||||
|     ) | ||||
|     this.options.dependencies = { | ||||
|       ...this.options.dependencies, | ||||
|       ...jsonData.dependencies, | ||||
|       ...(() => { | ||||
|         const resultDependencies = {}; | ||||
|         for (const dependency of jsonData.dependencies) { | ||||
|           resultDependencies[dependency] = monoRepoPackageJson.dependencies[dependency]; | ||||
|         } | ||||
|         return resultDependencies; | ||||
|       })() | ||||
|     }; | ||||
|     this.options.name = this.options.name || jsonData.name; | ||||
|     this.options.version = plugins.smartfile.fs.toObjectSync( | ||||
|       plugins.path.join(this.options.monoRepoDir, 'package.json') | ||||
|     ).version; | ||||
|     this.options.version = monoRepoPackageJson.version; | ||||
|  | ||||
|     // now that we have a name and version, lets check if there is already a package under the same name and version. | ||||
|     const smartnpmInstance = new plugins.smartnpm.NpmRegistry({}); // TODO: pass in options | ||||
| @@ -102,4 +108,18 @@ export class PublishModule { | ||||
|     // ts folder | ||||
|     await plugins.smartfile.fs.copy(this.options.packageSubFolderFullPath, plugins.path.join(this.options.publishModDirFullPath, this.options.packageSubFolder))  | ||||
|   } | ||||
|  | ||||
|   public async build() { | ||||
|     const smartshellInstance = new plugins.smartshell.Smartshell({ | ||||
|       executor: 'bash', | ||||
|     }) | ||||
|     await smartshellInstance.exec(`cd ${this.options.publishModDirFullPath} && pnpm run build`); | ||||
|   } | ||||
|  | ||||
|   public async publish() { | ||||
|     const smartshellInstance = new plugins.smartshell.Smartshell({ | ||||
|       executor: 'bash', | ||||
|     }) | ||||
|     await smartshellInstance.exec(`cd ${this.options.publishModDirFullPath} && pnpm publish`); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -14,6 +14,9 @@ export class TsPublish { | ||||
|         packageSubFolder: publishModule, | ||||
|       }); | ||||
|       await publishModuleInstance.init(); | ||||
|       await publishModuleInstance.createPublishModuleDir(); | ||||
|       await publishModuleInstance.build(); | ||||
|       await publishModuleInstance.publish(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -10,5 +10,6 @@ import * as smartcli from '@push.rocks/smartcli'; | ||||
| import * as smartlog from '@push.rocks/smartlog'; | ||||
| import * as smartnpm from '@push.rocks/smartnpm'; | ||||
| import * as smartpath from '@push.rocks/smartpath'; | ||||
| import * as smartshell from '@push.rocks/smartshell'; | ||||
|  | ||||
| export { smartfile, smartcli, smartlog, smartnpm, smartpath, }; | ||||
| export { smartfile, smartcli, smartlog, smartnpm, smartpath, smartshell }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user