-
Notifications
You must be signed in to change notification settings - Fork 45
255 lines (222 loc) · 9.71 KB
/
Copy pathdeploy.yml
File metadata and controls
255 lines (222 loc) · 9.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
name: Deploy
on:
push:
branches: [ main ]
workflow_dispatch:
inputs:
environment:
description: 'Deployment environment'
required: true
default: 'staging'
type: choice
options:
- staging
- production
# Prevent concurrent deploys to the same environment
concurrency:
group: deploy-${{ github.event.inputs.environment || 'staging' }}
cancel-in-progress: false
jobs:
deploy-contracts:
name: Deploy Smart Contracts
runs-on: ubuntu-latest
# Only run when the deployer secret is present (production/staging deployments)
if: vars.DEPLOY_CONTRACTS_ENABLED == 'true'
environment: ${{ github.event.inputs.environment || 'staging' }}
env:
STELLAR_CLI_VERSION: 23.4.0
outputs:
# Expose contract IDs to downstream jobs if needed
deployed: ${{ steps.deploy.outputs.deployed }}
steps:
- name: Checkout code
uses: actions/checkout@v4
# Pinned to 1.96.0: Rust 1.97 changed core::num::TryFromIntError's size,
# breaking the transitive ethnum 1.5.2 crate (E0512). Keep below 1.97 until
# soroban's dependency tree no longer pulls the broken ethnum.
- name: Install Rust
uses: dtolnay/rust-toolchain@1.96.0
with:
targets: wasm32-unknown-unknown
# Fixed: use the official Stellar CLI GitHub Action (replaces broken soroban curl install)
- name: Install Stellar CLI
shell: bash
run: |
set -euo pipefail
mkdir -p "$HOME/.local/bin"
arch="$(uname -m)"
case "$arch" in
x86_64) asset_arch="x86_64" ;;
aarch64|arm64) asset_arch="aarch64" ;;
*) echo "Unsupported architecture: $arch"; exit 1 ;;
esac
version="${STELLAR_CLI_VERSION}"
base_url="https://github.com/stellar/stellar-cli/releases/download/v${version}"
urls=(
"${base_url}/stellar-cli-${version}-${asset_arch}-unknown-linux-gnu.tar.gz"
"${base_url}/stellar-cli-${version}-${asset_arch}-unknown-linux-musl.tar.gz"
)
success="false"
for url in "${urls[@]}"; do
echo "Attempting download: ${url}"
if curl -fL --retry 6 --retry-all-errors --retry-delay 5 -o stellar-cli.tar.gz "${url}"; then
success="true"
break
fi
done
if [ "$success" != "true" ]; then
echo "Failed to download stellar-cli v${version} from GitHub releases."
exit 1
fi
tmpdir="$(mktemp -d)"
tar -xzf stellar-cli.tar.gz -C "$tmpdir"
stellar_path="$(find "$tmpdir" -type f -name stellar | head -n 1)"
if [ -z "$stellar_path" ]; then
echo "Could not find 'stellar' binary in downloaded archive."
exit 1
fi
mv "$stellar_path" "$HOME/.local/bin/stellar"
chmod +x "$HOME/.local/bin/stellar"
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
stellar --version
# Fixed: register the deployer key into the CLI key store.
# --secret-key flag was removed from deploy/invoke commands in modern stellar CLI.
# The correct approach is to add the key once via `stellar keys add` and then
# reference it by name with --source-account in subsequent commands.
- name: Register deployer identity
env:
STELLAR_SECRET_KEY: ${{ secrets.STELLAR_SECRET_KEY }}
run: |
echo "$STELLAR_SECRET_KEY" | stellar keys add deployer --secret-key
# Fixed: use stellar contract build instead of cargo build --target wasm32-unknown-unknown.
# This ensures correct metadata, optimizer flags, and proper wasm output paths.
- name: Build contracts
working-directory: ./smart-contract
run: stellar contract build
- name: Configure network
run: |
NETWORK=${{ github.event.inputs.environment || 'staging' }}
if [ "$NETWORK" = "production" ]; then
echo "STELLAR_NETWORK=mainnet" >> $GITHUB_ENV
echo "STELLAR_RPC_URL=https://soroban-rpc.mainnet.stellar.org" >> $GITHUB_ENV
echo "STELLAR_NETWORK_PASSPHRASE=Public Global Stellar Network ; September 2015" >> $GITHUB_ENV
else
echo "STELLAR_NETWORK=testnet" >> $GITHUB_ENV
echo "STELLAR_RPC_URL=https://soroban-testnet.stellar.org" >> $GITHUB_ENV
echo "STELLAR_NETWORK_PASSPHRASE=Test SDF Network ; September 2015" >> $GITHUB_ENV
fi
# Fixed: replaced --secret-key (removed flag) with --source-account referencing the
# registered identity. Also uses --alias per current CLI docs so contracts can be
# referenced by name in subsequent steps instead of tracking raw IDs in a text file.
- name: Deploy contracts
id: deploy
run: |
for wasm_file in smart-contract/target/wasm32-unknown-unknown/release/*.wasm; do
CONTRACT_NAME=$(basename "$wasm_file" .wasm)
echo "Deploying $CONTRACT_NAME..."
stellar contract deploy \
--wasm "$wasm_file" \
--source-account deployer \
--network "$STELLAR_NETWORK" \
--rpc-url "$STELLAR_RPC_URL" \
--network-passphrase "$STELLAR_NETWORK_PASSPHRASE" \
--alias "$CONTRACT_NAME" \
--ignore-checks
echo "Deployed $CONTRACT_NAME"
done
echo "deployed=true" >> $GITHUB_OUTPUT
- name: Initialize contracts
run: |
# Add per-contract initialization calls here, e.g.:
# stellar contract invoke \
# --id <contract-alias> \
# --source-account deployer \
# --network "$STELLAR_NETWORK" \
# -- initialize --admin deployer
echo "Add initialization logic here"
- name: Health check
run: |
# Add contract health check invocations here, e.g.:
# stellar contract invoke --id <alias> --network "$STELLAR_NETWORK" -- get_status
echo "Add health check logic here"
deploy-frontend:
name: Deploy Frontend
runs-on: ubuntu-latest
environment: ${{ github.event.inputs.environment || 'staging' }}
needs: deploy-contracts
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
- name: Install dependencies
working-directory: ./frontend
run: npm ci
- name: Write environment config
working-directory: ./frontend
run: |
NETWORK=${{ github.event.inputs.environment || 'staging' }}
if [ "$NETWORK" = "production" ]; then
echo "NEXT_PUBLIC_CONTRACT_ID=${{ secrets.PRODUCTION_CONTRACT_ID }}" >> .env.local
echo "NEXT_PUBLIC_STELLAR_NETWORK=mainnet" >> .env.local
echo "NEXT_PUBLIC_RPC_URL=https://soroban-rpc.mainnet.stellar.org" >> .env.local
else
echo "NEXT_PUBLIC_CONTRACT_ID=${{ secrets.STAGING_CONTRACT_ID }}" >> .env.local
echo "NEXT_PUBLIC_STELLAR_NETWORK=testnet" >> .env.local
echo "NEXT_PUBLIC_RPC_URL=https://soroban-testnet.stellar.org" >> .env.local
fi
- name: Build frontend
working-directory: ./frontend
run: npm run build
# Fixed: `if: env.VERCEL_TOKEN != ''` silently never evaluates true in GitHub Actions
# because env context is not available in `if:` conditions.
# Use vars (non-secret config) to gate the Vercel deploy instead.
- name: Deploy to Vercel
if: vars.USE_VERCEL == 'true'
working-directory: ./frontend
run: |
npm install -g vercel
vercel --prod --yes --token ${{ secrets.VERCEL_TOKEN }}
# Fixed: upgraded from stale peaceiris/actions-gh-pages@v3 to @v4
- name: Deploy to GitHub Pages (fallback)
if: vars.USE_VERCEL != 'true'
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./frontend/.next
cname: ${{ (github.event.inputs.environment == 'production') && 'chainlogistics.app' || 'staging.chainlogistics.app' }}
notify:
name: Notify Deployment Status
runs-on: ubuntu-latest
needs: [ deploy-contracts, deploy-frontend ]
if: always()
steps:
- name: Notify success
if: needs.deploy-contracts.result == 'success' && needs.deploy-frontend.result == 'success'
run: |
echo "Deployment successful!"
# Add Slack/email notification here
- name: Notify failure
if: needs.deploy-contracts.result == 'failure' || needs.deploy-frontend.result == 'failure'
run: |
echo "Deployment failed!"
# Add Slack/email notification here
# NOTE: True contract rollback on Stellar/Soroban is not possible by reverting a deploy —
# deployed contracts are immutable on-chain. A real rollback strategy requires either:
# 1. Redeploying the previous WASM and updating any router/proxy contract to point to it, or
# 2. Maintaining a feature-flag or upgrade mechanism inside the contract itself.
# The stub below is preserved as a placeholder for frontend-only rollback (e.g. Vercel promote).
rollback:
name: Rollback Frontend on Failure
runs-on: ubuntu-latest
needs: [ deploy-contracts, deploy-frontend ]
if: failure() && github.event_name == 'push' && vars.USE_VERCEL == 'true'
steps:
- name: Rollback Vercel deployment
run: |
echo "Promote the previous Vercel deployment via the Vercel API or CLI here."
# vercel rollback --token ${{ secrets.VERCEL_TOKEN }}