|
1 | | -# Reusable github workflow |
| 1 | +## Reusable Github workflow for solana programs |
2 | 2 |
|
| 3 | +This repository provides GitHub workfloes that automatically build, verify, and deploy solana programs including their IDL uploads. |
| 4 | +There is also squads multisig support which is highly recommended to use. |
| 5 | +Here you can find a [detailed guide](https://github.com/solana-developers/squads-program-action) on how to use the squads integration. For the workflow you just need to set `use-squads` to true and add the needed secrets. |
| 6 | + |
| 7 | +### Features |
| 8 | + |
| 9 | +- ✅ Automated program builds |
| 10 | +- ✅ Program verification against source code |
| 11 | +- ✅ IDL buffer creation and uploads |
| 12 | +- ✅ Squads multisig integration |
| 13 | +- ✅ Program deploys for both devnet and mainnet |
| 14 | +- ✅ Compute budget optimization |
| 15 | +- ✅ Retry mechanisms for RPC failures |
| 16 | + |
| 17 | +### How to use |
| 18 | + |
| 19 | +```toml |
| 20 | +name: Devnet Build and Deploy |
| 21 | + |
| 22 | +on: |
| 23 | + workflow_dispatch: |
| 24 | + inputs: |
| 25 | + priority_fee: |
| 26 | + description: "Priority fee for transactions" |
| 27 | + required: true |
| 28 | + default: "300000" |
| 29 | + type: string |
| 30 | + |
| 31 | +jobs: |
| 32 | + build: |
| 33 | + uses: solana-developers/github-workflows/.github/workflows/reusable-build.yaml@main |
| 34 | + with: |
| 35 | + program: "hello_world" |
| 36 | + network: "devnet" |
| 37 | + deploy: true |
| 38 | + upload_idl: false |
| 39 | + verify: false |
| 40 | + use-squads: false |
| 41 | + priority-fee: ${{ github.event.inputs.priority_fee }} |
| 42 | + secrets: |
| 43 | + DEVNET_SOLANA_DEPLOY_URL: ${{ secrets.DEVNET_SOLANA_DEPLOY_URL }} |
| 44 | + DEVNET_DEPLOYER_KEYPAIR: ${{ secrets.DEVNET_DEPLOYER_KEYPAIR }} |
| 45 | + PROGRAM_ADDRESS_KEYPAIR: ${{ secrets.PROGRAM_ADDRESS_KEYPAIR }} |
| 46 | +``` |
| 47 | + |
| 48 | +Or for mainnet with verification: |
| 49 | + |
| 50 | +```toml |
| 51 | +name: Release to mainnet with IDL and verify |
| 52 | + |
| 53 | +on: |
| 54 | + workflow_dispatch: |
| 55 | + inputs: |
| 56 | + priority_fee: |
| 57 | + description: "Priority fee for transactions" |
| 58 | + required: true |
| 59 | + default: "300000" |
| 60 | + type: string |
| 61 | + |
| 62 | +jobs: |
| 63 | + build: |
| 64 | + uses: solana-developers/github-workflows/.github/workflows/reusable-build.yaml@main |
| 65 | + with: |
| 66 | + program: "transaction_example" |
| 67 | + network: "mainnet" |
| 68 | + deploy: true |
| 69 | + upload_idl: true |
| 70 | + verify: true |
| 71 | + use-squads: false |
| 72 | + priority-fee: ${{ github.event.inputs.priority_fee }} |
| 73 | + |
| 74 | + secrets: |
| 75 | + MAINNET_SOLANA_DEPLOY_URL: ${{ secrets.MAINNET_SOLANA_DEPLOY_URL }} |
| 76 | + MAINNET_DEPLOYER_KEYPAIR: ${{ secrets.MAINNET_DEPLOYER_KEYPAIR }} |
| 77 | + PROGRAM_ADDRESS_KEYPAIR: ${{ secrets.PROGRAM_ADDRESS_KEYPAIR }} |
| 78 | + MAINNET_MULTISIG: ${{ secrets.MAINNET_MULTISIG }} |
| 79 | + MAINNET_MULTISIG_VAULT: ${{ secrets.MAINNET_MULTISIG_VAULT }} |
| 80 | +``` |
| 81 | + |
| 82 | +There are two examples: |
| 83 | + |
| 84 | +- [Anchor Program](https://github.com/Woody4618/anchor-github-action-example) |
| 85 | +- [Native Program](https://github.com/Woody4618/native-solana-github-action-example) |
| 86 | + |
| 87 | +### Required Secrets for specific actions |
| 88 | + |
| 89 | +Some of the options of the build workflow require you to add secrets to your repository: |
| 90 | + |
| 91 | +```bash |
| 92 | +# Network RPC URLs |
| 93 | +DEVNET_SOLANA_DEPLOY_URL= # Your devnet RPC URL - Recommended to use a payed RPC url |
| 94 | +MAINNET_SOLANA_DEPLOY_URL= # Your mainnet RPC URL - Recommended to use a payed RPC url |
| 95 | + |
| 96 | +# Deployment Keys |
| 97 | +DEVNET_DEPLOYER_KEYPAIR= # Base58 encoded keypair for devnet |
| 98 | +MAINNET_DEPLOYER_KEYPAIR= # Base58 encoded keypair for mainnet |
| 99 | + |
| 100 | +PROGRAM_ADDRESS_KEYPAIR= # Keypair of the program address - Needed for initial deploy and for native programs to find the program address. Can also be overwritten in the workflow if you dont have the keypair. |
| 101 | + |
| 102 | +# For Squads integration (There is sadly no devnet squads ui) |
| 103 | +MAINNET_MULTISIG= # Mainnet Squads multisig address |
| 104 | +MAINNET_MULTISIG_VAULT= # Mainnet Squads vault address |
| 105 | +``` |
| 106 | + |
| 107 | +### Extend and automate |
| 108 | + |
| 109 | +You can easily extend or change your workflow. For example run the build workflow automatically on every push to a development branch. |
| 110 | + |
| 111 | +```bash |
| 112 | + push: |
| 113 | + branches: |
| 114 | + - develop |
| 115 | + - dev |
| 116 | + - development |
| 117 | + paths: |
| 118 | + - 'programs/**' |
| 119 | + - 'Anchor.toml' |
| 120 | + - 'Cargo.toml' |
| 121 | + - 'Cargo.lock' |
| 122 | +``` |
| 123 | + |
| 124 | +Or run a new release to mainnet on every tag push for example. |
| 125 | + |
| 126 | +```bash |
| 127 | + push: |
| 128 | + tags: |
| 129 | + - 'v*' |
| 130 | +``` |
| 131 | + |
| 132 | +Or you can setup a matrix build for multiple programs and networks. |
| 133 | +Customize the workflow to your needs! |
| 134 | + |
| 135 | +### Running the actions locally |
| 136 | + |
| 137 | +If you for some reason want to run the actions locally you can do so with the following commands using the act command. |
| 138 | + |
| 139 | +Follow the instructions [here](https://nektosact.com/installation/index.html) to install act. |
| 140 | + |
| 141 | +1. Build |
| 142 | + |
| 143 | +You need to copy the workflow file to your local `.github/workflows` directory because act does not support reusable workflows. |
| 144 | +Just pick the parameters you want. This is using act to run the workflow locally. Good for testing or if you dont want to install anything because this is running in docker and outputs the build artifacts as well. |
| 145 | + |
| 146 | +```bash |
| 147 | +act -W .github/workflows/reusable-build.yaml \ |
| 148 | + --container-architecture linux/amd64 \ |
| 149 | + --secret-file .secrets \ |
| 150 | + workflow_dispatch \ |
| 151 | + --input program=transaction-example \ |
| 152 | + --input network=devnet \ |
| 153 | + --input deploy=true \ |
| 154 | + --input upload_idl=true \ |
| 155 | + --input verify=true \ |
| 156 | + --input use-squads=false |
| 157 | +``` |
| 158 | + |
| 159 | +2. Run anchor tests |
| 160 | + |
| 161 | +Note: The anchor tests use solana-test-validator which does not work in act docker container on mac because of AVX dependency. Wither run them in github, locally without docker or open PR to fix it. I couldnt find a nice way to fix it. |
| 162 | +You can adjust the workflow to run your specific tests as well. |
| 163 | + |
| 164 | +```bash |
| 165 | +act -W .github/workflows/test.yaml \ |
| 166 | + --container-architecture linux/amd64 \ |
| 167 | + --secret-file .secrets \ |
| 168 | + workflow_dispatch \ |
| 169 | + --input program=transaction-example |
| 170 | +``` |
| 171 | + |
| 172 | +## How to setup Squads integration: |
| 173 | + |
| 174 | +In general its recommended to use the [Squads Multisig](https://docs.squads.so/squads-cli/overview) to manage your programs. |
| 175 | +It makes your program deployments more secure and is considered good practice. |
| 176 | + |
| 177 | +1. Setup a new squad in [Squads](https://v4.squads.so/squads/) then transfer your program authority to the squad. |
| 178 | + |
| 179 | +2. Add your local keypair to the squad as a member (At least needs to be a voter) so that you can propose transactions. And also add that keypair as a github secret. |
| 180 | + To run it locally add the following to your .secrets file: |
| 181 | + |
| 182 | + |
| 183 | + |
| 184 | +```bash |
| 185 | +DEVNET_DEPLOYER_KEYPAIR= |
| 186 | +MAINNET_DEPLOYER_KEYPAIR= |
| 187 | +``` |
| 188 | + |
| 189 | +2. Add the following to your .secrets file if you want to run it locally or add them to your github secrets if you want to run it in github actions: |
| 190 | + |
| 191 | +```bash |
| 192 | +DEVNET_MULTISIG= |
| 193 | +DEVNET_MULTISIG_VAULT= |
| 194 | +MAINNET_MULTISIG= |
| 195 | +MAINNET_MULTISIG_VAULT= |
| 196 | +``` |
| 197 | + |
| 198 | +Where Multisig vault is the address you can find on the top left corner in the [Squads Dachboard](https://v4.squads.so/squads/) |
| 199 | +The MULTISIG is the address of the multisig you want to use this one you can find the the settings. Its a bit more hidden so that people dont accidentally use it as program upgrade authority. |
| 200 | + |
| 201 | +What this will do is write a program and an IDL buffer for your program and then propose a transaction that you can approve in the Squads UI. |
| 202 | + |
| 203 | +4. Now you can run the workflow with the following command: |
| 204 | + |
| 205 | +```bash |
| 206 | +act -W .github/workflows/build.yaml \ |
| 207 | + --container-architecture linux/amd64 \ |
| 208 | + --secret-file .secrets \ |
| 209 | + workflow_dispatch \ |
| 210 | + --input program=transaction-example \ |
| 211 | + --input network=devnet \ |
| 212 | + --input deploy=true \ |
| 213 | + --input upload_idl=true --input use-squads=true --input verify=true |
| 214 | +``` |
| 215 | + |
| 216 | +## 📝 Todo List |
| 217 | + |
| 218 | +### Program Verification |
| 219 | + |
| 220 | +- [x] Trigger verified build PDA upload |
| 221 | +- [x] Verify build remote trigger |
| 222 | +- [x] Support and test squads Verify |
| 223 | +- [x] Support and test squads IDL |
| 224 | +- [x] Support and test squads Program deploy |
| 225 | + |
| 226 | +### Action Improvements |
| 227 | + |
| 228 | +- [x] Separate IDL and Program buffer action |
| 229 | +- [x] Remove deprecated cache functions |
| 230 | +- [x] Remove node-version from anchor build |
| 231 | +- [x] Skip anchor build when native program build |
| 232 | +- [ ] Make verify build and anchor build in parallel |
| 233 | +- [x] Trigger release build on tag push |
| 234 | +- [x] Trigger devnet releases on develop branch? |
| 235 | +- [x] Make solana verify also work locally using cat |
| 236 | +- [x] Use keypairs to find deployer address to remove 2 secrets |
| 237 | +- [x] Add priority fees |
| 238 | +- [x] Add extend program if needed |
| 239 | +- [x] Bundle the needed TS scripts with the .github actions for easier copy paste |
| 240 | + |
| 241 | +### Testing & Integration |
| 242 | + |
| 243 | +- [x] Add running tests |
| 244 | + - Research support for different test frameworks |
| 245 | +- [ ] Add Codama support |
| 246 | +- [ ] Add to solana helpers or mucho -> release |
| 247 | + |
| 248 | +Close Buffer: |
| 249 | + |
| 250 | +You may need this in case your deploy failed and you want to close a buffer that was already transfered to your multisig. |
| 251 | + |
| 252 | +```bash |
| 253 | +solana program show --buffers --buffer-authority <You multisig vault address> |
| 254 | + |
| 255 | +npx ts-node scripts/squad-closebuffer.ts \ |
| 256 | + --rpc "https://api.mainnet-beta.solana.com" \ |
| 257 | + --multisig "FJviNjW3L2u2kR4TPxzUNpfe2ZjrULCRhQwWEu3LGzny" \ |
| 258 | + --buffer "7SGJSG8aoZj39NeAkZvbUvsPDMRcUUrhRhPzgzKv7743" \ |
| 259 | + --keypair ~/.config/solana/id.json \ |
| 260 | + --program "BhV84MZrRnEvtWLdWMRJGJr1GbusxfVMHAwc3pq92g4z" |
| 261 | +``` |
0 commit comments