build(deps): bump soroban-sdk from 22.0.9 to 22.0.11 in /contracts in the contracts-minor-patch group across 1 directory #1389
Workflow file for this run
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: RemitLend CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| jobs: | |
| supply-chain-audit: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Block compromised packages | |
| run: | | |
| echo "Scanning lockfiles for known malicious packages..." | |
| BLOCKED="plain-crypto-js" | |
| for lockfile in backend/package-lock.json frontend/package-lock.json scripts/package-lock.json; do | |
| if [ -f "$lockfile" ] && grep -q "$BLOCKED" "$lockfile"; then | |
| echo "::error::SUPPLY CHAIN ALERT: $lockfile contains $BLOCKED (confirmed malware)" | |
| exit 1 | |
| fi | |
| done | |
| if grep -r '"axios": "1\.14\.' --include="package-lock.json" .; then | |
| echo "::error::SUPPLY CHAIN ALERT: axios 1.14.x detected (compromised version)" | |
| exit 1 | |
| fi | |
| echo "No known malicious packages found." | |
| backend: | |
| needs: supply-chain-audit | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Use Node.js 20 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: "npm" | |
| cache-dependency-path: backend/package-lock.json | |
| - name: Install dependencies | |
| run: npm ci | |
| working-directory: backend | |
| - name: Lint | |
| run: npm run lint | |
| working-directory: backend | |
| - name: Build | |
| run: npm run build | |
| working-directory: backend | |
| - name: Type check | |
| run: npm run typecheck | |
| working-directory: backend | |
| - name: Run tests | |
| run: npm test | |
| working-directory: backend | |
| env: | |
| NODE_ENV: test | |
| DATABASE_URL: postgres://user:pass@localhost:5432/test | |
| REDIS_URL: redis://localhost:6379 | |
| JWT_SECRET: test_jwt_secret | |
| STELLAR_RPC_URL: https://rpc.test.invalid | |
| STELLAR_NETWORK_PASSPHRASE: Test SDF Network ; September 2015 | |
| LOAN_MANAGER_CONTRACT_ID: CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | |
| LENDING_POOL_CONTRACT_ID: CBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB | |
| REMITTANCE_NFT_CONTRACT_ID: CDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD | |
| MULTISIG_GOVERNANCE_CONTRACT_ID: CEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE | |
| POOL_TOKEN_ADDRESS: CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC | |
| LOAN_MANAGER_ADMIN_SECRET: test_admin_secret | |
| INTERNAL_API_KEY: test_internal_api_key | |
| FRONTEND_URL: https://frontend.example.com | |
| migration-paths: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| migrations: ${{ steps.filter.outputs.migrations }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dorny/paths-filter@v3 | |
| id: filter | |
| with: | |
| filters: | | |
| migrations: | |
| - 'backend/migrations/**' | |
| - 'backend/package.json' | |
| migration-check: | |
| needs: [supply-chain-audit, migration-paths] | |
| if: github.event_name == 'push' || needs.migration-paths.outputs.migrations == 'true' | |
| runs-on: ubuntu-latest | |
| services: | |
| postgres: | |
| image: postgres:16 | |
| env: | |
| POSTGRES_USER: pguser | |
| POSTGRES_PASSWORD: pgpass | |
| POSTGRES_DB: remitlend_test | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd "pg_isready -U pguser" | |
| --health-interval 5s | |
| --health-timeout 5s | |
| --health-retries 10 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Use Node.js 20 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: "npm" | |
| cache-dependency-path: backend/package-lock.json | |
| - name: Install dependencies | |
| run: npm ci | |
| working-directory: backend | |
| - name: Migrate up from empty schema | |
| run: npm run migrate:up | |
| working-directory: backend | |
| env: | |
| DATABASE_URL: postgres://pguser:pgpass@localhost:5432/remitlend_test | |
| - name: Migrate all the way down (reversibility check) | |
| run: | | |
| # Count migrations and roll them all back one by one | |
| MIGRATION_COUNT=$(ls migrations/*.js 2>/dev/null | wc -l) | |
| for i in $(seq 1 "$MIGRATION_COUNT"); do | |
| npm run migrate:down -- --count 1 | |
| done | |
| working-directory: backend | |
| env: | |
| DATABASE_URL: postgres://pguser:pgpass@localhost:5432/remitlend_test | |
| - name: Migrate up again (ordering + idempotency check) | |
| run: npm run migrate:up | |
| working-directory: backend | |
| env: | |
| DATABASE_URL: postgres://pguser:pgpass@localhost:5432/remitlend_test | |
| frontend: | |
| needs: supply-chain-audit | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Use Node.js 20 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: "npm" | |
| cache-dependency-path: frontend/package-lock.json | |
| - name: Install dependencies | |
| run: npm ci | |
| working-directory: frontend | |
| - name: Lint | |
| run: npm run lint | |
| working-directory: frontend | |
| - name: Type check | |
| run: npm run typecheck | |
| working-directory: frontend | |
| - name: Unit tests | |
| run: npm test | |
| working-directory: frontend | |
| env: | |
| NODE_ENV: test | |
| - name: Build | |
| run: npm run build | |
| working-directory: frontend | |
| scripts-typecheck: | |
| needs: supply-chain-audit | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Use Node.js 20 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: npm | |
| cache-dependency-path: scripts/package-lock.json | |
| - name: Install dependencies | |
| run: npm ci | |
| working-directory: scripts | |
| - name: Type check deploy scripts | |
| run: npm run typecheck | |
| working-directory: scripts | |
| e2e: | |
| needs: [supply-chain-audit, frontend] | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'push' || contains(github.event.pull_request.changed_files, 'frontend/') | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Use Node.js 20 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| cache: "npm" | |
| cache-dependency-path: frontend/package-lock.json | |
| - name: Install dependencies | |
| run: npm ci | |
| working-directory: frontend | |
| - name: Install Playwright browsers | |
| run: npx playwright install --with-deps chromium | |
| working-directory: frontend | |
| - name: Run e2e tests | |
| run: npx playwright test --project=chromium | |
| working-directory: frontend | |
| env: | |
| NODE_ENV: test | |
| CI: true | |
| - name: Upload Playwright report | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: playwright-report | |
| path: frontend/playwright-report/ | |
| retention-days: 7 | |
| env-docs-check: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Use Node.js 20 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| - name: Check env docs are in sync | |
| run: node scripts/check-env-docs.mjs | |
| contracts: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| workspaces: | | |
| contracts | |
| contracts/fuzz | |
| - name: Format check | |
| run: cargo fmt --all -- --check | |
| working-directory: contracts | |
| - name: Clippy | |
| run: cargo clippy --all-targets --all-features -- -D warnings | |
| working-directory: contracts | |
| - name: Run tests | |
| run: cargo test -- --test-threads=1 | |
| working-directory: contracts | |
| - name: Build contracts for wasm32 and enforce size budget | |
| run: | | |
| set -euo pipefail | |
| cargo build --target wasm32-unknown-unknown --release | |
| # Generous initial budget: 256 KiB per contract. Tighten after baseline optimization. | |
| max_bytes=$((256 * 1024)) | |
| shopt -s nullglob | |
| wasm_files=(target/wasm32-unknown-unknown/release/*.wasm) | |
| if [ "${#wasm_files[@]}" -eq 0 ]; then | |
| echo "::error::No wasm artifacts were produced." | |
| exit 1 | |
| fi | |
| for wasm in "${wasm_files[@]}"; do | |
| size_bytes=$(stat -c%s "$wasm") | |
| size_kib=$(( (size_bytes + 1023) / 1024 )) | |
| echo "$(basename "$wasm"): ${size_bytes} bytes (${size_kib} KiB), budget ${max_bytes} bytes" | |
| if [ "$size_bytes" -gt "$max_bytes" ]; then | |
| echo "::error file=$wasm::WASM artifact exceeds the 256 KiB per-contract budget." | |
| exit 1 | |
| fi | |
| done | |
| working-directory: contracts | |
| - name: Upload wasm artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: contracts-wasm | |
| path: contracts/target/wasm32-unknown-unknown/release/*.wasm | |
| if-no-files-found: error | |
| - name: Install tarpaulin | |
| uses: taiki-e/install-action@v2 | |
| with: | |
| tool: cargo-tarpaulin | |
| - name: Run coverage | |
| run: cargo tarpaulin --out Xml | |
| working-directory: contracts | |
| - name: Upload coverage report | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: contracts-coverage | |
| path: contracts/cobertura.xml | |
| retention-days: 7 | |
| - name: Check fuzz targets compile | |
| run: cargo check | |
| working-directory: contracts/fuzz |