Merge pull request #1178 from yosemite01/snyk-fix-559836ce68e4fdcb4b1… #263
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Deploy to Mainnet | ||
|
Check failure on line 1 in .github/workflows/deploy-mainnet.yml
|
||
| 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 | ||