|
| 1 | +name: Deploy Contracts |
| 2 | + |
| 3 | +on: |
| 4 | + workflow_dispatch: |
| 5 | + inputs: |
| 6 | + network: |
| 7 | + description: "Target network" |
| 8 | + required: true |
| 9 | + type: choice |
| 10 | + options: |
| 11 | + - testnet |
| 12 | + - mainnet |
| 13 | + action: |
| 14 | + description: "Deploy action" |
| 15 | + required: true |
| 16 | + type: choice |
| 17 | + options: |
| 18 | + - fresh-deploy |
| 19 | + - upgrade-all |
| 20 | + - upgrade-single |
| 21 | + contract: |
| 22 | + description: "Contract to upgrade (only for upgrade-single)" |
| 23 | + required: false |
| 24 | + type: choice |
| 25 | + options: |
| 26 | + - core_escrow |
| 27 | + - reputation_registry |
| 28 | + - governance_voting |
| 29 | + - project_registry |
| 30 | + - bounty_registry |
| 31 | + - crowdfund_registry |
| 32 | + - grant_hub |
| 33 | + - hackathon_registry |
| 34 | + |
| 35 | +env: |
| 36 | + CARGO_TERM_COLOR: always |
| 37 | + WASM_DIR: target/wasm32v1-none/release |
| 38 | + |
| 39 | +jobs: |
| 40 | + # ────────────────────────────────────────────────────── |
| 41 | + # Build WASM artifacts |
| 42 | + # ────────────────────────────────────────────────────── |
| 43 | + build: |
| 44 | + name: Build WASM |
| 45 | + runs-on: ubuntu-latest |
| 46 | + steps: |
| 47 | + - uses: actions/checkout@v4 |
| 48 | + |
| 49 | + - name: Install Rust toolchain |
| 50 | + uses: dtolnay/rust-toolchain@stable |
| 51 | + with: |
| 52 | + targets: wasm32-unknown-unknown |
| 53 | + |
| 54 | + - name: Cache cargo |
| 55 | + uses: actions/cache@v4 |
| 56 | + with: |
| 57 | + path: | |
| 58 | + ~/.cargo/registry |
| 59 | + ~/.cargo/git |
| 60 | + target |
| 61 | + key: ${{ runner.os }}-deploy-${{ hashFiles('**/Cargo.lock') }} |
| 62 | + |
| 63 | + - name: Install Stellar CLI |
| 64 | + run: cargo install --locked stellar-cli |
| 65 | + |
| 66 | + - name: Build all contracts |
| 67 | + run: stellar contract build |
| 68 | + |
| 69 | + - name: Verify WASM sizes |
| 70 | + run: | |
| 71 | + for wasm in $WASM_DIR/*.wasm; do |
| 72 | + NAME=$(basename "$wasm") |
| 73 | + SIZE=$(stat -c%s "$wasm" 2>/dev/null || stat -f%z "$wasm") |
| 74 | + if [ "$SIZE" -gt 65536 ]; then |
| 75 | + echo "FAIL: $NAME exceeds 64KB ($((SIZE/1024))KB)" |
| 76 | + exit 1 |
| 77 | + fi |
| 78 | + echo "OK: $NAME — $((SIZE/1024))KB" |
| 79 | + done |
| 80 | +
|
| 81 | + - name: Run all tests |
| 82 | + run: cargo test --workspace |
| 83 | + |
| 84 | + - name: Upload WASM artifacts |
| 85 | + uses: actions/upload-artifact@v4 |
| 86 | + with: |
| 87 | + name: wasm-contracts |
| 88 | + path: target/wasm32v1-none/release/*.wasm |
| 89 | + |
| 90 | + # ────────────────────────────────────────────────────── |
| 91 | + # Fresh deploy — all 8 contracts from scratch |
| 92 | + # ────────────────────────────────────────────────────── |
| 93 | + fresh-deploy: |
| 94 | + name: Fresh Deploy |
| 95 | + needs: build |
| 96 | + if: inputs.action == 'fresh-deploy' |
| 97 | + runs-on: ubuntu-latest |
| 98 | + environment: ${{ inputs.network }} |
| 99 | + steps: |
| 100 | + - uses: actions/checkout@v4 |
| 101 | + |
| 102 | + - name: Install Stellar CLI |
| 103 | + run: cargo install --locked stellar-cli |
| 104 | + |
| 105 | + - name: Download WASM artifacts |
| 106 | + uses: actions/download-artifact@v4 |
| 107 | + with: |
| 108 | + name: wasm-contracts |
| 109 | + path: ${{ env.WASM_DIR }} |
| 110 | + |
| 111 | + - name: Run deploy script |
| 112 | + env: |
| 113 | + ADMIN_SECRET: ${{ secrets.ADMIN_SECRET }} |
| 114 | + TREASURY_ADDRESS: ${{ secrets.TREASURY_ADDRESS }} |
| 115 | + run: | |
| 116 | + chmod +x scripts/deploy.sh |
| 117 | + ./scripts/deploy.sh ${{ inputs.network }} | tee deploy-output.txt |
| 118 | +
|
| 119 | + - name: Extract contract addresses |
| 120 | + id: addresses |
| 121 | + run: | |
| 122 | + extract() { grep "$1:" deploy-output.txt | awk '{print $NF}'; } |
| 123 | + echo "core_escrow=$(extract CoreEscrow)" >> "$GITHUB_OUTPUT" |
| 124 | + echo "reputation_registry=$(extract ReputationRegistry)" >> "$GITHUB_OUTPUT" |
| 125 | + echo "governance_voting=$(extract GovernanceVoting)" >> "$GITHUB_OUTPUT" |
| 126 | + echo "project_registry=$(extract ProjectRegistry)" >> "$GITHUB_OUTPUT" |
| 127 | + echo "bounty_registry=$(extract BountyRegistry)" >> "$GITHUB_OUTPUT" |
| 128 | + echo "crowdfund_registry=$(extract CrowdfundRegistry)" >> "$GITHUB_OUTPUT" |
| 129 | + echo "grant_hub=$(extract GrantHub)" >> "$GITHUB_OUTPUT" |
| 130 | + echo "hackathon_registry=$(extract HackathonRegistry)" >> "$GITHUB_OUTPUT" |
| 131 | +
|
| 132 | + - name: Save deployment manifest |
| 133 | + run: | |
| 134 | + cat > deployment-manifest.json <<EOF |
| 135 | + { |
| 136 | + "network": "${{ inputs.network }}", |
| 137 | + "deployed_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)", |
| 138 | + "commit": "${{ github.sha }}", |
| 139 | + "contracts": { |
| 140 | + "core_escrow": "${{ steps.addresses.outputs.core_escrow }}", |
| 141 | + "reputation_registry": "${{ steps.addresses.outputs.reputation_registry }}", |
| 142 | + "governance_voting": "${{ steps.addresses.outputs.governance_voting }}", |
| 143 | + "project_registry": "${{ steps.addresses.outputs.project_registry }}", |
| 144 | + "bounty_registry": "${{ steps.addresses.outputs.bounty_registry }}", |
| 145 | + "crowdfund_registry": "${{ steps.addresses.outputs.crowdfund_registry }}", |
| 146 | + "grant_hub": "${{ steps.addresses.outputs.grant_hub }}", |
| 147 | + "hackathon_registry": "${{ steps.addresses.outputs.hackathon_registry }}" |
| 148 | + } |
| 149 | + } |
| 150 | + EOF |
| 151 | + cat deployment-manifest.json |
| 152 | +
|
| 153 | + - name: Upload deployment manifest |
| 154 | + uses: actions/upload-artifact@v4 |
| 155 | + with: |
| 156 | + name: deployment-manifest-${{ inputs.network }} |
| 157 | + path: deployment-manifest.json |
| 158 | + retention-days: 90 |
| 159 | + |
| 160 | + # ────────────────────────────────────────────────────── |
| 161 | + # Upgrade all contracts |
| 162 | + # ────────────────────────────────────────────────────── |
| 163 | + upgrade-all: |
| 164 | + name: Upgrade All Contracts |
| 165 | + needs: build |
| 166 | + if: inputs.action == 'upgrade-all' |
| 167 | + runs-on: ubuntu-latest |
| 168 | + environment: ${{ inputs.network }} |
| 169 | + steps: |
| 170 | + - uses: actions/checkout@v4 |
| 171 | + |
| 172 | + - name: Install Stellar CLI |
| 173 | + run: cargo install --locked stellar-cli |
| 174 | + |
| 175 | + - name: Download WASM artifacts |
| 176 | + uses: actions/download-artifact@v4 |
| 177 | + with: |
| 178 | + name: wasm-contracts |
| 179 | + path: ${{ env.WASM_DIR }} |
| 180 | + |
| 181 | + - name: Run upgrade script |
| 182 | + env: |
| 183 | + ADMIN_SECRET: ${{ secrets.ADMIN_SECRET }} |
| 184 | + NETWORK: ${{ inputs.network }} |
| 185 | + # Contract addresses from GitHub environment variables |
| 186 | + CORE_ESCROW_ID: ${{ vars.CORE_ESCROW_ID }} |
| 187 | + REPUTATION_REGISTRY_ID: ${{ vars.REPUTATION_REGISTRY_ID }} |
| 188 | + GOVERNANCE_VOTING_ID: ${{ vars.GOVERNANCE_VOTING_ID }} |
| 189 | + PROJECT_REGISTRY_ID: ${{ vars.PROJECT_REGISTRY_ID }} |
| 190 | + BOUNTY_REGISTRY_ID: ${{ vars.BOUNTY_REGISTRY_ID }} |
| 191 | + CROWDFUND_REGISTRY_ID: ${{ vars.CROWDFUND_REGISTRY_ID }} |
| 192 | + GRANT_HUB_ID: ${{ vars.GRANT_HUB_ID }} |
| 193 | + HACKATHON_REGISTRY_ID: ${{ vars.HACKATHON_REGISTRY_ID }} |
| 194 | + run: | |
| 195 | + chmod +x scripts/upgrade.sh |
| 196 | + ./scripts/upgrade.sh all |
| 197 | +
|
| 198 | + # ────────────────────────────────────────────────────── |
| 199 | + # Upgrade a single contract |
| 200 | + # ────────────────────────────────────────────────────── |
| 201 | + upgrade-single: |
| 202 | + name: Upgrade ${{ inputs.contract }} |
| 203 | + needs: build |
| 204 | + if: inputs.action == 'upgrade-single' |
| 205 | + runs-on: ubuntu-latest |
| 206 | + environment: ${{ inputs.network }} |
| 207 | + steps: |
| 208 | + - uses: actions/checkout@v4 |
| 209 | + |
| 210 | + - name: Install Stellar CLI |
| 211 | + run: cargo install --locked stellar-cli |
| 212 | + |
| 213 | + - name: Download WASM artifacts |
| 214 | + uses: actions/download-artifact@v4 |
| 215 | + with: |
| 216 | + name: wasm-contracts |
| 217 | + path: ${{ env.WASM_DIR }} |
| 218 | + |
| 219 | + - name: Run upgrade script |
| 220 | + env: |
| 221 | + ADMIN_SECRET: ${{ secrets.ADMIN_SECRET }} |
| 222 | + NETWORK: ${{ inputs.network }} |
| 223 | + CORE_ESCROW_ID: ${{ vars.CORE_ESCROW_ID }} |
| 224 | + REPUTATION_REGISTRY_ID: ${{ vars.REPUTATION_REGISTRY_ID }} |
| 225 | + GOVERNANCE_VOTING_ID: ${{ vars.GOVERNANCE_VOTING_ID }} |
| 226 | + PROJECT_REGISTRY_ID: ${{ vars.PROJECT_REGISTRY_ID }} |
| 227 | + BOUNTY_REGISTRY_ID: ${{ vars.BOUNTY_REGISTRY_ID }} |
| 228 | + CROWDFUND_REGISTRY_ID: ${{ vars.CROWDFUND_REGISTRY_ID }} |
| 229 | + GRANT_HUB_ID: ${{ vars.GRANT_HUB_ID }} |
| 230 | + HACKATHON_REGISTRY_ID: ${{ vars.HACKATHON_REGISTRY_ID }} |
| 231 | + run: | |
| 232 | + chmod +x scripts/upgrade.sh |
| 233 | + ./scripts/upgrade.sh ${{ inputs.contract }} |
0 commit comments