-
Notifications
You must be signed in to change notification settings - Fork 27
feat(cli): improve publish command output #1613
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: dev
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 |
|---|---|---|
|
|
@@ -8,7 +8,7 @@ import { | |
| PackageReference, | ||
| preparePublishPackage, | ||
| } from '@usecannon/builder'; | ||
| import { blueBright, bold, gray } from 'chalk'; | ||
| import { bold, cyanBright, gray, green, yellow } from 'chalk'; | ||
| import prompts from 'prompts'; | ||
| import * as viem from 'viem'; | ||
| import { log } from '../util/console'; | ||
|
|
@@ -37,22 +37,17 @@ interface DeployList { | |
| export async function publish({ | ||
| fullPackageRef, | ||
| cliSettings, | ||
| onChainRegistry, | ||
| tags = ['latest'], | ||
| onChainRegistry, | ||
| chainId, | ||
| quiet = false, | ||
| includeProvisioned = true, | ||
| skipConfirm = false, | ||
| }: Params) { | ||
| if (onChainRegistry instanceof OnChainRegistry) { | ||
| if (!onChainRegistry.signer) { | ||
| throw new Error('signer not provided in registry'); | ||
| } | ||
| if (!quiet) { | ||
| log(blueBright(`Publishing with ${onChainRegistry.signer!.address}`)); | ||
| log(); | ||
| } | ||
| if (onChainRegistry instanceof OnChainRegistry && !onChainRegistry.signer) { | ||
| throw new Error('signer not provided in registry'); | ||
| } | ||
|
|
||
| // Generate CannonStorage to publish ipfs remotely and write to the registry | ||
| const toStorage = new CannonStorage(onChainRegistry, { | ||
| ipfs: new IPFSLoader(cliSettings.publishIpfsUrl || getCannonRepoRegistryUrl()), | ||
|
|
@@ -62,7 +57,6 @@ export async function publish({ | |
| const localRegistry = new LocalRegistry(cliSettings.cannonDirectory); | ||
| const fromStorage = new CannonStorage(localRegistry, getMainLoader(cliSettings)); | ||
|
|
||
| // if the package reference is an ipfs reference (url or hash) we pass it the full package ref since its referencing a specific deploy | ||
| let deploys = await localRegistry.scanDeploys(fullPackageRef, chainId); | ||
|
|
||
| if (!deploys || deploys.length === 0) { | ||
|
|
@@ -127,7 +121,7 @@ export async function publish({ | |
| chainId: deploys[0].chainId, | ||
| fromStorage, | ||
| toStorage, | ||
| tags: publishTags!, | ||
| tags: publishTags, | ||
| includeProvisioned, | ||
| }); | ||
|
|
||
|
|
@@ -138,54 +132,75 @@ export async function publish({ | |
| throw new Error("There isn't anything new to publish."); | ||
| } | ||
|
|
||
| for (const publishCall of publishCalls) { | ||
| const packageName = new PackageReference(publishCall.packagesNames[0]).name; | ||
| log(blueBright(`\nThis will publish ${bold(packageName)} to the registry:`)); | ||
|
|
||
| for (const fullPackageRef of publishCall.packagesNames) { | ||
| const { version, preset } = new PackageReference(fullPackageRef); | ||
| log(` - ${version} (preset: ${preset})`); | ||
| if (!quiet) { | ||
| if (onChainRegistry instanceof OnChainRegistry) { | ||
| log('\n' + bold('Publishing Package')); | ||
| log(gray('================================================================================')); | ||
| log(`Package: ${cyanBright(fullPackageRef)}`); | ||
| log(`Signer: ${cyanBright(onChainRegistry.signer!.address)}`); | ||
| log(gray('================================================================================\n')); | ||
| } | ||
| } | ||
|
|
||
| log(); | ||
|
|
||
| if (onChainRegistry instanceof OnChainRegistry) { | ||
| const totalFees = await onChainRegistry.calculatePublishingFee(publishCalls.length); | ||
|
|
||
| log(`Total publishing fees: ${viem.formatEther(totalFees)} ETH`); | ||
| log(); | ||
| log(bold('Package Details:')); | ||
| for (const publishCall of publishCalls) { | ||
| const packageName = new PackageReference(publishCall.packagesNames[0]).name; | ||
| log(gray('--------------------------------------------------------------------------------')); | ||
| log(`Package: ${cyanBright(packageName)}`); | ||
|
|
||
| for (const fullPackageRef of publishCall.packagesNames) { | ||
| const { version, preset } = new PackageReference(fullPackageRef); | ||
| log(` • ${cyanBright(version)}${preset !== 'main' ? ` (preset: ${preset})` : gray(' (default)')}`); | ||
| } | ||
|
|
||
| if (publishCall.url) { | ||
| log(gray('\nIPFS Data:')); | ||
| log(gray(` URL: ${publishCall.url}`)); | ||
| } | ||
| } | ||
|
|
||
| if ( | ||
| totalFees > 0n && | ||
| totalFees >= (await onChainRegistry.provider!.getBalance({ address: onChainRegistry.signer!.address })) | ||
| ) { | ||
| throw new Error('You do not appear to have enough ETH in your wallet to publish'); | ||
| if (onChainRegistry instanceof OnChainRegistry) { | ||
| const totalFees = await onChainRegistry.calculatePublishingFee(publishCalls.length); | ||
|
|
||
| log(bold('\nTransaction Details:')); | ||
| log(gray(` Publishing Fee: ${viem.formatEther(totalFees)} ETH`)); | ||
|
|
||
| if (totalFees > 0n) { | ||
| const balance = await onChainRegistry.provider!.getBalance({ | ||
| address: onChainRegistry.signer!.address | ||
| }); | ||
|
|
||
| if (totalFees >= balance) { | ||
| throw new Error('You do not appear to have enough ETH in your wallet to publish'); | ||
| } | ||
|
Contributor
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. The balance check is now inside if (onChainRegistry instanceof OnChainRegistry) {
const totalFees = await onChainRegistry.calculatePublishingFee(publishCalls.length);
if (totalFees > 0n) {
const balance = await onChainRegistry.provider!.getBalance({
address: onChainRegistry.signer!.address
});
if (totalFees >= balance) {
throw new Error('You do not appear to have enough ETH in your wallet to publish');
}
}
if (!quiet) {
log(bold('\nTransaction Details:'));
log(gray(` Publishing Fee: ${viem.formatEther(totalFees)} ETH`));
}
} |
||
| } | ||
| } | ||
| } | ||
|
|
||
| if (!skipConfirm) { | ||
| const verification = await prompts({ | ||
| const { proceed } = await prompts({ | ||
| type: 'confirm', | ||
| name: 'confirmation', | ||
| message: 'Proceed?', | ||
| initial: true, | ||
| name: 'proceed', | ||
| message: 'Proceed with publishing?', | ||
| }); | ||
|
|
||
| if (!verification.confirmation) { | ||
| log('Cancelled'); | ||
| process.exit(1); | ||
| if (!proceed) { | ||
|
Contributor
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. Good change —
Contributor
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. Good change — |
||
| throw new Error('User aborted'); | ||
| } | ||
| } | ||
|
|
||
| log(bold('Publishing package...')); | ||
| log(gray('This may take a few minutes.')); | ||
| log(); | ||
|
|
||
| const registrationReceipts = await toStorage.registry.publishMany(publishCalls); | ||
|
|
||
| if (!quiet) { | ||
| log(blueBright('Transactions:')); | ||
| for (const tx of registrationReceipts) log(` - ${tx}`); | ||
| log(gray('\nPublishing packages...')); | ||
| } | ||
|
|
||
| const txHashes = await onChainRegistry.publishMany(publishCalls); | ||
|
|
||
| if (!quiet) { | ||
| log(`\n${green('✓')} Successfully published packages`); | ||
| for (const txHash of txHashes) { | ||
|
Contributor
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. Good change — returning the txHashes makes this function more useful for programmatic consumers.
Contributor
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. Good change — returning the txHashes makes this function more useful for programmatic consumers. |
||
| log(gray(`Transaction Hash: ${txHash}`)); | ||
| } | ||
| log('\n'); | ||
| } | ||
|
|
||
| return txHashes; | ||
| } | ||
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.
The balance check is now inside
if (!quiet), meaning in quiet mode the insufficient balance check is skipped. The transaction will still fail, but the user gets a less helpful error. Consider moving the balance check outside the!quietblock: