Skip to content

Commit bfe7569

Browse files
committed
feat: Set up CI/CD pipelines, add an environment example, and update the deployment script for governance voting.
1 parent 7301258 commit bfe7569

28 files changed

Lines changed: 536 additions & 42 deletions

File tree

.env.example

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# ── Deployment Secrets ──────────────────────────────────
2+
# Admin keypair secret key (deployer account)
3+
ADMIN_SECRET=S...
4+
5+
# Treasury public address (receives platform fees)
6+
TREASURY_ADDRESS=G...
7+
8+
# Target network
9+
NETWORK=testnet
10+
11+
# ── Contract Addresses (set after fresh deploy) ────────
12+
# Used by upgrade.sh and the frontend
13+
CORE_ESCROW_ID=
14+
REPUTATION_REGISTRY_ID=
15+
GOVERNANCE_VOTING_ID=
16+
PROJECT_REGISTRY_ID=
17+
BOUNTY_REGISTRY_ID=
18+
CROWDFUND_REGISTRY_ID=
19+
GRANT_HUB_ID=
20+
HACKATHON_REGISTRY_ID=

.github/workflows/ci.yml

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main, develop]
6+
pull_request:
7+
branches: [main, develop]
8+
9+
env:
10+
CARGO_TERM_COLOR: always
11+
RUST_BACKTRACE: 1
12+
13+
jobs:
14+
check:
15+
name: Check & Test
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Install Rust toolchain
21+
uses: dtolnay/rust-toolchain@stable
22+
with:
23+
targets: wasm32-unknown-unknown
24+
25+
- name: Cache cargo registry & build
26+
uses: actions/cache@v4
27+
with:
28+
path: |
29+
~/.cargo/registry
30+
~/.cargo/git
31+
target
32+
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
33+
restore-keys: ${{ runner.os }}-cargo-
34+
35+
- name: Install Stellar CLI
36+
run: cargo install --locked stellar-cli
37+
38+
- name: Check formatting
39+
run: cargo fmt --all -- --check
40+
41+
- name: Clippy lints
42+
run: cargo clippy --all-targets -- -D warnings
43+
44+
- name: Run unit tests
45+
run: cargo test --workspace --exclude integration-tests
46+
47+
- name: Run integration tests
48+
run: cargo test -p integration-tests
49+
50+
build-wasm:
51+
name: Build WASM & Verify Size
52+
runs-on: ubuntu-latest
53+
steps:
54+
- uses: actions/checkout@v4
55+
56+
- name: Install Rust toolchain
57+
uses: dtolnay/rust-toolchain@stable
58+
with:
59+
targets: wasm32-unknown-unknown
60+
61+
- name: Cache cargo registry & build
62+
uses: actions/cache@v4
63+
with:
64+
path: |
65+
~/.cargo/registry
66+
~/.cargo/git
67+
target
68+
key: ${{ runner.os }}-wasm-${{ hashFiles('**/Cargo.lock') }}
69+
restore-keys: ${{ runner.os }}-wasm-
70+
71+
- name: Install Stellar CLI
72+
run: cargo install --locked stellar-cli
73+
74+
- name: Build all contracts
75+
run: stellar contract build
76+
77+
- name: Verify WASM sizes (< 64KB)
78+
run: |
79+
WASM_DIR="target/wasm32v1-none/release"
80+
FAILED=0
81+
for wasm in "$WASM_DIR"/*.wasm; do
82+
NAME=$(basename "$wasm")
83+
SIZE=$(stat -c%s "$wasm" 2>/dev/null || stat -f%z "$wasm")
84+
SIZE_KB=$((SIZE / 1024))
85+
if [ "$SIZE" -gt 65536 ]; then
86+
echo "FAIL: $NAME is ${SIZE_KB}KB (limit: 64KB)"
87+
FAILED=1
88+
else
89+
echo "OK: $NAME — ${SIZE_KB}KB"
90+
fi
91+
done
92+
if [ "$FAILED" -eq 1 ]; then exit 1; fi
93+
94+
- name: Upload WASM artifacts
95+
uses: actions/upload-artifact@v4
96+
with:
97+
name: wasm-contracts
98+
path: target/wasm32v1-none/release/*.wasm
99+
retention-days: 30

.github/workflows/deploy.yml

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
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 }}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ target
1717
# Environment
1818
.env
1919
.env.*
20+
!.env.example
2021

2122
# Logs
2223
*.log

contracts/bounty_registry/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![no_std]
2+
#![allow(clippy::too_many_arguments)]
23

34
pub mod contract;
45
pub mod error;

contracts/bounty_registry/src/tests/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![cfg(test)]
2-
31
use crate::contract::{BountyRegistry, BountyRegistryClient};
42
use crate::storage::{BountyStatus, BountyType};
53
use boundless_types::ActivityCategory;

0 commit comments

Comments
 (0)