Skip to content

ci(actions): bump actions/upload-artifact from 4 to 7 #356

ci(actions): bump actions/upload-artifact from 4 to 7

ci(actions): bump actions/upload-artifact from 4 to 7 #356

Workflow file for this run

name: CI/CD Pipeline
on:
push:
branches: [main, dev, develop, 'feature/*']
pull_request:
branches: [main, dev, develop, 'feature/*']
env:
NODE_VERSION: '20'
RUST_VERSION: '1.85'
jobs:
commitlint:
name: Conventional Commit Check
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Cache node modules
uses: actions/cache@v4
id: cache-node-modules
with:
path: node_modules
key: ${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}
- name: Install dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: npm ci --legacy-peer-deps
- name: Validate PR commits
run: npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.sha }} --verbose
# ─────────────────────────────────────────────────────────
# TypeScript / React Native Checks
# ─────────────────────────────────────────────────────────
typescript-lint:
name: TypeScript Lint & Format
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Cache node modules
uses: actions/cache@v4
id: cache-node-modules
with:
path: node_modules
key: ${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}
- name: Install dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: npm ci --legacy-peer-deps
- name: Check formatting (Prettier)
run: npm run format:check
- name: Run ESLint
run: npm run lint
npm-audit:
name: NPM Audit (High/Critical)
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci --legacy-peer-deps
- name: Run NPM Audit
run: npx audit-ci --config audit-ci.json
typescript-typecheck:
name: TypeScript Type Check
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Cache node modules
uses: actions/cache@v4
id: cache-node-modules
with:
path: node_modules
key: ${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}
- name: Install dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: npm ci --legacy-peer-deps
- name: EVM ABI TypeChain (must match committed output)
run: npm run contracts:codegen:check
- name: Run TypeScript type check
run: npx tsc --noEmit
typescript-tests:
name: TypeScript Tests (Sharded)
runs-on: ubuntu-latest
strategy:
matrix:
shard: [1, 2, 3]
env:
SHARD: ${{ matrix.shard }}
SHARD_COUNT: 3
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Cache node modules
uses: actions/cache@v4
id: cache-node-modules
with:
path: node_modules
key: ${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}
- name: Install dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: npm ci --legacy-peer-deps
- name: Run sharded tests with coverage
run: |
echo "Running shard $SHARD of $SHARD_COUNT"
npm run test:shard
- name: Upload coverage report
uses: actions/upload-artifact@v7
with:
name: coverage-report-${{ matrix.shard }}
path: coverage/lcov.info
typescript-build:
name: TypeScript Build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Cache node modules
uses: actions/cache@v4
id: cache-node-modules
with:
path: node_modules
key: ${{ runner.os }}-node-${{ env.NODE_VERSION }}-${{ hashFiles('package-lock.json') }}
- name: Cache Expo build cache
uses: actions/cache@v4
with:
path: |
.expo
node_modules/.cache/expo
key: ${{ runner.os }}-expo-${{ hashFiles('package.json', 'app.json') }}
restore-keys: |
${{ runner.os }}-expo-
- name: Install dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: npm ci --legacy-peer-deps
- name: Run Expo export
run: npm run build
env:
EXPO_NO_TELEMETRY: 1
sonarcloud:
name: SonarCloud Analysis
runs-on: ubuntu-latest
needs: [typescript-tests]
if: github.event_name == 'pull_request' || github.ref == 'refs/heads/main'
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download coverage report
uses: actions/download-artifact@v4
with:
name: coverage-report
path: coverage
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
# ─────────────────────────────────────────────────────────
# Rust / Soroban Smart Contract Checks
# ─────────────────────────────────────────────────────────
rust-format:
name: Rust Format Check
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ env.RUST_VERSION }}
components: rustfmt
- name: Check Rust formatting
run: cd contracts && cargo fmt --check
rust-clippy:
name: Rust Clippy Lint
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ env.RUST_VERSION }}
components: clippy
- name: Cache Rust dependencies and target
uses: actions/cache@v4
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
contracts/target/
key: ${{ runner.os }}-cargo-${{ env.RUST_VERSION }}-${{ hashFiles('contracts/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-${{ env.RUST_VERSION }}-
- name: Run Clippy
working-directory: ./contracts
run: cargo clippy --all-targets -- -D warnings
rust-tests:
name: Rust Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ env.RUST_VERSION }}
- name: Cache Rust dependencies and target
uses: actions/cache@v4
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
contracts/target/
key: ${{ runner.os }}-cargo-${{ env.RUST_VERSION }}-${{ hashFiles('contracts/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-${{ env.RUST_VERSION }}-
- name: Run Rust tests
working-directory: ./contracts
run: cargo test --verbose
rust-build:
name: Rust Build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ env.RUST_VERSION }}
- name: Cache Rust dependencies and target
uses: actions/cache@v4
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
contracts/target/
key: ${{ runner.os }}-cargo-${{ env.RUST_VERSION }}-${{ hashFiles('contracts/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-${{ env.RUST_VERSION }}-
- name: Build Rust contracts
working-directory: ./contracts
run: cargo build --release
# ─────────────────────────────────────────────────────────
# Load Testing
# ─────────────────────────────────────────────────────────
load-test:
name: k6 Load Test
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run k6 Load Test
uses: grafana/[email protected]
with:
filename: load-tests/run.js
flags: --env SCENARIO=subscription
# ─────────────────────────────────────────────────────────
# Bundle Size Monitoring
# ─────────────────────────────────────────────────────────
bundle-size:
name: Bundle Size Check
runs-on: ubuntu-latest
env:
EXPO_NO_TELEMETRY: 1
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci --legacy-peer-deps
- name: Check bundle size (PR)
if: github.event_name == 'pull_request'
uses: andresz1/size-limit-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
build_script: 'npm run build'
- name: Build app
if: github.event_name != 'pull_request'
run: npm run build
- name: Check bundle size (Push)
if: github.event_name != 'pull_request'
run: npx size-limit --json > bundle-size-report.json
- name: Upload bundle size report
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
uses: actions/upload-artifact@v7
with:
name: bundle-size-report-${{ github.sha }}
path: bundle-size-report.json
# ─────────────────────────────────────────────────────────
# Merge Protection (only on PRs)
# ─────────────────────────────────────────────────────────
merge-protection:
name: Merge Protection Check
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
needs:
[
commitlint,
typescript-lint,
typescript-typecheck,
typescript-tests,
typescript-build,
sonarcloud,
rust-format,
rust-clippy,
rust-tests,
rust-build,
load-test,
bundle-size,
]
steps:
- name: All checks passed
run: echo "All quality gates passed!"
# ─────────────────────────────────────────────────────────
# Full CI Summary (runs after all jobs)
# ─────────────────────────────────────────────────────────
ci-success:
name: CI Complete
runs-on: ubuntu-latest
if: always()
needs:
[
commitlint,
typescript-lint,
typescript-typecheck,
typescript-tests,
typescript-build,
sonarcloud,
rust-format,
rust-clippy,
rust-tests,
rust-build,
load-test,
bundle-size,
]
steps:
- name: Check for failures
run: |
if [ "${{ github.event_name }}" = "pull_request" ] && [ "${{ needs.commitlint.result }}" != "success" ]; then
echo "Conventional commit check failed"
exit 1
fi
if [ "${{ needs.typescript-lint.result }}" != "success" ] || \
[ "${{ needs.typescript-typecheck.result }}" != "success" ] || \
[ "${{ needs.typescript-tests.result }}" != "success" ] || \
[ "${{ needs.typescript-build.result }}" != "success" ] || \
[ "${{ needs.sonarcloud.result }}" != "success" ] || \
[ "${{ needs.rust-format.result }}" != "success" ] || \
[ "${{ needs.rust-clippy.result }}" != "success" ] || \
[ "${{ needs.rust-tests.result }}" != "success" ] || \
[ "${{ needs.rust-build.result }}" != "success" ] || \
[ "${{ needs.load-test.result }}" != "success" ] || \
[ "${{ needs.bundle-size.result }}" != "success" ]; then
echo "One or more CI checks failed"
exit 1
fi
echo "All CI checks passed successfully!"