Why not use SAP CI/CD service
SAP's Continuous Integration & Delivery service on BTP is technically correct but painful in practice:
- Limited customisation of pipeline steps
- Slow feedback loops (5β10 min for a simple iFlow deploy)
- No native GitHub PR integration
- Additional BTP service cost
GitHub Actions gives you full control, integrates directly with your PR workflow, runs faster, and is free for public repos. If you're already using GitHub, use GitHub Actions.
Repository structure
my-integration-suite/
βββ .github/
β βββ workflows/
β βββ deploy-dev.yml
β βββ deploy-qa.yml
β βββ deploy-prod.yml
βββ iflows/
β βββ OrderProcessing/
β β βββ OrderProcessing.iflw # exported iFlow ZIP extracted
β β βββ metainfo.prop
β β βββ src/main/resources/
β β βββ mapping/
β βββ InvoiceSync/
β βββ ...
βββ packages/
β βββ MyIntegrationPackage/
β βββ metainfo.prop
βββ scripts/
βββ deploy.sh
βββ validate.sh
Export iFlows from the CPI tenant as ZIP files and commit the extracted contents. This makes diffs readable β you can see what XSLT or Groovy changed in a PR review.
The pipeline workflow
# .github/workflows/deploy-dev.yml
name: Deploy to CPI Dev
on:
push:
branches: [develop]
paths:
- 'iflows/**'
- 'packages/**'
env:
CPI_HOST: ${{ secrets.CPI_DEV_HOST }}
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Get OAuth Token
id: token
run: |
TOKEN=$(curl -s -X POST \
"${{ secrets.XSUAA_URL }}/oauth/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-u "${{ secrets.CPI_CLIENT_ID }}:${{ secrets.CPI_CLIENT_SECRET }}" \
-d "grant_type=client_credentials" \
| jq -r '.access_token')
echo "::add-mask::$TOKEN"
echo "token=$TOKEN" >> $GITHUB_OUTPUT
- name: Upload iFlow
run: |
./scripts/deploy.sh \
--host "$CPI_HOST" \
--token "${{ steps.token.outputs.token }}" \
--iflow "OrderProcessing" \
--package "MyIntegrationPackage"
- name: Verify Deployment
run: |
./scripts/validate.sh \
--host "$CPI_HOST" \
--token "${{ steps.token.outputs.token }}" \
--iflow "OrderProcessing"
Use ::add-mask:: to redact the OAuth token from GitHub Actions logs. Without this, the token appears in plain text in the workflow run output β visible to anyone with read access to your repository.
Approval gates & environments
For production deployments, add a manual approval step using GitHub Environments:
- Go to Repository Settings β Environments β New environment
- Name it
production - Add Required reviewers (your tech lead or team lead)
- Set a Wait timer if you want a mandatory delay after approval
# .github/workflows/deploy-prod.yml
jobs:
deploy-prod:
runs-on: ubuntu-latest
environment: production # triggers approval gate
needs: [deploy-qa] # only runs after QA succeeded
steps:
# same deploy steps as dev, pointing to prod secrets
The pipeline stops at the production deploy job, sends a notification to the required reviewers, and only continues after manual approval in the GitHub UI. Zero extra tooling needed.
Tag the Git commit after every successful production deployment: git tag -a v1.4.2 -m "Deploy: OrderProcessing hotfix". When a production incident happens at 2am, you want to immediately see what version is deployed and diff it against the previous version.