Deployment workflows for Solana programs — devnet, mainnet, multisig upgrades, CI/CD pipelines, and rollback procedures.
git clone https://github.com/solanabr/solana-ai-kit.git--- name: deployment description: Deployment workflows for Solana programs — devnet, mainnet, multisig upgrades, CI/CD pipelines, and rollback procedures. --- # Deployment Workflows ## Deployment Strategy Overview | Environment | Purpose | Commitment | Upgrades | |------------|---------|------------|----------| | **localnet** | Development | processed | Frequent, no restrictions | | **devnet** | Testing | confirmed | Frequent, test multisig | | **testnet** | Staging | confirmed | Controlled, production-like | | **mainnet** | Production | finalized | Rare, full security review | ## Pre-Deployment Checklist ### Code Quality - [ ] All tests passing (unit, integration, fuzz) - [ ] Security audit completed (for mainnet) - [ ] Code review approved - [ ] No `unwrap()` or `expect()` in program code - [ ] All arithmetic uses checked operations ### Build Verification - [ ] Verifiable build successful - [ ] Binary hash matches expected - [ ] IDL generated and committed - [ ] Client SDK generated and tested ### Security Review - [ ] All accounts validated - [ ] CPI targets hardcoded - [ ] PDA bumps stored - [ ] Accounts reloaded after CPIs - [ ] Reentrancy considered ### Documentation - [ ] CHANGELOG updated - [ ] Migration guide if breaking changes - [ ] User-facing documentation updated --- ## Devnet Deployment ### First Deployment ```bash # 1. Build with verifiable flag anchor build --verifiable # 2. Get program keypair solana-keygen new -o target/deploy/my_program-keypair.json # 3. Airdrop devnet SOL solana airdrop 2 --url devnet # 4. Deploy to devnet anchor deploy --provider.cluster devnet # 5. Verify deployment solana program show <PROGRAM_ID> --url devnet ``` ### Upgrade Deployment ```bash # 1. Build new version anchor build --verifiable # 2. Verify buffer before upgrade solana program write-buffer target/deploy/my_program.so --url devnet solana program show <BUFFER_ADDRESS> --url devnet # 3. Deploy upgrade anchor upgrade target/deploy/my_program.so \ --program-id <PROGRAM_ID> \ --provider.cluster devnet # 4. Close old buffers to reclaim SOL solana program close --buffers --url devnet ``` ### IDL Update ```bash # Update IDL on-chain (required for explorer parsing) anchor idl upgrade --filepath target/idl/my_program.json \ --provider.cluster devnet \ <PROGRAM_ID> ``` --- ## Mainnet Deployment ### Pre-Mainnet Verification ```bash # 1. Full test suite cargo test --all # 2. Fuzz testing (critical paths) trident fuzz run fuzz_0 --iterations 50000 # 3. Build verification anchor build --verifiable anchor verify <PROGRAM_ID> --provider.cluster devnet # 4. Audit tool scan soteria -analyzeAll . ``` ### Mainnet First Deploy ```bash # 1. Ensure sufficient SOL (deployment costs ~2-5 SOL depending on program size) solana balance --url mainnet # 2. Build verifiable anchor build --verifiable # 3. Deploy with confirmation prompts anchor deploy --provider.cluster mainnet # 4. Immediately verify on-chain anchor verify <PROGRAM_ID> --provider.cluster mainnet # 5. Publish IDL anchor idl init --filepath target/idl/my_program.json \ --provider.cluster mainnet \ <PROGRAM_ID> ``` ### Mainnet Upgrade (With Multisig) For production programs, use a multisig upgrade authority: ```bash # 1. Write new buffer (anyone can do this) solana program write-buffer target/deploy/my_program.so \ --url mainnet \ --buffer-authority <MULTISIG_PDA> # 2. Verify buffer contents solana program dump <BUFFER_ADDRESS> buffer_dump.so --url mainnet diff <(xxd target/deploy/my_program.so) <(xxd buffer_dump.so) # 3. Create upgrade proposal via multisig UI (e.g., Squads) # Members review and approve # 4. Execute upgrade after threshold reached # (Handled by multisig program) # 5. Verify post-upgrade anchor verify <PROGRAM_ID> --provider.cluster mainnet ``` --- ## Multisig Setup (Squads v4) ### Creating a Squad for Program Authority ```typescript import { Squads } from "@sqds/multisig"; async function createProgramSquad() { const squads = new Squads({ connection, wallet }); // Create multisig with 2-of-3 threshold const multisigPda = await squads.createMultisig({ threshold: 2, members: [ { pubkey: member1.publicKey, permissions: { vote: true, execute: true } }, { pubkey: member2.publicKey, permissions: { vote: true, execute: true } }, { pubkey: member3.publicKey, permissions: { vote: true, execute: false } }, ], }); console.log("Multisig created:", multisigPda.toString()); return multisigPda; } ``` ### Transferring Upgrade Authority to Multisig ```bash # Transfer program upgrade authority to multisig solana program set-upgrade-authority <PROGRAM_ID> \ --new-upgrade-authority <MULTISIG_PDA> \ --url mainnet ``` ### Creating Upgrade Proposals ```typescript async function proposeUpgrade( squads: Squads, multisigPda: PublicKey, programId: PublicKey, bufferAddress: PublicKey ) { const transaction = await squads.createTransaction({ multisig: multisigPda, instructions: [ SystemProgram.createUpgradeInstruction({ programId, bufferAddress, upgradeAuthority: multisigPda, spillAccount: treasury, }), ], }); console.log("Upgrade proposal created:", transaction.toString()); } ``` ### Upgrade Authority Staging <!-- Adapted from sendaifun/solana-new (deploy-to-mainnet), MIT --> Stage the path to immutability rather than freezing at launch: 1. **Launch → ~3 months** — keep upgrade authority on a secured deployer key (hardware wallet). Bugs surface early; you need the ability to ship fixes fast. 2. **~3 months post-launch** — transfer authority to the Squads multisig (above). Removes single-key risk once the program is stable. 3. **Post-audit, battle-tested** — freeze: `solana program set-upgrade-authority <PROGRAM_ID> --final`. Irreversible and removes any rollback path — only after extensive mainnet history and a completed audit. --- ## CI/CD Pipeline ### GitHub Actions Workflow ```yaml name: Solana Program CI/CD on: push: branches: [main, develop] pull_request: branches: [main] env: SOLANA_VERSION: "2.1.0" ANCHOR_VERSION: "0.31.1" jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup Solana uses: solana-labs/solana-actions/setup@v1 with: solana-version: ${{ env.SOLANA_VERSION }} - name: Setup Anchor run: | cargo install --git https://github.com/coral-xyz/anchor anchor-cli --tag v${{ env.ANCHOR_VERSION }} - name: Install dependencies run: yarn install - name: Build run: anchor build --verifiable - name: Test run: anchor test - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: program-artifacts path: | target/deploy/*.so target/idl/*.json deploy-devnet: needs: test if: github.ref == 'refs/heads/develop' runs-on: ubuntu-latest environment: devnet steps: - uses: actions/checkout@v4 - name: Download artifacts uses: actions/download-artifact@v4 with: name: program-artifacts - name: Setup Solana uses: solana-labs/solana-actions/setup@v1 - name: Configure keypair run: | echo "${{ secrets.DEVNET_DEPLOYER_KEYPAIR }}" > deployer.json solana config set --keypair deployer.json --url devnet - name: Deploy to devnet run: | anchor deploy --provider.cluster devnet - name: Verify deployment run: | anchor verify ${{ vars.PROGRAM_ID }} --provider.cluster devnet deploy-mainnet: needs: test if: github.ref == 'refs/heads/main' && github.event_name == 'push' runs-on: ubuntu-latest environment: mainnet steps: - uses: actions/checkout@v4 - name: Download artifacts uses: actions/download-artifact@v4 with: name: program-artifacts - name: Write buffer run: | # Only write buffer - manual multisig approval required echo "${{ secrets.MAINNET_BUFFER_KEYPAIR }}" > buffer.json solana program write-buffer target/deploy/my_program.so \ --url mainnet \ --keypair buffer.json - name: Output buffer address id: buffer run: echo "::set-output name=address::$(cat buffer-address.txt)" - name: Create PR comment uses: actions/github-script@v7 with: script: | github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: `🚀 Buffer written to mainnet: \`${{ steps.buffer.outputs.address }}\`\n\nApprove upgrade via Squads multisig.` }) ``` --- ## Rollback Procedures ### Devnet Rollback ```bash # Redeploy previous version anchor deploy --provider.cluster devnet \ --program-id <PROGRAM_ID> \ target/deploy/my_program_v1.so ``` ### Mainnet Rollback 1. **Immediate**: If caught quickly, create emergency multisig proposal for rollback 2. **Planned**: Keep previous verified buffer, create upgrade proposal to previous version 3. **Emergency freeze**: If program has freeze capability, pause operations while preparing rollback ### Freeze Pattern (Program Design) ```rust #[account] pub struct GlobalState { pub authority: Pubkey, pub is_frozen: bool, // Emergency stop } // In each instruction pub fn some_instruction(ctx: Context<SomeInstruction>) -> Result<()> { require!(!ctx.accounts.global_state.is_frozen, ErrorCode::ProgramFrozen); // ... instruction logic } ``` --- ## Environment Configuration ### `.env.development` ```env SOLANA_RPC_URL=http://localhost:8899 SOLANA_WS_URL=ws://localhost:8900 PROGRAM_ID=<LOCAL_PROGRAM_ID> ``` ### `.env.devnet` ```env SOLANA_RPC_URL=https://api.devnet.solana.com SOLANA_WS_URL=wss://api.devnet.solana.com PROGRAM_ID=<DEVNET_PROGRAM_ID> ``` ### `.env.mainnet` ```env SOLANA_RPC_URL=https://api.mainnet-beta.solana.com SOLANA_WS_URL=wss://api.mainnet-beta.solana.com PROGRAM_ID=<MAINNET_PROGRAM_ID> # Consider premium RPC providers for production: # - Helius # - QuickNode # - Triton ``` --- ## Deployment Cost Estimation | Action | Approximate Cost | |--------|------------------| | Deploy small program (<100KB) | ~1.5 SOL | | Deploy medium program (100-500KB) | ~3-5 SOL | | Deploy large program (>500KB) | ~5-10 SOL | | Upgrade (buffer write) | Same as deploy | | IDL init/upgrade | ~0.01 SOL | | Close old buffers | Returns ~90% of rent | **Tip**: Close unused buffers after upgrades to reclaim SOL: ```bash solana program close --buffers --url mainnet ``` --- ## Post-Deployment Verification ### On-Chain Verification ```bash # Verify program binary matches source anchor verify <PROGRAM_ID> --provider.cluster mainnet # Check program authority solana program show <PROGRAM_ID> --url mainnet # Verify IDL anchor idl fetch <PROGRAM_ID> --provider.cluster mainnet > fetched_idl.json diff target/idl/my_program.json fetched_idl.json ``` ### Functional Verification ```bash # Run smoke tests against deployed program anchor test --skip-build --provider.cluster devnet # Monitor logs for first transactions solana logs <PROGRAM_ID> --url devnet ``` --- ## Best Practices Summary 1. **Always use verifiable builds** for production deployments 2. **Use multisig** for mainnet upgrade authority 3. **Test on devnet** before mainnet 4. **Keep deployment keys secure** (HSM or multisig) 5. **Document every deployment** with version and hash 6. **Have a rollback plan** before deploying 7. **Monitor post-deployment** for anomalies 8. **Close old buffers** to reclaim SOL
No install command available. Check the GitHub repository for manual installation instructions.
git clone https://github.com/solanabr/solana-ai-kit/blob/main/.claude/skills/deployment.mdCopy the install command above and run it in your terminal.
Launch Claude Code, Cursor, or your preferred AI coding agent.
Use the prompt template or examples below to test the skill.
Adapt the skill to your specific use case and workflow.
Check the GitHub repository or documentation for usage examples.
skills-collection
Take a free 3-minute scan and get personalized AI skill recommendations.
Take free scan