From b437f3dbcb7daa4d5d3c3a5e4e8c062fe252ff5d Mon Sep 17 00:00:00 2001 From: Brian Le Date: Wed, 15 Nov 2023 11:45:00 -0500 Subject: [PATCH] chore: update deploy (#322) --- package.json | 8 ++--- utils/deploy.ts | 96 ++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 88 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 0c28a82c..dd56a65c 100644 --- a/package.json +++ b/package.json @@ -13,13 +13,13 @@ "test:fork": "yarn test --fork-url $ETH_RPC_URL", "test:gas": "forge test --ffi --mc GasBenchmarks -vv", "deploy": "node js/deploy.js", - "deploy:goerli": "DRY_RUN=0 forge script ./deploy/Goerli.s.sol -vvv --rpc-url $GOERLI_RPC_URL --broadcast --etherscan-api-key ${ETHERSCAN_API_KEY} --via-ir --skip test --optimize --optimizer-runs 95 --ffi --slow", + "deploy:goerli": "DRY_RUN=0 forge script ./deploy/Goerli.s.sol -vvv --rpc-url $GOERLI_RPC_URL --broadcast --etherscan-api-key $ETHERSCAN_API_KEY --via-ir --skip test --optimize --optimizer-runs 95 --ffi --slow", "deploy:goerli:dry": "DRY_RUN=1 forge script ./deploy/Goerli.s.sol -vvv --rpc-url $GOERLI_RPC_URL --via-ir --skip test --optimize --optimizer-runs 95 --ffi", - "deploy:mainnet": "DRY_RUN=0 forge script ./deploy/Mainnet.s.sol -vvv --rpc-url $ETH_RPC_URL --broadcast --etherscan-api-key ${ETHERSCAN_API_KEY} --via-ir --skip test --optimize --optimizer-runs 95 --ffi --slow", + "deploy:mainnet": "DRY_RUN=0 forge script ./deploy/Mainnet.s.sol -vvv --rpc-url $ETH_RPC_URL --broadcast --etherscan-api-key $ETHERSCAN_API_KEY --via-ir --skip test --optimize --optimizer-runs 95 --ffi --slow", "deploy:mainnet:dry": "DRY_RUN=1 forge script ./deploy/Mainnet.s.sol -vvv --rpc-url $ETH_RPC_URL --via-ir --skip test --optimize --optimizer-runs 95 --ffi", - "deploy:base": "DRY_RUN=0 forge script ./deploy/Base.s.sol -vvv --rpc-url $BASE_RPC_URL --via-ir --broadcast --etherscan-api-key ${ETHERSCAN_API_KEY} --evm-version paris --skip test --optimize --optimizer-runs 0 --ffi --slow", + "deploy:base": "DRY_RUN=0 forge script ./deploy/Base.s.sol -vvv --rpc-url $BASE_RPC_URL --via-ir --broadcast --etherscan-api-key $BASESCAN_API_KEY --evm-version paris --skip test --optimize --optimizer-runs 0 --ffi --slow", "deploy:base:dry": "DRY_RUN=1 forge script ./deploy/Base.s.sol -vvv --rpc-url $BASE_RPC_URL --via-ir --evm-version paris --skip test --optimize --optimizer-runs 0 --ffi", - "deploy:base-goerli": "DRY_RUN=0 forge script ./deploy/BaseGoerli.s.sol -vvv --rpc-url $BASE_GOERLI_RPC_URL --via-ir --broadcast --etherscan-api-key ${ETHERSCAN_API_KEY} --evm-version paris --skip test --optimize --optimizer-runs 0 --ffi --slow", + "deploy:base-goerli": "DRY_RUN=0 forge script ./deploy/BaseGoerli.s.sol -vvv --rpc-url $BASE_GOERLI_RPC_URL --via-ir --broadcast --etherscan-api-key $BASESCAN_API_KEY --evm-version paris --skip test --optimize --optimizer-runs 0 --ffi --slow", "deploy:base-goerli:dry": "DRY_RUN=1 forge script ./deploy/BaseGoerli.s.sol -vvv --rpc-url $BASE_GOERLI_RPC_URL --via-ir --evm-version paris --skip test --optimize --optimizer-runs 0 --ffi", "decode-revert": "node js/decode-revert.js", "layout": "node js/gen-storage-layout.js", diff --git a/utils/deploy.ts b/utils/deploy.ts index a238cb8e..52b1e3a8 100644 --- a/utils/deploy.ts +++ b/utils/deploy.ts @@ -14,17 +14,19 @@ const rl = readline.createInterface({ output: process.stdout, }); -async function run(command: string) { +async function run(command: string, { captureOutput = false, throwOnError = true } = {}) { const result = childProcess.spawnSync(command, [], { shell: true, - stdio: "inherit", + stdio: captureOutput ? "pipe" : "inherit", }); - if (result.status !== 0) { + if (throwOnError && result.status !== 0) { throw new Error(`Command "${command}" failed with status code ${result.status}`); } - return result.stdout; + if (captureOutput) { + return result.stdout.toString().trim(); + } } async function confirm(question: string, defaultValue?: boolean): Promise { @@ -337,6 +339,74 @@ async function main() { process.exit(1); } + // Get name of remote branch current branch is tracking + const currentBranch = await run("git rev-parse --abbrev-ref HEAD", { + captureOutput: true, + throwOnError: false, + }); + + if (currentBranch) { + const remoteBranch = `origin/${currentBranch}`; + + // Get number of commits current branch is ahead and behind remote branch + const [numOfCommitsBehind, numOfCommitsAhead] = ( + await run(`git rev-list --left-right --count ${remoteBranch}...HEAD`, { + captureOutput: true, + }) + ) + .split("\t") + .map(Number); + + // If current branch is behind remote branch, prompt to pull latest changes + if (numOfCommitsBehind > 0) { + console.warn( + ( + (numOfCommitsBehind > 1 ? `${numOfCommitsBehind} commits` : `1 commit`) + + " behind remote." + ).yellow, + ); + + if (await confirm("Do you want to pull latest changes?", true)) { + await run(`git pull origin ${currentBranch}`); + } + } + + // If current branch is ahead of remote branch, prompt to confirm whether to continue + if (numOfCommitsAhead > 0) { + console.warn( + ( + (numOfCommitsAhead > 1 ? `${numOfCommitsAhead} commits` : `1 commit`) + + " ahead of remote." + ).yellow, + ); + + if (!(await confirm("Do you want to continue?", false))) { + process.exit(0); + } + } + } + + // Get private key of deployer address + const privateKey = process.env.PRIVATE_KEY; + if (!privateKey) { + console.error("Missing PRIVATE_KEY environment variable."); + process.exit(1); + } + + // Check that deployer address is expected address + const deployerAddress = await run(`cast wallet address ${privateKey}`, { + captureOutput: true, + }); + const expectedDeployerAddress = "0x0e63D6f414b40BaFCa676810ef1aBf05ECc8E459"; + if (deployerAddress !== expectedDeployerAddress) { + console.warn( + `Deployer address is ${deployerAddress}, expected ${expectedDeployerAddress}.`.yellow, + ); + if (!(await confirm("Do you want to continue?", false))) { + process.exit(0); + } + } + if ( await confirm( "Do you want to set contract variables to their existing addresses in Deploy.s.sol?", @@ -349,6 +419,10 @@ async function main() { console.warn("Remember to unset variables for contracts that are going to be deployed!".yellow); } + await confirm("Have you updated Deploy.sol to only deploy the contracts you want?", true); + + await confirm("Are there no other changes that should be included into this deploy?", true); + if ( await confirm( "Do you want to check that deploy script variable names match contract names?", @@ -358,12 +432,11 @@ async function main() { await checkDeployContractVariables(); } - await confirm("Have you updated Deploy.sol to only deploy the contracts you want?", true); - + // Run dry run deploy and check that it succeeded let dryRunSucceeded = false; while (!dryRunSucceeded) { if (await confirm("Do dry run?", true)) { - await run(`yarn deploy:${chain}:dry --private-key ${process.env.PRIVATE_KEY}`); + await run(`yarn deploy:${chain}:dry --private-key ${privateKey}`); await run("yarn lint:fix > /dev/null"); await checksumAddresses(`deploy/cache/${chain}.json`); @@ -374,8 +447,6 @@ async function main() { break; } - await confirm("Was the deployer the expected address?", true); - await confirm( `Does deploy/cache/${chain}.json only contain addresses for contracts that changed?`, true, @@ -384,10 +455,8 @@ async function main() { await confirm("Were ABI files in deploy/cache/abis created or changed as you expected?", true); } - await confirm("Are there no other changes that should be included into this deploy?", true); - if (await confirm("Run deploy?", true)) { - run(`yarn deploy:${chain} --private-key ${process.env.PRIVATE_KEY}`); + run(`yarn deploy:${chain} --private-key ${privateKey}`); await run("yarn lint:fix > /dev/null"); await checksumAddresses(`deploy/cache/${chain}.json`); @@ -409,6 +478,9 @@ async function main() { release_name = await new Promise(resolve => rl.question("What is the release name? ", resolve), ); + + // Format the release name to be lowercase and replace spaces and dashes with underscores + release_name = release_name.trim().toLowerCase().replace(/[\s-]/g, "_"); } if (await confirm("Copy deploy script to party-addresses?", false)) {