Skip to content

Commit

Permalink
feat(pg): Add dry-run and confirm flags to the propose task
Browse files Browse the repository at this point in the history
  • Loading branch information
sam-goldman authored and RPate97 committed Aug 9, 2023
1 parent b63b98f commit 0b309f0
Show file tree
Hide file tree
Showing 18 changed files with 409 additions and 197 deletions.
6 changes: 6 additions & 0 deletions .changeset/beige-rabbits-kick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@sphinx-labs/plugins': patch
'@sphinx-labs/core': patch
---

Support proposals in CI
84 changes: 84 additions & 0 deletions docs/ci-foundry-proposals.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Propose Deployments from your CI Process (Foundry)

We recommend that you propose from your CI process instead of using the command line. This ensures that your deployments are reproducible, and that they don't depend on a single developer's machine, which can be a source of bugs.

This guide will show you how to integrate proposals into your CI process using GitHub Actions. You can still follow this guide if you're using a different CI platform, but the exact configuration may be slightly different.

If you're using Sphinx's Hardhat plugin instead of Foundry, check out the [Hardhat version of this guide](https://github.com/sphinx-labs/sphinx/blob/develop/docs/ci-hardhat-proposals.md).

## Table of Contents

TODO

## Prerequisites

Make sure that you've already completed the [Getting Started with the DevOps Platform](https://github.com/sphinx-labs/sphinx/blob/develop/docs/ops-foundry-getting-started.md) guide for the project you're going to use in this guide.

Also, make sure that your `foundry.toml` has an `rpc_endpoints` section that contains an RPC endpoint for each network you want to support in your project.

## Create a new branch in your repo

`git checkout -B sphinx/integrate-ci`

## Create a Github Actions folder

If you already have a `.github/` folder, you can skip this step.

Run the following command in the root directory of your project:

`mkdir -p .github/workflows`

## Create a new workflow `deploy.yml`

`touch .github/workflows/deploy.yml`

## Create the action template

We'll create an action template that runs the `propose` command on every push to the `main` branch.

Copy and paste the following into your `deploy.yml` file:

```
name: Sphinx Propose
env:
PROPOSER_PRIVATE_KEY: ${{ secrets.PROPOSER_PRIVATE_KEY }}
SPHINX_API_KEY: ${{ secrets.SPHINX_API_KEY }}
# Put any node provider API keys or urls here. For example:
# ALCHEMY_API_KEY: ${{ secrets.ALCHEMY_API_KEY }}
# Performs a dryrun proposal when a PR is opened and updated to confirm the
$ proposal will complete successfully after a PR is merged
on: pull_request
jobs:
sphinx-dry-run
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: yarn install
- run: npx sphinx propose --config path/to/config --dry-run
# Triggers a deployment when a change is merged to main
on:
push:
branches:
- main
jobs:
sphinx-propose:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: yarn install
- run: npx sphinx propose --config path/to/config --confirm
```

Here is a checklist of things to do before moving on:
- [ ] Add the `PROPOSER_PRIVATE_KEY` secret to your CI process. This should be the private key of one of the proposer addresses in your Sphinx config file (under the `proposers` field).
- [ ] Add the `SPHINX_API_KEY` secret to your CI process. You can find this in the Sphinx UI after registering your organization.
- [ ] Enter any node provider API keys or urls in the `env` section of the template and make sure they are also [configured as secrets in GitHub actions](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository).
- [ ] If you want to push to a branch other than `main`, update the `branches` section of the template.
- [ ] If your repository doesn't use `yarn install`, update the `yarn install` step under `jobs`.
- [ ] Add the path to your Sphinx config in the `npx sphinx propose` command under `jobs`.

## Test your integration

Push your branch to Github, open a PR, and merge it after the dryrun check completes. You can then go to https://www.sphinx.dev and you'll find your new deployment there.
84 changes: 84 additions & 0 deletions docs/ci-hardhat-proposals.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Propose Deployments from your CI Process (Foundry)

We recommend that you propose from your CI process instead of using the command line. This ensures that your deployments are reproducible, and that they don't depend on a single developer's machine, which can be a source of bugs.

This guide will show you how to integrate proposals into your CI process using GitHub Actions. You can still follow this guide if you're using a different CI platform, but the exact configuration may be slightly different.

If you're using Sphinx's Foundry plugin instead of Foundry, check out the [Foundry version of this guide](https://github.com/sphinx-labs/sphinx/blob/develop/docs/ci-foundry-proposals.md).

## Table of Contents

TODO

## Prerequisites

Make sure that you've already completed the [Getting Started with the DevOps Platform](https://github.com/sphinx-labs/sphinx/blob/develop/docs/ops-hardhat-getting-started.md) guide for the project you're going to use in this guide.

Also, make sure that your `hardhat.config.ts` file has a `networks` section that contains an RPC endpoint for each network you want to support in your project.

## Create a new branch in your repo

`git checkout -B sphinx/integrate-ci`

## Create a Github Actions folder

If you already have a `.github/` folder, you can skip this step.

Run the following command in the root directory of your project:

`mkdir -p .github/workflows`

## Create a new workflow `deploy.yml`

`touch .github/workflows/deploy.yml`

## Create the action template

We'll create an action template that runs the `propose` command on every push to the `main` branch. We'll also use the `--dry-run` flag to check that a proposal will complete successfully whenever a PR is opened and updated.

Copy and paste the following into your `deploy.yml` file:

```
name: Sphinx Propose
env:
PROPOSER_PRIVATE_KEY: ${{ secrets.PROPOSER_PRIVATE_KEY }}
SPHINX_API_KEY: ${{ secrets.SPHINX_API_KEY }}
# Put any node provider API keys or urls here. For example:
# ALCHEMY_API_KEY: ${{ secrets.ALCHEMY_API_KEY }}
# Performs a dryrun proposal when a PR is opened and updated to confirm the
$ proposal will complete successfully after a PR is merged
on: pull_request
jobs:
sphinx-dry-run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: yarn install
- run: npx hardhat sphinx-propose --config-path path/to/config --dry-run
# Triggers a deployment when a change is merged to main
on:
push:
branches:
- main
jobs:
sphinx-propose:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: yarn install
- run: npx hardhat sphinx-propose --config-path path/to/config --confirm
```

Here is a checklist of things to do before moving on:
- [ ] Add the `PROPOSER_PRIVATE_KEY` secret to your CI process. This should be the private key of one of the proposer addresses in your Sphinx config file (under the `proposers` field).
- [ ] Add the `SPHINX_API_KEY` secret to your CI process. You can find this in the Sphinx UI after registering your organization.
- [ ] Enter any node provider API keys or urls in the `env` section of the template and make sure they are also [configured as secrets in GitHub actions](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository).
- [ ] If you want to push to a branch other than `main`, update the `branches` section of the template.
- [ ] If your repository doesn't use `yarn install`, update the `yarn install` step under `jobs`.
- [ ] Add the path to your Sphinx config in the `npx sphinx propose` command under `jobs`.

## Test your integration

Push your branch to Github, open a PR, and merge it after the dryrun check completes. You can then go to https://www.sphinx.dev and you'll find your new deployment ready to be funded and approved.
2 changes: 1 addition & 1 deletion docs/config-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ It contains the following fields:
* Gnosis Chiado: `'gnosis-chiado'`
* `owners`: The list of addresses that own this project. Owners can perform permissioned actions such as approving deployments via the Sphinx UI. We currently only support projects that are owned by a single account.
* `threshold`: The number of owners that must sign a permissioned action, such as approving a deployment, before the action can be executed on-chain.
* `proposers`: The list of addresses that are allowed to propose changes to the Sphinx config file. Any change to the Sphinx config file, including deploying contracts, must be proposed before it can be approved by the project owners. Since proposals are triggered from the CLI, we recommend that proposers are hot wallets, i.e. a wallet that you feel comfortable pasting its private key into a `.env` file. We currently only support projects that have a single proposer, which must be the same address as the owner.
* `proposers`: The list of addresses that are allowed to propose changes to the Sphinx config file. Any change to the Sphinx config file, including contract deployments, must be proposed before it can be approved by the project owners. We recommend that proposals occur in a CI process, but you can also propose from the command line.

## Contracts

Expand Down
6 changes: 5 additions & 1 deletion docs/ops-foundry-getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

This guide will walk you through a sample multi-chain deployment using the Sphinx Foundry plugin and DevOps platform.

If you're using Hardhat instead of Foundry, check out the [Hardhat version of this guide](https://github.com/sphinx-labs/sphinx/blob/develop/docs/ops-hardhat-getting-started.md).

## Table of Contents

1. [Prerequisites](#1-prerequisites)
Expand All @@ -27,7 +29,7 @@ To give some context on the deployment process, here's a high-level overview of

Deployments are a three-step process with the DevOps platform.

1. **Proposal**: The deployment is proposed on the command line. This creates a meta transaction that's signed by the proposer then relayed to Sphinx's back-end.
1. **Proposal**: The deployment is proposed on the command line or in a CI process. This creates a meta transaction that's signed by the proposer then relayed to Sphinx's back-end. For simplicity, we'll propose the deployment on the command line in this guide.
2. **Approval**: Each owner signs a meta transaction to approve the deployment in the Sphinx UI.
3. **Execution**: The deployment is trustlessly executed on-chain by a relayer. In order to execute the deployment, the relayer must submit the meta transactions signed by the proposer and the owners.

Expand Down Expand Up @@ -89,6 +91,8 @@ polygon_mumbai = "https://rpc-mumbai.maticvigil.com"

## 7. Propose the deployment

For simplicity, we'll propose the deployment on the command line in this guide. However, we recommend that you propose deployments in a CI process for production deployments. [Check out the CI integration guide for Foundry.](https://github.com/sphinx-labs/sphinx/blob/develop/docs/ci-foundry-proposals.md)

Add a `PROPOSER_PRIVATE_KEY` field to your `.env`:
```
PROPOSER_PRIVATE_KEY=<your private key>
Expand Down
6 changes: 5 additions & 1 deletion docs/ops-hardhat-getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

This guide will walk you through a sample multi-chain deployment using the Sphinx Hardhat plugin and DevOps platform.

If you're using Foundry instead of Hardhat, check out the [Foundry version of this guide](https://github.com/sphinx-labs/sphinx/blob/develop/docs/ops-foundry-getting-started.md).

## Table of Contents

1. [Prerequisites](#1-prerequisites)
Expand All @@ -24,7 +26,7 @@ To give some context on the deployment process, here's a high-level overview of

Deployments are a three-step process with the DevOps platform.

1. **Proposal**: The deployment is proposed on the command line. This creates a meta transaction that's signed by the proposer then relayed to Sphinx's back-end.
1. **Proposal**: The deployment is proposed on the command line or in a CI process. This creates a meta transaction that's signed by the proposer then relayed to Sphinx's back-end. For simplicity, we'll propose the deployment on the command line in this guide.
2. **Approval**: Each owner signs a meta transaction to approve the deployment in the Sphinx UI.
3. **Execution**: The deployment is trustlessly executed on-chain by a relayer. In order to execute the deployment, the relayer must submit the meta transactions signed by the proposer and the owners.

Expand Down Expand Up @@ -104,6 +106,8 @@ maticmum: {

## 7. Propose the deployment

For simplicity, we'll propose the deployment on the command line in this guide. However, we recommend that you propose deployments in a CI process for production deployments. [Check out the CI integration guide for Hardhat.](https://github.com/sphinx-labs/sphinx/blob/develop/docs/ci-hardhat-proposals.md)

Add a `PROPOSER_PRIVATE_KEY` field to your `.env`:
```
PROPOSER_PRIVATE_KEY=<your private key>
Expand Down
13 changes: 6 additions & 7 deletions packages/core/src/tasks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,19 +89,18 @@ dotenv.config()
* @param getCanonicalConfig A function that returns the canonical config. By default, this function
* will fetch the canonical config from the back-end. However, it can be overridden to return a
* different canonical config. This is useful for testing.
* @param skipRelay If true, the proposal will not be relayed to the back-end. This is for testing
* purposes only.
* @param dryRun If true, the proposal will not be relayed to the back-end.
*/
export const proposeAbstractTask = async (
userConfig: UserConfigWithOptions,
isTestnet: boolean,
cre: SphinxRuntimeEnvironment,
dryRun: boolean,
getConfigArtifacts: GetConfigArtifacts,
getProviderForChainId: GetProviderForChainId,
spinner: ora.Ora = ora({ isSilent: true }),
failureAction: FailureAction = FailureAction.EXIT,
getCanonicalConfig: GetCanonicalConfig = fetchCanonicalConfig,
skipRelay: boolean = false
getCanonicalConfig: GetCanonicalConfig = fetchCanonicalConfig
): Promise<ProposalRequest> => {
const apiKey = process.env.SPHINX_API_KEY
if (!apiKey) {
Expand Down Expand Up @@ -224,7 +223,7 @@ export const proposeAbstractTask = async (
)
}

if (!cre.confirm) {
if (!cre.confirm && !dryRun) {
spinner.stop()
// Confirm deployment with the user before proceeding.
await userConfirmation(getDiffString(diff))
Expand All @@ -251,7 +250,7 @@ export const proposeAbstractTask = async (

// Sign the meta-txn for the auth root, or leave it undefined if we're not relaying the proposal
// to the back-end.
const metaTxnSignature = skipRelay
const metaTxnSignature = dryRun
? undefined
: await signAuthRootMetaTxn(wallet, root)

Expand Down Expand Up @@ -381,7 +380,7 @@ export const proposeAbstractTask = async (
},
}

if (!skipRelay) {
if (!dryRun) {
await relayProposal(proposalRequest)
const compilerConfigArray = Object.values(compilerConfigs)
await relayIPFSCommit(apiKey, orgId, compilerConfigArray)
Expand Down
1 change: 1 addition & 0 deletions packages/plugins/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ allow_paths = ["../contracts"]
anvil = "http://127.0.0.1:8545"
goerli = "http://127.0.0.1:42005"
optimism-goerli = "http://127.0.0.1:42420"
arbitrum-goerli = "http://127.0.0.1:42613"
8 changes: 4 additions & 4 deletions packages/plugins/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,12 @@ const config: HardhatUserConfig = {
// },
// bnbt: {
// chainId: 97,
// url: process.env.BNB_TESTNET_URL,
// url: `${process.env.BNB_TESTNET_URL}`,
// accounts,
// },
// bnb: {
// chainId: 56,
// url: process.env.BNB_MAINNET_URL,
// url: `${process.env.BNB_MAINNET_URL}`,
// accounts,
// },
// 'gnosis-chiado': {
Expand All @@ -80,7 +80,7 @@ const config: HardhatUserConfig = {
// },
// gnosis: {
// chainId: 100,
// url: process.env.GNOSIS_MAINNET_URL,
// url: `${process.env.GNOSIS_MAINNET_URL}`,
// accounts,
// },
// maticmum: {
Expand Down Expand Up @@ -111,7 +111,7 @@ const config: HardhatUserConfig = {
},
'gnosis-chiado': {
chainId: 10200,
url: 'http://127.0.0.1:42102',
url: 'http://127.0.0.1:42200',
accounts,
},
bnbt: {
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"@prb/math": "^4.0.0",
"@sphinx-labs/contracts": "^0.9.4",
"@sphinx-labs/core": "^0.12.6",
"@swc/core": "^1.3.62",
"@swc/core": "^1.3.75",
"core-js": "^3.31.1",
"dotenv": "^16.0.3",
"ds-test": "https://github.com/dapphub/ds-test.git#e282159d5170298eb2455a6c05280ab5a73a4ef0",
Expand Down
Loading

0 comments on commit 0b309f0

Please sign in to comment.