Skip to content

Merge pull request #1178 from yosemite01/snyk-fix-559836ce68e4fdcb4b1… #263

Merge pull request #1178 from yosemite01/snyk-fix-559836ce68e4fdcb4b1…

Merge pull request #1178 from yosemite01/snyk-fix-559836ce68e4fdcb4b1… #263

name: Deploy to Mainnet

Check failure on line 1 in .github/workflows/deploy-mainnet.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/deploy-mainnet.yml

Invalid workflow file

(Line: 149, Col: 13): Unrecognized named-value: 'secrets'. Located at position 1 within expression: secrets.SLACK_WEBHOOK_URL != '', (Line: 152, Col: 14): Unexpected symbol: '"'success'"'"''. Located at position 37 within expression: needs.deploy-contracts.result == '"'"'success'"'"' && needs.deploy-frontend.result == '"'"'success'"'"' && '"'"'good'"'"' || '"'"'danger'"'"'
on:
release:
types: [published]
env:
STELLAR_NETWORK: mainnet
MAINNET_RPC_URL: https://soroban-mainnet.stellar.org
MAINNET_PASSPHRASE: "Public Global Stellar Network ; September 2015"
jobs:
validate-release:
name: Validate Release Tag
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Enforce semver release tag
run: |
TAG="${GITHUB_REF_NAME}"
if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "❌ Release tag '$TAG' is not a valid semver (e.g. v1.2.3). Aborting."
exit 1
fi
echo "✅ Release tag: $TAG"
simulate-contracts:
name: Simulate Contracts Against Mainnet RPC
runs-on: ubuntu-latest
needs: validate-release
steps:
- uses: actions/checkout@v6
- name: Build reproducible contracts & verify hashes
run: ./scripts/verify.sh
- name: Install Stellar CLI
run: |
cargo install --locked stellar-cli --features opt 2>/dev/null || \
cargo install stellar-cli --features opt
- name: Build contracts
run: cd backend && cargo build --release --target wasm32-unknown-unknown \
--package stellar-bounty-contract \
--package stellar-escrow-contract \
--package stellar-freelancer-contract \
--package stellar-governance-contract \
--package oracle \
--package stellar-identity-contract
- name: Run contract unit tests
run: cd backend && cargo test --all-features
- name: Simulate contracts against Mainnet RPC
env:
STELLAR_RPC_URL: ${{ env.MAINNET_RPC_URL }}
run: node scripts/deploy.js --simulate-only
# Exits non-zero if any simulation fails, blocking the deploy.
deploy-contracts:
name: Deploy Soroban Contracts to Mainnet
runs-on: ubuntu-latest
needs: simulate-contracts
environment: mainnet # Requires manual approval in GitHub Environments
outputs:
bounty_contract_id: ${{ steps.deploy.outputs.bounty_contract_id }}
escrow_contract_id: ${{ steps.deploy.outputs.escrow_contract_id }}
freelancer_contract_id: ${{ steps.deploy.outputs.freelancer_contract_id }}
governance_contract_id: ${{ steps.deploy.outputs.governance_contract_id }}
oracle_contract_id: ${{ steps.deploy.outputs.oracle_contract_id }}
identity_contract_id: ${{ steps.deploy.outputs.identity_contract_id }}
steps:
- uses: actions/checkout@v6
- name: Build reproducible contracts & verify hashes
run: ./scripts/verify.sh
- name: Install Stellar CLI
run: cargo install --locked stellar-cli --features opt 2>/dev/null || cargo install stellar-cli --features opt
- name: Deploy contracts
id: deploy
env:
STELLAR_NETWORK: ${{ env.STELLAR_NETWORK }}
STELLAR_RPC_URL: ${{ env.MAINNET_RPC_URL }}
STELLAR_NETWORK_PASSPHRASE: ${{ env.MAINNET_PASSPHRASE }}
STELLAR_ADMIN_SECRET: ${{ secrets.MAINNET_DEPLOYER_SECRET }}
WASM_DIR: artifacts
run: node scripts/deploy.js
deploy-frontend:
name: Deploy Frontend to Production
runs-on: ubuntu-latest
needs: deploy-contracts
environment: mainnet
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6
with:
version: 8
- uses: actions/setup-node@v6
with:
node-version: '20'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Build frontend
env:
NEXT_PUBLIC_STELLAR_NETWORK: mainnet
NEXT_PUBLIC_MAINNET_RPC_URL: ${{ env.MAINNET_RPC_URL }}
NEXT_PUBLIC_MAINNET_PASSPHRASE: ${{ env.MAINNET_PASSPHRASE }}
NEXT_PUBLIC_BOUNTY_CONTRACT_ID: ${{ needs.deploy-contracts.outputs.bounty_contract_id }}
NEXT_PUBLIC_ESCROW_CONTRACT_ID: ${{ needs.deploy-contracts.outputs.escrow_contract_id }}
NEXT_PUBLIC_FREELANCER_CONTRACT_ID: ${{ needs.deploy-contracts.outputs.freelancer_contract_id }}
NEXT_PUBLIC_GOVERNANCE_CONTRACT_ID: ${{ needs.deploy-contracts.outputs.governance_contract_id }}
NEXT_PUBLIC_ORACLE_CONTRACT_ID: ${{ needs.deploy-contracts.outputs.oracle_contract_id }}
NEXT_PUBLIC_IDENTITY_CONTRACT_ID: ${{ needs.deploy-contracts.outputs.identity_contract_id }}
run: pnpm build
- name: Deploy to Vercel (production)
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
run: npx vercel --prod --token "$VERCEL_TOKEN"
notify:
name: Broadcast Deployment
runs-on: ubuntu-latest
needs: [deploy-contracts, deploy-frontend]
if: always()
steps:
- name: Build notification payload
id: payload
run: |
STATUS="✅ Success"
if [[ "${{ needs.deploy-contracts.result }}" != "success" || "${{ needs.deploy-frontend.result }}" != "success" ]]; then
STATUS="❌ Failed"
fi
echo "status=$STATUS" >> "$GITHUB_OUTPUT"
echo "tag=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
- name: Post to Slack
if: ${{ secrets.SLACK_WEBHOOK_URL != '' }}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
run: |
curl -fsSL -X POST "$SLACK_WEBHOOK_URL" \
-H 'Content-Type: application/json' \
-d '{
"text": "${{ steps.payload.outputs.status }} *Stellar Mainnet Deploy* — `${{ steps.payload.outputs.tag }}`",
"attachments": [{
"color": "${{ needs.deploy-contracts.result == '"'"'success'"'"' && needs.deploy-frontend.result == '"'"'success'"'"' && '"'"'good'"'"' || '"'"'danger'"'"' }}",
"fields": [
{"title": "Bounty Contract", "value": "`${{ needs.deploy-contracts.outputs.bounty_contract_id }}`", "short": true},
{"title": "Escrow Contract", "value": "`${{ needs.deploy-contracts.outputs.escrow_contract_id }}`", "short": true},
{"title": "Freelancer Contract", "value": "`${{ needs.deploy-contracts.outputs.freelancer_contract_id }}`", "short": true},
{"title": "Governance Contract", "value": "`${{ needs.deploy-contracts.outputs.governance_contract_id }}`", "short": true},
{"title": "Oracle Contract", "value": "`${{ needs.deploy-contracts.outputs.oracle_contract_id }}`", "short": true},
{"title": "Identity Contract", "value": "`${{ needs.deploy-contracts.outputs.identity_contract_id }}`", "short": true},
{"title": "Run", "value": "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View logs>", "short": false}
]
}]
}'
- name: Create GitHub deployment summary
run: |
cat >> "$GITHUB_STEP_SUMMARY" << EOF
## ${{ steps.payload.outputs.status }} Mainnet Deployment — \`${{ steps.payload.outputs.tag }}\`
| Contract | ID |
|---|---|
| Bounty | \`${{ needs.deploy-contracts.outputs.bounty_contract_id }}\` |
| Escrow | \`${{ needs.deploy-contracts.outputs.escrow_contract_id }}\` |
| Freelancer | \`${{ needs.deploy-contracts.outputs.freelancer_contract_id }}\` |
| Governance | \`${{ needs.deploy-contracts.outputs.governance_contract_id }}\` |
| Oracle | \`${{ needs.deploy-contracts.outputs.oracle_contract_id }}\` |
| Identity | \`${{ needs.deploy-contracts.outputs.identity_contract_id }}\` |
[View full run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
EOF