GitHub Actions for Fabric
Validate on PR, deploy on merge. A service principal, fabric-cli, and two workflows.
Prerequisites
Create a service principal (SPN)
Register an Entra app. Grant it the Fabric permissions your org allows for SPNs, and add it as a workspace Admin on dev/test/prod (or via a group).
Enable SPN access in the Fabric admin portal
Admin portal → Tenant settings → Service principals can use Fabric APIs — scope
to a security group containing your SPN.
Store secrets in GitHub
FABRIC_CLIENT_ID, FABRIC_CLIENT_SECRET, FABRIC_TENANT_ID. Put deploy
secrets in a protected Environment (prod) with required reviewers.
PR validation workflow
# .github/workflows/pr-validate.yml
name: Validate Fabric items
on:
pull_request:
branches: [main]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install fabric-cli
run: pip install ms-fabric-cli
- name: Login
env:
FABRIC_CLIENT_ID: ${{ secrets.FABRIC_CLIENT_ID }}
FABRIC_CLIENT_SECRET: ${{ secrets.FABRIC_CLIENT_SECRET }}
FABRIC_TENANT_ID: ${{ secrets.FABRIC_TENANT_ID }}
run: |
fab auth login -u "$FABRIC_CLIENT_ID" \
-p "$FABRIC_CLIENT_SECRET" --tenant "$FABRIC_TENANT_ID"
- name: Static checks
run: |
python -m json.tool < parameter.yml > /dev/null || (echo "bad parameter.yml" && exit 1)
# notebook lint, naming conventions, forbidden hard-coded workspace ids
! grep -rEn "abfss://[^ ]*@onelake" workspaces/ || (echo "hard-coded OneLake path" && exit 1)Deploy workflow
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy-test:
runs-on: ubuntu-latest
environment: test
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: '3.11' }
- run: pip install ms-fabric-cli
- name: Login
env:
FABRIC_CLIENT_ID: ${{ secrets.FABRIC_CLIENT_ID }}
FABRIC_CLIENT_SECRET: ${{ secrets.FABRIC_CLIENT_SECRET }}
FABRIC_TENANT_ID: ${{ secrets.FABRIC_TENANT_ID }}
run: fab auth login -u "$FABRIC_CLIENT_ID" -p "$FABRIC_CLIENT_SECRET" --tenant "$FABRIC_TENANT_ID"
- name: Update dev workspace from Git
run: fab git update "Analytics - Dev" --remote-commit-hash "$GITHUB_SHA" --wait
- name: Deploy dev -> test
run: |
fab deploy-pipeline "Analytics Pipeline" --source Development --target Test --wait
- name: Smoke test
run: fab job run "Analytics - Test" --item "Smoke.Notebook" --wait
deploy-prod:
needs: deploy-test
runs-on: ubuntu-latest
environment: prod # required reviewers gate this
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: '3.11' }
- run: pip install ms-fabric-cli
- name: Login
env:
FABRIC_CLIENT_ID: ${{ secrets.FABRIC_CLIENT_ID }}
FABRIC_CLIENT_SECRET: ${{ secrets.FABRIC_CLIENT_SECRET }}
FABRIC_TENANT_ID: ${{ secrets.FABRIC_TENANT_ID }}
run: fab auth login -u "$FABRIC_CLIENT_ID" -p "$FABRIC_CLIENT_SECRET" --tenant "$FABRIC_TENANT_ID"
- name: Deploy test -> prod
run: fab deploy-pipeline "Analytics Pipeline" --source Test --target Production --waitms-fabric-cli command names evolve. Pin the version (pip install ms-fabric-cli==<x.y.z>) and check fab --help when upgrading.
What CI cannot do yet
- Some item types still lack full API deploy support — check the current matrix.
- SPNs cannot perform every workspace operation a user can; test each command with the SPN early, not on release day.
Was this page helpful?
Stay ahead of Fabric changes
Fabric runtime changes, API updates, and deprecations. No spam, unsubscribe anytime.