-
Notifications
You must be signed in to change notification settings - Fork 990
Fix publishing workflow and update scripts for web packages #768
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| # Publishing Guide for A2UI Web Packages | ||
|
|
||
| This guide is for project maintainers. It details the manual publishing process to the npm registry for all four web-related packages in this repository: | ||
|
|
||
| 1. `@a2ui/web_core` | ||
| 2. `@a2ui/lit` | ||
| 3. `@a2ui/angular` | ||
| 4. `@a2ui/markdown-it` | ||
|
|
||
| --- | ||
|
|
||
| ## 🚀 Setup Authentication | ||
|
|
||
| Ensure you have an NPM Access Token with rights to the `@a2ui` organization. | ||
|
|
||
| 1. Create an `.npmrc` file in the directory of the package you are publishing (it is git-ignored): | ||
| ```sh | ||
| echo "//registry.npmjs.org/:_authToken=\${NPM_TOKEN}" > .npmrc | ||
| ``` | ||
| 2. Export your token in your terminal: | ||
| ```sh | ||
| export NPM_TOKEN="npm_YourSecretTokenHere" | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## 📦 1. Publishing `@a2ui/web_core` | ||
|
|
||
| This package does not have internal `file:` dependencies, so it can be published directly from its root. | ||
|
|
||
| ### Pre-flight Checks | ||
| 1. Ensure your working tree is clean and you are on the correct branch (e.g., `main`). | ||
| 2. Update the `version` in `renderers/web_core/package.json`. | ||
| 3. Verify all tests pass: | ||
| ```sh | ||
| cd renderers/web_core | ||
| npm run test | ||
| ``` | ||
|
|
||
| ### Publish to NPM | ||
| Because this is a scoped package (`@a2ui/`), you have two options: | ||
|
|
||
| **Option A: Publish as Private, then promote to Public (Requires Paid NPM Account)** | ||
| 1. Publish (defaults to private): | ||
| ```sh | ||
| npm publish | ||
| ``` | ||
| 2. Verify the package looks correct on the npm website. | ||
| 3. Promote to public: | ||
| ```sh | ||
| npm access public @a2ui/web_core | ||
| ``` | ||
|
|
||
| **Option B: Publish directly as Public (Free or Paid NPM Account)** | ||
| ```sh | ||
| npm publish --access public | ||
| ``` | ||
|
|
||
| *Note: NPM automatically executes the `prepack` script (`npm run build`), compiles the TypeScript, and generates the `dist/` directory right before creating the tarball.* | ||
|
|
||
| **What exactly gets published?** | ||
| Only the `dist/` directory, `src/` directory (for sourcemaps), `package.json`, `README.md`, and `LICENSE` are included in the published package. This is strictly controlled by the `"files"` array in `package.json`. Internal files like this publishing guide, tests, and configuration scripts are excluded. | ||
|
|
||
| **What about the License?** | ||
| The package is automatically published under the `Apache-2.0` open-source license, as defined in `package.json`. | ||
|
|
||
| --- | ||
|
|
||
| ## 📦 2. Publishing `@a2ui/lit`, `@a2ui/angular`, and `@a2ui/markdown-it` | ||
|
|
||
| These packages depend on `@a2ui/web_core` via a local `file:../web_core` path for development. Therefore, **they must be published from their generated `dist/` folders.** We use specialized scripts to automatically rewrite their `package.json` with the correct `@a2ui/web_core` npm version before publishing. | ||
|
|
||
| If you attempt to run `npm publish` in their root directories, it will fail and throw an error to protect against publishing broken paths. | ||
|
|
||
| ### Pre-flight Checks | ||
| 1. Ensure `@a2ui/web_core` is already published (or its version string is correctly updated) since these packages will read that version number. | ||
| 2. Update the `version` in the package you want to publish (e.g., `renderers/lit/package.json`). | ||
| 3. Ensure all tests pass. | ||
|
|
||
| ### Publish to NPM | ||
| For each of these packages, simply run their automated publish script: | ||
|
|
||
| **For Lit:** | ||
| ```sh | ||
| cd renderers/lit | ||
| npm run publish:package | ||
| ``` | ||
|
|
||
| **For Angular:** | ||
| ```sh | ||
| cd renderers/angular | ||
| npm run publish:package | ||
| ``` | ||
|
|
||
| **For Markdown-it:** | ||
| ```sh | ||
| cd renderers/markdown/markdown-it | ||
| npm run publish:package | ||
| ``` | ||
|
|
||
| ### How It Works (Explanations) | ||
|
|
||
| **What happens during `npm run publish:package`?** | ||
| Before publishing, the script runs the necessary `build` command which processes the code. For Lit and Markdown-it, `prepare-publish.mjs` runs, and for Angular, `postprocess-build.mjs` runs. These scripts: | ||
| 1. Copy `package.json`, `README.md`, and `LICENSE` to the `dist/` folder. | ||
| 2. Read the `version` from `@a2ui/web_core`. | ||
| 3. Update the `file:` dependency in the `dist/package.json` to the actual core version (e.g., `^0.8.0`). | ||
| 4. Adjust exports and paths to be relative to `dist/`. | ||
| 5. Remove any build scripts (`prepublishOnly`, `scripts`) so they don't interfere with the publish process. | ||
|
|
||
| The `npm publish dist/` command then uploads only the contents of the `dist/` directory to the npm registry. | ||
|
|
||
| --- | ||
|
|
||
| ## 🔖 Post-Publish | ||
| 1. Tag the release (replace with actual version): | ||
| ```sh | ||
| git tag v0.8.0 | ||
| ``` | ||
| 2. Push the tag: | ||
| ```sh | ||
| git push origin v0.8.0 | ||
| ``` | ||
| 3. Create a GitHub Release mapping to the new tag. |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| import { readFileSync, writeFileSync, copyFileSync, mkdirSync, existsSync } from 'fs'; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Copyright? |
||
| import { join } from 'path'; | ||
|
|
||
| // This script prepares the markdown-it package for publishing by: | ||
| // 1. Copying package.json to dist/ | ||
| // 2. Updating @a2ui/web_core dependency from 'file:...' to the actual version | ||
| // 3. Adjusting paths in package.json (main, types, exports) to be relative to dist/ | ||
|
|
||
| const dirname = import.meta.dirname; | ||
| const corePkgPath = join(dirname, '../../web_core/package.json'); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This package is going to be fairly stable, and it most likely won't need a lot of changes to web_core. Can you please update the package.json to take a dependency on the published version of web_core? Maybe we can remove most of this file? |
||
| const pkgPath = join(dirname, './package.json'); | ||
| const distDir = join(dirname, './dist'); | ||
|
|
||
| if (!existsSync(distDir)) { | ||
| mkdirSync(distDir, { recursive: true }); | ||
| } | ||
|
|
||
| // 1. Get Core Version | ||
| const corePkg = JSON.parse(readFileSync(corePkgPath, 'utf8')); | ||
| const coreVersion = corePkg.version; | ||
| if (!coreVersion) throw new Error('Cannot determine @a2ui/web_core version'); | ||
|
|
||
| // 2. Read Package | ||
| const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')); | ||
|
|
||
| // 3. Update Dependency | ||
| if (pkg.peerDependencies && pkg.peerDependencies['@a2ui/web_core']) { | ||
| pkg.peerDependencies['@a2ui/web_core'] = '^' + coreVersion; | ||
| } else { | ||
| console.warn('Warning: @a2ui/web_core not found in peerDependencies.'); | ||
| } | ||
| if (pkg.devDependencies && pkg.devDependencies['@a2ui/web_core']) { | ||
| // We can just remove devDependencies for the published package, or update it | ||
| pkg.devDependencies['@a2ui/web_core'] = '^' + coreVersion; | ||
| } | ||
|
|
||
| // 4. Adjust Paths for Dist | ||
| pkg.main = adjustPath(pkg.main); | ||
| pkg.types = adjustPath(pkg.types); | ||
|
|
||
| if (pkg.exports) { | ||
| for (const key in pkg.exports) { | ||
| const exp = pkg.exports[key]; | ||
| if (typeof exp === 'string') { | ||
| pkg.exports[key] = adjustPath(exp); | ||
| } else { | ||
| if (exp.types) exp.types = adjustPath(exp.types); | ||
| if (exp.default) exp.default = adjustPath(exp.default); | ||
| if (exp.import) exp.import = adjustPath(exp.import); | ||
| if (exp.require) exp.require = adjustPath(exp.require); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Remove files and wireit properties since we are publishing the dist folder directly | ||
| delete pkg.files; | ||
| delete pkg.wireit; | ||
| delete pkg.scripts; | ||
|
|
||
| // 5. Write to dist/package.json | ||
| writeFileSync(join(distDir, 'package.json'), JSON.stringify(pkg, null, 2)); | ||
|
|
||
| // 6. Copy README and LICENSE | ||
| // LICENSE is in the root directory for this package structure, or we can copy from parent | ||
| const licenseSrc = join(dirname, '../../../LICENSE'); | ||
| const readmeSrc = join(dirname, 'README.md'); | ||
|
|
||
| if (existsSync(readmeSrc)) { | ||
| copyFileSync(readmeSrc, join(distDir, 'README.md')); | ||
| } | ||
| if (existsSync(licenseSrc)) { | ||
| copyFileSync(licenseSrc, join(distDir, 'LICENSE')); | ||
| } else { | ||
| console.warn("Could not find LICENSE at " + licenseSrc); | ||
| } | ||
|
|
||
| console.log(`Prepared dist/package.json with @a2ui/web_core@${coreVersion}`); | ||
|
|
||
| // Utility function to adjust the paths of the built files (dist/src/*) to (src/*) | ||
| function adjustPath(p) { | ||
| if (p && p.startsWith('./dist/')) { | ||
| return './' + p.substring(7); // Remove ./dist/ | ||
| } | ||
| return p; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| node_modules/ | ||
| dist/ | ||
| .wireit/ | ||
| .npmrc |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # @a2ui/web_core | ||
|
|
||
| This is the Core Library for A2UI web renderers. | ||
|
|
||
| ## Installation | ||
|
|
||
| ```sh | ||
| npm install @a2ui/web_core | ||
| ``` | ||
|
|
||
| ## Usage | ||
|
|
||
| Please refer to the A2UI documentation for usage instructions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should stop post-processing the
web_coredependency, and instead, take a dependency on the version of the package that's published on npm. That way, these build script could be simplified quite a lot! WDYT?Then, we'd need some instructions on how to develop locally to be able to modify multiple packages at once, with workspaces, or npm link (?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my 2¢ is a npm link workflow is probably the best way to approach this, whenever we document that.