Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions .github/workflows/contract-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Contract Deploy & Auto-Regenerate Bindings

on:
push:
branches:
- main
paths:
- 'contracts/**'
- 'scripts/deploy.sh'
- 'scripts/generate-contract-bindings.sh'
workflow_dispatch:

jobs:
deploy-and-regenerate:
name: Deploy Contract, Auto-Regenerate Bindings & Verify TS
runs-on: ubuntu-latest

permissions:
contents: write
pull-requests: write

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown

- name: Install Soroban CLI
run: |
cargo install --locked soroban-cli --version 21.0.0

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
Comment thread
Kingsley4867 marked this conversation as resolved.

- name: Create Test Account / Prepare Secret
run: |
if [ -z "${{ secrets.SECRET_KEY }}" ]; then
echo "SECRET_KEY secret not set, generating temporary deployer account..."
DEPLOYER_SECRET=$(soroban keys generate deployer --network testnet --format secret)
DEPLOYER_PUBLIC=$(soroban keys address deployer)
echo "SECRET_KEY=$DEPLOYER_SECRET" >> $GITHUB_ENV
echo "DEPLOYER_PUBLIC=$DEPLOYER_PUBLIC" >> $GITHUB_ENV
curl -s -X GET "https://friendbot.stellar.org?addr=$DEPLOYER_PUBLIC" > /dev/null
else
echo "Using SECRET_KEY from secrets"
echo "SECRET_KEY=${{ secrets.SECRET_KEY }}" >> $GITHUB_ENV
fi

- name: Build and Deploy Contract to Testnet
run: |
chmod +x scripts/deploy.sh
./scripts/deploy.sh
CONTRACT_ID=$(cat contracts/contract_id.txt)
echo "CONTRACT_ID=$CONTRACT_ID" >> $GITHUB_ENV
echo "Contract deployed successfully with ID: $CONTRACT_ID"

- name: Auto-Regenerate Contract Bindings
run: |
chmod +x scripts/generate-contract-bindings.sh
npm run gen:bindings

- name: Validate Frontend TypeScript Compilation
working-directory: frontend
run: |
npx tsc --noEmit

- name: Create Pull Request with Updated Bindings
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
Comment thread
Kingsley4867 marked this conversation as resolved.
commit-message: "chore(contracts): auto-regenerate contract bindings after testnet deploy"
title: "chore(contracts): update contract bindings after deploy"
body: |
Automated PR created after testnet contract deployment.

- Deployed Contract ID: `${{ env.CONTRACT_ID }}`
- TypeScript bindings generated via `npm run gen:bindings`
- Frontend TypeScript check (`tsc --noEmit`) verified clean compilation
branch: auto-update-contract-bindings
delete-branch: true
34 changes: 34 additions & 0 deletions .github/workflows/contract-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ jobs:
smoke-test:
name: Deploy and Smoke Test
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write

steps:
- name: Checkout code
Expand Down Expand Up @@ -50,6 +53,37 @@ jobs:
echo "CONTRACT_ID=$CONTRACT_ID" >> $GITHUB_ENV
echo "Contract deployed with ID: $CONTRACT_ID"

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'

- name: Auto-Regenerate Contract Bindings
run: |
chmod +x scripts/generate-contract-bindings.sh
npm run gen:bindings

- name: Validate Frontend TypeScript Compilation
working-directory: frontend
run: |
npx tsc --noEmit

- name: Create Pull Request with Updated Bindings
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "chore(contracts): auto-regenerate contract bindings after testnet deploy"
title: "chore(contracts): update contract bindings after smoke test deploy"
body: |
Automated PR created after testnet contract deployment in smoke test.

- Deployed Contract ID: `${{ env.CONTRACT_ID }}`
- TypeScript bindings auto-generated via `npm run gen:bindings`
- Frontend TypeScript check (`tsc --noEmit`) verified clean compilation
branch: auto-update-contract-bindings
delete-branch: true

- name: Initialize Contract
run: |
# Call initialize(admin: Address)
Expand Down
32 changes: 25 additions & 7 deletions docs/CONTRACT_BINDINGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,17 +316,35 @@ public method:

## CI / automated regeneration

To regenerate bindings in a CI pipeline, add a step after deployment:
Automated contract binding regeneration runs in CI after testnet contract deployment (`.github/workflows/contract-deploy.yml` and `.github/workflows/contract-smoke.yml`).

Workflow steps after contract deployment:

1. **Auto-generate contract bindings:**
Runs `npm run gen:bindings` using the deployed `CONTRACT_ID` (either from environment variable or automatically read from `contracts/contract_id.txt`).

2. **Frontend TypeScript compilation check:**
Validates that the generated TypeScript bindings compile cleanly without errors using `npx tsc --noEmit` in `frontend/`.

3. **Automated Pull Request creation:**
If generated bindings differ from repository state, CI automatically creates a pull request (branch: `auto-update-contract-bindings`) containing the updated bindings.

```yaml
- name: Generate contract bindings
env:
CONTRACT_ID: ${{ steps.deploy.outputs.contract_id }}
- name: Auto-Regenerate Contract Bindings
run: npm run gen:bindings
```

The generated files do not need to be committed they can be regenerated from
the deployed contract ID on every CI run.
- name: Validate Frontend TypeScript Compilation
working-directory: frontend
run: npx tsc --noEmit

- name: Create PR with Updated Bindings
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "chore(contracts): auto-regenerate contract bindings after testnet deploy"
title: "chore(contracts): update contract bindings after deploy"
branch: auto-update-contract-bindings
```

---

Expand Down
19 changes: 19 additions & 0 deletions scripts/generate-contract-bindings.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ NETWORK_PASSPHRASE="${NETWORK_PASSPHRASE:-Test SDF Network ; September 2015}"
RPC_URL="${RPC_URL:-https://soroban-testnet.stellar.org:443}"

# ── Checks ────────────────────────────────────────────────────────────────
if [ -z "$CONTRACT_ID" ] && [ -f "contracts/contract_id.txt" ]; then
CONTRACT_ID=$(cat contracts/contract_id.txt)
echo -e "${YELLOW}Notice: CONTRACT_ID not set directly, read from contracts/contract_id.txt ($CONTRACT_ID)${NC}"
fi

if [ -z "$CONTRACT_ID" ]; then
echo -e "${RED}Error: CONTRACT_ID environment variable is required${NC}"
echo ""
Expand Down Expand Up @@ -75,6 +80,20 @@ echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}Bindings generated successfully!${NC}"
echo -e "${GREEN}========================================${NC}"
echo ""

if [ "$SKIP_TS_CHECK" != "true" ] && [ -d "frontend" ] && [ -f "frontend/tsconfig.json" ]; then
echo -e "${YELLOW}Validating frontend TypeScript compilation...${NC}"
if command -v npx &> /dev/null; then
(cd frontend && npx tsc --noEmit)
if [ $? -eq 0 ]; then
echo -e "${GREEN}Frontend TypeScript verification passed!${NC}"
else
echo -e "${RED}Frontend TypeScript verification failed!${NC}"
exit 1
fi
fi
fi
Comment thread
Kingsley4867 marked this conversation as resolved.

echo -e "Output location: ${YELLOW}$OUTPUT_DIR/${NC}"
echo ""
echo -e "${GREEN}Next steps:${NC}"
Expand Down