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

chore(ci): publish to staging on merge of PR with deploy-to-staging l… #58

Merged
merged 2 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/actions/build-anchor/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: "Anchor Build"
description: "Build a program using Anchor"
inputs:
program:
description: "The program to build"
required: true
program_id:
description: "The program address"
required: true
replace_program_id:
description: "Whether to replace current program id with `program_id` in lib.rs, e.g. when deploying to a staging address"

runs:
using: "composite"
steps:
- name: Cache Anchor build
uses: actions/cache@v3
id: cache-anchor-build
if: env.CACHE != 'true' || steps.cache-anchor-build.outputs.cache-hit != 'true'
with:
path: |
./target/
key: build-${{ runner.os }}-${{env.ANCHOR_VERSION}}-${{ hashFiles(format('./programs/{0}/**', inputs.program)) }}-${{ inputs.program }}-${{ inputs.staging }}

- name: Replace program ID if needed
if: inputs.replace_program_id == 'true'
env:
PROGRAM_ID: ${{ inputs.program_id }}
run: |
sed -i "s/declare_id!(\".*\")/declare_id!(\"${PROGRAM_ID}\")/g" ./programs/${{ inputs.program }}/src/lib.rs
shell: bash

- name: Build with Anchor
run: ~/.cargo/bin/anchor build -p ${{ inputs.program }}
shell: bash

- name: Store .so files
uses: actions/upload-artifact@v3
with:
name: ${{inputs.program}}-so
path: |
./target/deploy/${{inputs.program}}.so

- name: Store IDL files
uses: actions/upload-artifact@v3
with:
name: ${{inputs.program}}-idl
path: |
./target/idl/${{inputs.program}}.json
49 changes: 49 additions & 0 deletions .github/actions/deploy-anchor/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: "Deploy Program with Anchor"
description: "Deploy a program to a cluster using Anchor"

inputs:
program:
description: "The program to build"
required: true
program_id:
description: "The program address"
required: true
rpc_url:
description: "The RPC url for the cluster to deploy to"
required: true
upgrade_authority_keypair:
description: "The keypair to use as the upgrade authority"
required: true

runs:
using: "composite"
steps:
- name: Save Upgrade Authority keypair on disk
run: |
echo $UPGRADE_AUTHORITY_KEYPAIR > ./upgrade-authority.json && chmod 600 ./upgrade-authority.json
shell: bash
env:
UPGRADE_AUTHORITY_KEYPAIR: ${{ inputs.upgrade_authority_keypair }}

- name: Deploy .so with Anchor
run: |
~/.cargo/bin/anchor upgrade --program-id $PROGRAM_ID --provider.cluster $RPC_URL --provider.wallet ./upgrade-authority.json ./target/deploy/${PROGRAM_NAME}.so
shell: bash
env:
RPC_URL: ${{ inputs.rpc_url }}
PROGRAM_NAME: ${{ inputs.program }}
PROGRAM_ID: ${{ inputs.program_id }}

- name: Deploy IDL with Anchor
run: |
anchor idl upgrade --provider.cluster $RPC_URL --provider.wallet ./upgrade-authority.json --filepath target/idl/${PROGRAM_NAME}.json $PROGRAM_ID
shell: bash
env:
RPC_URL: ${{ inputs.rpc_url }}
PROGRAM_NAME: ${{ inputs.program }}
PROGRAM_ID: ${{ inputs.program_id }}

- name: Remove Upgrade Authority keypair from disk
run: |
rm ./upgrade-authority.json
shell: bash
49 changes: 49 additions & 0 deletions .github/workflows/check-staging-deployer-balance.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Checks that the balance of the Solana public key
# associated with the UPGRADE_AUTHORITY_KEYPAIR_STAGING is greater than
# the estimated balance required to deploy a program.
name: Check Staging Deployer Balance

on:
pull_request:
branches:
- main
paths:
- 'programs/squads_multisig_program/**'

jobs:
check-balance:
if: contains(github.event.pull_request.labels.*.name, 'deploy-staging')
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup Solana
uses: ./.github/actions/setup-solana/

- name: Check Solana Balance
env:
UPGRADE_AUTHORITY_KEYPAIR: ${{ secrets.UPGRADE_AUTHORITY_KEYPAIR_STAGING }}
RPC_URL: ${{ secrets.RPC_URL_MAINNET }}
run: |
# Write the keypair to a file so it can be used with solana-keygen
echo $UPGRADE_AUTHORITY_KEYPAIR > ./upgrade-authority.json && chmod 600 ./upgrade-authority.json

# Extract the public key from the keypair file
PUBLIC_KEY=$(solana-keygen pubkey ./upgrade-authority.json)

# Remove the keypair file
rm ./upgrade-authority.json

# Fetch the balance of the public key
BALANCE=$(solana balance $PUBLIC_KEY --url $RPC_URL | awk '{print $1}')

MIN_BALANCE=10

# Check if the balance is less than the minimum balance using floating point comparison with `bc`
if (( $(echo "$BALANCE < $MIN_BALANCE" | bc -l) )); then
echo "Balance of $PUBLIC_KEY is $BALANCE, which is less than the minimum balance of $MIN_BALANCE"
exit 1
fi

echo "Balance of $PUBLIC_KEY is $BALANCE SOL"
25 changes: 25 additions & 0 deletions .github/workflows/publish-staging.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Publish to Staging

on:
pull_request:
types:
- closed
branches:
- main
paths:
- 'programs/squads_multisig_program/**'

jobs:
publish-staging:
if: github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'deploy-staging')
uses: ./.github/workflows/reusable-publish-staging.yaml
with:
cache: true
solana_cli_version: 1.17.0
anchor_version: 0.29.0
program: "squads_multisig_program"
program_id: "STAG3xkFMyVK3sRtQhipsKuLpRGbgospDpVdNyJqDpS"
replace_program_id: true
secrets:
RPC_URL: ${{ secrets.RPC_URL_MAINNET }}
UPGRADE_AUTHORITY_KEYPAIR: ${{ secrets.UPGRADE_AUTHORITY_KEYPAIR_STAGING }}
73 changes: 73 additions & 0 deletions .github/workflows/reusable-publish-staging.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: Reusable Publish to Staging

on:
workflow_call:
inputs:
cache:
required: true
type: boolean
solana_cli_version:
required: true
type: string
anchor_version:
required: true
type: string
program:
description: "The program to build"
required: true
type: string
program_id:
description: "The program address"
required: true
type: string
replace_program_id:
description: "Whether to replace current program id with `program_id` in lib.rs, e.g. when deploying to a staging address"
type: boolean

secrets:
RPC_URL:
required: true
UPGRADE_AUTHORITY_KEYPAIR:
required: true

env:
CACHE: inputs.cache
SOLANA_CLI_VERSION: ${{ inputs.solana_cli_version }}
NODE_VERSION: ${{ inputs.node_version }}
CARGO_PROFILE: ${{ inputs.cargo_profile }}
ANCHOR_VERSION: ${{ inputs.anchor_version }}

jobs:
publish:
name: Publish
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup Rust
uses: ./.github/actions/setup-rust/

- name: Setup Solana
uses: ./.github/actions/setup-solana/

- name: Setup Anchor
uses: ./.github/actions/setup-anchor/

- name: Build Anchor
uses: ./.github/actions/build-anchor/
with:
program: ${{ inputs.program }}
program_id: ${{ inputs.program_id }}
replace_program_id: ${{ inputs.replace_program_id }}

- name: Deploy with Anchor
uses: ./.github/actions/deploy-anchor/
with:
program: ${{ inputs.program }}
program_id: ${{ inputs.program_id }}
rpc_url: ${{ secrets.RPC_URL }}
upgrade_authority_keypair: ${{ secrets.UPGRADE_AUTHORITY_KEYPAIR }}


6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
],
"scripts": {
"build": "turbo run build",
"test": "turbo run build && anchor test",
"ts": "turbo run ts && yarn tsc --noEmit",
"deploy": "anchor deploy --provider.cluster mainnet-beta --provider.wallet .keys/upgrade-authority.json --program-name multisig"
"test": "turbo run build && anchor test -- --features=testing && echo \"\n⚠️ Don't forget to recompile the .so file before deployment\n\"",
"pretest": "mkdir -p target/deploy && cp ./test-program-keypair.json ./target/deploy/squads_multisig_program-keypair.json",
"ts": "turbo run ts && yarn tsc --noEmit"
},
"devDependencies": {
"@solana/spl-token": "*",
Expand Down
2 changes: 2 additions & 0 deletions programs/squads_multisig_program/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ no-entrypoint = []
no-idl = []
no-log-ix-name = []
cpi = ["no-entrypoint"]
testing = []
default = []

[dependencies]
anchor-lang = { version = "=0.29.0", features = ["allow-missing-optionals"] }
anchor-spl = { version="=0.29.0", features=["token"] }
solana-security-txt = "1.1.1"
#
4 changes: 4 additions & 0 deletions programs/squads_multisig_program/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ security_txt! {
auditors: "OtterSec, Neodyme"
}

#[cfg(not(feature = "testing"))]
declare_id!("SQDS4ep65T869zMMBKyuUq6aD6EgTu8psMjkvj52pCf");

#[cfg(feature = "testing")]
declare_id!("GyhGAqjokLwF9UXdQ2dR5Zwiup242j4mX4J1tSMKyAmD");

#[program]
pub mod squads_multisig_program {
use super::*;
Expand Down
24 changes: 1 addition & 23 deletions sdk/multisig/.solitarc.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,10 @@ const ignoredTypes = new Set([
"MessageAddressTableLookup",
]);

function loadKeypairFromFile(relativePath) {
try {
const absolutePath = path.join(__dirname, relativePath);
return Keypair.fromSecretKey(
Buffer.from(JSON.parse(readFileSync(absolutePath, "utf-8")))
);
} catch (error) {
console.error("Error reading keypair from file:", error);
return {
publicKey: {
toBase58: () => "SQDS4ep65T869zMMBKyuUq6aD6EgTu8psMjkvj52pCf",
},
};
}
}

const keypair = loadKeypairFromFile(
`../../target/deploy/${PROGRAM_NAME}-keypair.json`
);

const pubkey = keypair.publicKey.toBase58();

module.exports = {
idlGenerator: "anchor",
programName: PROGRAM_NAME,
programId: pubkey,
programId: "SQDS4ep65T869zMMBKyuUq6aD6EgTu8psMjkvj52pCf",
idlDir,
sdkDir,
binaryInstallDir,
Expand Down
11 changes: 9 additions & 2 deletions sdk/multisig/src/instructions/batchAddTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
PublicKey,
TransactionMessage,
} from "@solana/web3.js";
import { createBatchAddTransactionInstruction } from "../generated";
import { createBatchAddTransactionInstruction, PROGRAM_ID } from "../generated";
import {
getBatchTransactionPda,
getProposalPda,
Expand All @@ -22,6 +22,7 @@ export function batchAddTransaction({
ephemeralSigners,
transactionMessage,
addressLookupTableAccounts,
programId = PROGRAM_ID,
}: {
vaultIndex: number;
multisigPda: PublicKey;
Expand All @@ -37,23 +38,28 @@ export function batchAddTransaction({
transactionMessage: TransactionMessage;
/** `AddressLookupTableAccount`s referenced in `transaction_message`. */
addressLookupTableAccounts?: AddressLookupTableAccount[];
programId?: PublicKey;
}) {
const [proposalPda] = getProposalPda({
multisigPda,
transactionIndex: batchIndex,
programId,
});
const [batchPda] = getTransactionPda({
multisigPda,
index: batchIndex,
programId,
});
const [batchTransactionPda] = getBatchTransactionPda({
multisigPda,
batchIndex,
transactionIndex,
programId,
});
const [vaultPda] = getVaultPda({
multisigPda,
index: vaultIndex,
programId,
});

const transactionMessageBytes =
Expand All @@ -77,6 +83,7 @@ export function batchAddTransaction({
ephemeralSigners,
transactionMessage: transactionMessageBytes,
},
}
},
programId
);
}
Loading
Loading