Skip to content
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

Add changeset support (npm publishing part 1) #672

Merged
merged 2 commits into from
Mar 13, 2024
Merged

Add changeset support (npm publishing part 1) #672

merged 2 commits into from
Mar 13, 2024

Conversation

grod220
Copy link
Contributor

@grod220 grod220 commented Mar 5, 2024

Closes #138

We have a few consumers interested in making requests to the extension. That means we need to start publishing our packages to npm 📦. Followed the recommendations from turborepo docs in using changesets for versioning+publishing.

  • Marked packages we don't anticipate publishing with private
  • Uses changeset github action
  • Added deployment docs
  • Adds compilation for a few packages so they can serve as independent packages

Specifically targeting client package to publish first. However, need to handle types, getters, constants, and transport-dom as well due to dep tree.

@turbocrime
Copy link
Contributor

it seems unnecessary to bother with CJS support. both node and the browser have full ESM support now

@turbocrime turbocrime mentioned this pull request Mar 6, 2024
@grod220 grod220 force-pushed the changset-npm branch 7 times, most recently from b345281 to f18494a Compare March 12, 2024 16:53
.eslintrc.js Outdated
@@ -1,7 +1,7 @@
module.exports = {
root: true,
// This tells ESLint to load the config from the package `eslint-config-custom`
extends: ['custom'],
extends: ['@penumbra-zone/eslint-config-custom'],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: packages published externally need to have their dependencies published as well

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's a couple options here which don't require publishing an eslint config package

  1. transition to eslint flat config, so it is no longer a package-level thing
  2. programmatically remove the eslint devDeps with a prepack configuration

Comment on lines +2 to +7
export interface Chain {
displayName: string;
chainId: string;
ibcChannel: string;
iconUrl: string;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We had a hidden cyclical dependency

"lint": "eslint \"**/*.ts*\"",
"test": "vitest run"
},
"dependencies": {
"bip39": "^3.1.0",
"crypto-js": "^4.2.0"
"crypto-js": "^4.2.0",
"@penumbra-zone/types": "workspace:*"
Copy link
Contributor Author

@grod220 grod220 Mar 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two reasons why @penumbra-zone/types was put back in the local directories:

  • Cyclical dependencies (not detected when in parent package.json)
  • Turbo's automatic detection of build dependencies did not work without it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this is correct we should probably raise an issue with turbo

Comment on lines +26 to +28
getWalletServices: vi.fn(() =>
Promise.resolve({ indexedDb: mockIndexedDb }),
) as MockServices['getWalletServices'],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given we have to build all these packages, type errors are now getting caught that went unchecked before

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import { servicesCtx } from '../../ctx';

import { getEphemeralByIndex } from '@penumbra-zone/wasm';

export const ephemeralAddress: Impl['ephemeralAddress'] = async (req, ctx) => {
export const ephemeralAddress: ViewImpl['ephemeralAddress'] = async (req, ctx) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Easier to re-export in barrel file if they aren't all named the same Impl var

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the type is for local use, so we should probably break this out into another file that isn't exported from the package

also, now that we're no longer doing barrel this change could revert

@@ -1,16 +1,27 @@
{
"name": "@penumbra-zone/services",
"version": "1.0.0",
"version": "1.0.1",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These packages might have strange version numbers, but that's just because I've been publishing to test it out. Don't think we need to start on a clean 1.0.0 anyway.

@grod220 grod220 requested a review from turbocrime March 12, 2024 18:13
".": "./dist/index.js"
},
"scripts": {
"build": "pnpm clean && tsc && vite build",
Copy link
Contributor Author

@grod220 grod220 Mar 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conundrum, vite build is not idempotent for some reason. Exclude in tsconfig is not respected and therefore tries to re-bundle dist.

{
  "extends": "@penumbra-zone/tsconfig/base.json",
  "exclude": ["node_modules", "dist"],
  "compilerOptions": {
    "outDir": "dist"
  }
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

calling vite build manually demonstrates that it is in fact idempotent. it's actually a tsc problem - the typescript compiler is refusing to clobber existing output

after some experimenting, it seems that tsc is unnecessary, and vite build by itself doesn't complain. if we're using vite-plugin-dts we should either not call tsc or use noEmit in tsconfig anyway

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should keep tsc. It has managed to find type errors in a few packages that are otherwise going unnoticed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok - then let's use tsconfig noEmit

@@ -30,7 +30,7 @@ jobs:

turbo-lint:
name: Lint
runs-on: buildjet-2vcpu-ubuntu-2204
runs-on: buildjet-4vcpu-ubuntu-2204
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need more ram now...

Copy link
Contributor

@turbocrime turbocrime left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's wild that turbo doesn't handle top-level workspace dependencies, but maybe that's just a sign that our types package is overgrown.

i have several suggestions and i'll either PR some changes here or make a separate example branch.

.eslintrc.js Outdated
@@ -1,7 +1,7 @@
module.exports = {
root: true,
// This tells ESLint to load the config from the package `eslint-config-custom`
extends: ['custom'],
extends: ['@penumbra-zone/eslint-config-custom'],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's a couple options here which don't require publishing an eslint config package

  1. transition to eslint flat config, so it is no longer a package-level thing
  2. programmatically remove the eslint devDeps with a prepack configuration

apps/extension/src/approve-origin.ts Show resolved Hide resolved
apps/extension/src/clients.ts Outdated Show resolved Hide resolved
packages/crypto/index.ts Outdated Show resolved Hide resolved
"lint": "eslint \"**/*.ts*\"",
"test": "vitest run"
},
"dependencies": {
"bip39": "^3.1.0",
"crypto-js": "^4.2.0"
"crypto-js": "^4.2.0",
"@penumbra-zone/types": "workspace:*"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this is correct we should probably raise an issue with turbo

apps/extension/tsconfig.json Outdated Show resolved Hide resolved
".": "./dist/index.js"
},
"scripts": {
"build": "pnpm clean && tsc && vite build",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

calling vite build manually demonstrates that it is in fact idempotent. it's actually a tsc problem - the typescript compiler is refusing to clobber existing output

after some experimenting, it seems that tsc is unnecessary, and vite build by itself doesn't complain. if we're using vite-plugin-dts we should either not call tsc or use noEmit in tsconfig anyway

@grod220 grod220 mentioned this pull request Mar 13, 2024
20 tasks
@grod220 grod220 self-assigned this Mar 13, 2024
@grod220 grod220 added the ci/cd Deployment and github action related label Mar 13, 2024
@grod220 grod220 changed the title Add changeset support (npm publishing) Add changeset support (npm publishing part 1) Mar 13, 2024
@grod220 grod220 force-pushed the changset-npm branch 3 times, most recently from 58c963f to 917fce8 Compare March 13, 2024 11:20
@grod220
Copy link
Contributor Author

grod220 commented Mar 13, 2024

A new starting point in attempt to publish client package. Required:

  • client
  • constants
  • getters
  • polyfills
  • transport-dom
  • types

Reverted

  • crypto
  • estlint-custom-config
  • query
  • router
  • services
  • storage
  • tailwind-config
  • transport-chrome
  • ts-config

Surprised that eslint/ts-config is no longer giving publishing issues. I suppose it's because they are parent package.json deps now? Can't remember the issue before.

@grod220
Copy link
Contributor Author

grod220 commented Mar 13, 2024

Removed the barrel files for these packages we are now exposing. Thought, it kinda feels... wrong. I feel like there is major issue in javascript land that a clean API and performant imports are not compatible. Regardless, this is something perhaps we can explore ongoingly.

Comment on lines +10 to +13
".": "./dist/prax.js",
"./global": "./dist/global.js",
"./src/global": "./dist/global.js",
"./get-port": "./dist/get-port.js"
Copy link
Contributor Author

@grod220 grod220 Mar 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is kinda the demo of how we can make external packages a bit nicer (given the circumstances).

"./src/global": "./dist/global.js", <-- the way that internal packages require the exports
"./global": "./dist/global.js", <-- external packages get the ability to lose the /src/ part of the import
".": "./dist/prax.js", <-- the default . is the only harmonized internal/external import that drops the need for /src/. In this case, gave that honor to prax.js as it's likely the most common import for this package.

Note: I did not do this with any other package. The redundancy with say @penumbra-zone/types would be massive and difficult to maintain. Likely for later we need to consider a specific external/internal package.json.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from my example

"exports": {
".": "./src/index.ts",
"./*": "./src/*.ts"
},
"publishConfig": {
"files": [
"dist"
],
"exports": {
".": {
"import": "./dist/src/index.js",
"types": "./dist/src/index.d.ts"
},
"./*": {
"import": "./dist/src/*.js",
"types": "./dist/src/*.d.ts"
}
}
},

the types package, which is private in example and needs no publication, remains unchanged

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The types package is a dependency of this package. If we do not publish it, it will throw an error when the external app goes to npm install it

Copy link
Contributor

@turbocrime turbocrime left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this still seems overcomplicated with many unnecessary changes, and we really don't need to be publishing internal packages like tsconfig. i'll make a PR cleaning up tsconfig today

Comment on lines +10 to +13
".": "./dist/prax.js",
"./global": "./dist/global.js",
"./src/global": "./dist/global.js",
"./get-port": "./dist/get-port.js"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from my example

"exports": {
".": "./src/index.ts",
"./*": "./src/*.ts"
},
"publishConfig": {
"files": [
"dist"
],
"exports": {
".": {
"import": "./dist/src/index.js",
"types": "./dist/src/index.d.ts"
},
"./*": {
"import": "./dist/src/*.js",
"types": "./dist/src/*.d.ts"
}
}
},

the types package, which is private in example and needs no publication, remains unchanged

".": "./dist/index.js"
},
"scripts": {
"build": "pnpm clean && tsc && vite build",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok - then let's use tsconfig noEmit

import { servicesCtx } from '../../ctx';

import { getEphemeralByIndex } from '@penumbra-zone/wasm';

export const ephemeralAddress: Impl['ephemeralAddress'] = async (req, ctx) => {
export const ephemeralAddress: ViewImpl['ephemeralAddress'] = async (req, ctx) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the type is for local use, so we should probably break this out into another file that isn't exported from the package

also, now that we're no longer doing barrel this change could revert

Comment on lines +26 to +28
getWalletServices: vi.fn(() =>
Promise.resolve({ indexedDb: mockIndexedDb }),
) as MockServices['getWalletServices'],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

case: 'visible',
case: 'decoded',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A type error that's been fixed

package.json Outdated
"all-check": "pnpm install && pnpm compile && pnpm format-check && pnpm lint && pnpm test && pnpm download-keys && pnpm build && pnpm format-check:rust && pnpm lint:rust && pnpm test:rust"
"changeset": "changeset",
"changeset:publish": "changeset publish",
"all-check": "pnpm install && pnpm clean && pnpm compile && pnpm format-check && pnpm lint && pnpm test && pnpm download-keys && pnpm build && pnpm format-check:rust && pnpm lint:rust"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think having clean in all-check makes dev difficult because it blows away keys and results in a lot of redownload

apps/extension/src/message/popup.ts Outdated Show resolved Hide resolved
apps/extension/src/popup.ts Show resolved Hide resolved
@@ -1,5 +1,5 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { StoreApi, UseBoundStore, create } from 'zustand';
import { create, StoreApi, UseBoundStore } from 'zustand';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems like a good chunk of these changes are due to import sorting, can you turn that off

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol definitely not

@grod220
Copy link
Contributor Author

grod220 commented Mar 13, 2024

this still seems overcomplicated with many unnecessary changes

Most of these changes were due to the fact we are now building and it exposed a number of typing issues.

and we really don't need to be publishing internal packages like tsconfig

It is not, it's a private package

@turbocrime
Copy link
Contributor

the polyfill publish is broken

Copy link
Contributor

@turbocrime turbocrime left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merge it create issues for further concerns

@grod220 grod220 merged commit 4ef2ef7 into main Mar 13, 2024
6 checks passed
@grod220 grod220 deleted the changset-npm branch March 13, 2024 21:02
This was referenced Mar 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ci/cd Deployment and github action related
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Npm package publishing
2 participants