Tutorial: CI/CD pipeline
This tutorial walks through a complete GitHub Actions pipeline for a CephalonEngine app. The reference assumes the First-app shape and produces a signed container image deployed to Azure Container Apps on tag.
Pipeline shape
Section titled “Pipeline shape”name: ci
on: pull_request: push: branches: [main] tags: ['v*.*.*']
jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-dotnet@v4 with: dotnet-version: '10.x' - run: dotnet restore - run: dotnet build --no-restore -c Release - run: dotnet test --no-build -c Release --filter "Category!=Integration" - run: dotnet test --no-build -c Release --filter "Category=Integration"
benchmark: runs-on: ubuntu-latest if: github.event_name == 'pull_request' steps: - uses: actions/checkout@v4 - uses: actions/setup-dotnet@v4 with: { dotnet-version: '10.x' } - run: dotnet run --project ./benchmarks -c Release -- --filter "*HotPath*"
image: needs: test runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/v') permissions: { id-token: write, contents: read } steps: - uses: actions/checkout@v4 - uses: azure/login@v2 with: { client-id: ${{ secrets.AZURE_CLIENT_ID }}, tenant-id: ${{ secrets.AZURE_TENANT_ID }}, subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} } - run: ./deploy/container-image/publish-image.ps1 -Registry acmestore.azurecr.io -Tag ${GITHUB_REF_NAME#v}
deploy: needs: image runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/v') steps: - uses: actions/checkout@v4 - uses: azure/login@v2 with: { client-id: ${{ secrets.AZURE_CLIENT_ID }}, tenant-id: ${{ secrets.AZURE_TENANT_ID }}, subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} } - run: ./deploy/azure-container-apps/deploy-up.ps1 -AppName acmestore -Image acmestore.azurecr.io/acme/store:${GITHUB_REF_NAME#v}Why this shape
Section titled “Why this shape”testruns on every PR with composition + behavior in the fast lane, then integration.benchmarkruns on PRs only so trunk stays free of benchmark noise.imageruns on tags only so unsigned, half-validated images never get published.deployis gated byimageso a failed publish blocks the rollout.
Status
Section titled “Status”The full step-by-step lands in the next docs push. Until then:
- the AGENTS.md in the engine repo documents
pwsh ./scripts/publish-package-artifacts.ps1and the local-feed flow. - First-app step 8 shows the manual ACA deploy this pipeline automates.