SuperAPI AI Directory

ci-cd

Deployment & operations

View repository

Updated 10-16 02:37

About this skill

CI/CD — CAP Best Practices

Primary reference: https://cap.cloud.sap/docs/guides/deployment/cicd
GitHub Actions guide: https://cap.cloud.sap/docs/guides/deployment/github-actions (added Aug 2025)

Quick setup via CLI (recommended)

# Node.js project
cds add github-actions

# Java project (supported since Nov 2025)
cds add github-actions   # detects Java automatically

# Kyma/Kubernetes
cds add github-actions   # adds k8s-specific workflow

This generates .github/workflows/ with sensible defaults for your project type.

Node.js — standard GitHub Actions workflow

.github/workflows/ci.yml:

name: CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Lint CDS and JS
        run: npx eslint . --ext .cds,.js

      - name: Run tests
        run: npm test

      - name: Build for production
        run: npm run build:cf   # or build:k8s

  deploy-dev:
    needs: test
    if: github.ref == 'refs/heads/develop'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'

      - name: Install CF CLI
        run: |
          curl -L "https://packages.cloudfoundry.org/stable?release=linux64-binary&version=v8" | tar -zx
          sudo mv cf8 /usr/local/bin/cf

      - name: Build MTA
        run: |
          npm ci
          npm run build:cf
          mbt build -t gen/

      - name: Deploy to CF (Dev)
        env:
          CF_API: ${{ secrets.CF_API }}
          CF_USERNAME: ${{ secrets.CF_USERNAME }}
          CF_PASSWORD: ${{ secrets.CF_PASSWORD }}
          CF_ORG: ${{ secrets.CF_ORG }}
          CF_SPACE: ${{ vars.CF_SPACE_DEV }}
        run: |
          cf login -a $CF_API -u $CF_USERNAME -p $CF_PASSWORD -o $CF_ORG -s $CF_SPACE
          cf deploy gen/my-cap-app_1.0.0.mtar --retries 1

Java — GitHub Actions workflow

name: CI Java

on:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          java-version: '21'
          distribution: 'temurin'
          cache: 'maven'

      - name: Build and test
        run: mvn -B package --file pom.xml

      - name: CDS build
        run: |
          npm install -g @sap/cds-dk
          cds build --production

Kyma / Kubernetes deployment

name: Deploy to Kyma

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '22'

      - name: Login to container registry
        uses: docker/login-action@v3
        with:
          registry: ${{ vars.REGISTRY }}
          username: ${{ secrets.REGISTRY_USER }}
          password: ${{ secrets.REGISTRY_PASSWORD }}

      - name: Build and push image
        run: |
          pack build ${{ vars.REGISTRY }}/my-cap-app-srv:${{ github.sha }} \
            --builder paketobuildpacks/builder-jammy-base

      - name: Deploy with Helm
        run: |
          helm upgrade --install my-cap-app ./chart \
            --set srv.image.repository=${{ vars.REGISTRY }}/my-cap-app-srv \
            --set srv.image.tag=${{ github.sha }}

Using cds up for simplified deployment (Mar 2025+)

# CF — combines cds build + mbt build + cf deploy
cds up -2 cf

# With MTA extension for scaling:
cds up -2 cf --ext eu10-prod.mtaext

# Kyma — builds and deploys (Nov 2025: no more ctz dependency)
cds up -2 k8s

SAP CI/CD Service

Alternatively, use the SAP CI/CD Service on BTP:

  • Go to BTP Cockpit → CI/CD Service
  • Create a pipeline of type SAP Cloud Application Programming Model
  • Connect your GitHub/GitLab repository
  • Configure stages: Build → Test → Deploy

The service uses Piper pipeline templates tuned for CAP.

npm scripts to standardise across environments

{
  "scripts": {
    "build:cf":     "cds build --production && mbt build -t gen/",
    "build:k8s":    "cds build --production",
    "test":         "vitest run",             # recommended
    "test:jest":   "jest --forceExit --coverage", # if still on Jest
    "lint":         "eslint . --ext .cds,.js",
    "start:watch":  "cds watch"
  }
}

GitHub Secrets to configure

Secret Description
CF_API CF API endpoint, e.g. https://api.cf.eu10.hana.ondemand.com
CF_USERNAME BTP technical user
CF_PASSWORD BTP technical user password
CF_ORG CF organisation name
REGISTRY_USER Container registry user (Kyma)
REGISTRY_PASSWORD Container registry password (Kyma)

Use GitHub Environments for space-specific variables (CF_SPACE_DEV, CF_SPACE_PROD).

Common mistakes to avoid

  • ❌ Committing CF_PASSWORD directly — always use GitHub Secrets
  • ❌ Not pinning @sap/cds-dk version in CI — pipeline breaks on major upgrades
  • ❌ Running npm install instead of npm ci in CI — not reproducible
  • ❌ Using Jest for new projects — migrate to Vitest for full Chai ESM support
  • ✅ Use vitest run in CI; if still on Jest, always add --forceExit
  • ❌ Deploying without running tests first (needs: test dependency)
  • ❌ Not separating dev/staging/prod environments in the pipeline
  • ❌ Using ctz for Kyma builds — discontinued, use cds up --to k8s