Skip to content

A.1 - Caller Workflows

Caller workflows are the thin top-level files wired to GitHub Actions trigger events: push, pull_request, schedule, workflow_dispatch. Each caller composes one or more reusable workflows (defined in A.2) into a complete pipeline for that trigger. The caller is responsible for event filtering, concurrency scoping, and secret forwarding; it does not contain the quality gate logic itself.

A.1.1 - CI on Push

Lightweight push-time quality baseline. Runs on every push to every branch to provide immediate feedback before a PR is opened. On pushes to main, also triggers automated release management via release-please.

# .github/workflows/ci.yml
# Push Quality Baseline: runs lightweight quality checks on every push
# to any branch. On pushes to main, also triggers release management.

name: CI on Push

on:
  push:
    branches:
      - '**'

concurrency:
  group: push-${{ github.ref }}
  cancel-in-progress: true

jobs:
  # ── Formatting (runs first) ─────────────────────────────────
  prettier-verify:
    name: Formatting
    uses: ./.github/workflows/sf-prettier-verify.yml

  # ── Quality gates (run after formatting passes) ─────────────
  secret-scan:
    name: Secrets
    needs: prettier-verify
    uses: ./.github/workflows/sf-secret-scan.yml

  code-analyzer:
    name: Code Analysis
    needs: prettier-verify
    uses: ./.github/workflows/sf-code-analyzer.yml
    with:
      mode: ci
      workspace: force-app

  jest-tests:
    name: Jest Tests
    needs: prettier-verify
    uses: ./.github/workflows/sf-jest-tests.yml
    with:
      skip-delta-check: true
    secrets:
      CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

  # ── Release Management (main branch only, after all gates) ──
  release-please:
    name: Release
    needs: [secret-scan, code-analyzer, jest-tests]
    if: github.ref == 'refs/heads/main'
    uses: ./.github/workflows/release-please.yml
    secrets:
      RELEASE_PLEASE_TOKEN: ${{ secrets.RELEASE_PLEASE_TOKEN }}
      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

A.1.2 - PR to Production Branch

Full quality gate suite for pull requests targeting main. Authenticates to the production org for both Apex tests and deployment validation. The branch-specific split between this file and pr-staging.yml exists solely so that each caller can pass the correct credential secret; the underlying reusable workflows are identical.

# .github/workflows/pr-prod.yml
# PR Quality Gates (prod-bound): comprehensive quality gate suite for pull
# requests targeting `main`. Authenticates to the production org for both
# Apex tests and deployment validation.

name: CI on PR (prod)

on:
  pull_request:
    branches: [main]
    types: [opened, synchronize, ready_for_review]
    paths:
      - 'force-app/**'
      - '.github/**'

concurrency:
  group: pr-prod-${{ github.event.pull_request.number }}
  cancel-in-progress: true

jobs:
  # ── Independent gates (run in parallel) ─────────────────────

  semver-check:
    name: PR Title
    uses: ./.github/workflows/sf-semver-check.yml

  secret-scan:
    name: Secrets
    uses: ./.github/workflows/sf-secret-scan.yml

  prettier-verify:
    name: Formatting
    uses: ./.github/workflows/sf-prettier-verify.yml

  destructive-check:
    name: Destructive Changes
    uses: ./.github/workflows/sf-destructive-check.yml

  # ── Delta generation (prerequisite for analysis gates) ──────

  generate-delta:
    name: Delta Package
    uses: ./.github/workflows/sf-generate-delta.yml

  # ── Analysis gates (require delta) ──────────────────────────

  code-analyzer:
    name: Code Analysis
    needs: generate-delta
    if: needs.generate-delta.outputs.artifact-uploaded == 'true'
    uses: ./.github/workflows/sf-code-analyzer.yml
    with:
      mode: pr

  jest-tests:
    name: Jest Tests
    needs: generate-delta
    if: needs.generate-delta.outputs.artifact-uploaded == 'true'
    uses: ./.github/workflows/sf-jest-tests.yml
    secrets:
      CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

  apex-tests:
    name: Apex Tests
    needs: generate-delta
    if: needs.generate-delta.outputs.artifact-uploaded == 'true'
    uses: ./.github/workflows/sf-apex-tests-pr.yml
    secrets:
      SFDX_AUTH_URL: ${{ secrets.SFDX_AUTH_URL_PROD }}
      CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

  # ── Deployment validation (final gate) ──────────────────────

  validate-deploy:
    name: Validation
    needs: [generate-delta, code-analyzer, apex-tests, destructive-check]
    if: needs.generate-delta.outputs.artifact-uploaded == 'true' && !failure() && !cancelled()
    uses: ./.github/workflows/sf-validate-deployment.yml
    secrets:
      SFDX_AUTH_URL_VALIDATION: ${{ secrets.SFDX_AUTH_URL_PROD }}

A.1.3 - PR to Staging Branches

Identical gate chain to A.1.2, targeted at non-prod long-lived branches (staging, uat, integration, full). Authenticates to the staging org rather than production.

# .github/workflows/pr-staging.yml
# PR Quality Gates (staging-bound): comprehensive quality gate suite for pull
# requests targeting non-prod long-lived branches. Authenticates to the
# staging org for both Apex tests and deployment validation.

name: CI on PR (staging)

on:
  pull_request:
    branches: [staging, uat, integration, full]
    types: [opened, synchronize, ready_for_review]
    paths:
      - 'force-app/**'
      - '.github/**'

concurrency:
  group: pr-staging-${{ github.event.pull_request.number }}
  cancel-in-progress: true

jobs:
  # ── Independent gates (run in parallel) ─────────────────────

  semver-check:
    name: PR Title
    uses: ./.github/workflows/sf-semver-check.yml

  secret-scan:
    name: Secrets
    uses: ./.github/workflows/sf-secret-scan.yml

  prettier-verify:
    name: Formatting
    uses: ./.github/workflows/sf-prettier-verify.yml

  destructive-check:
    name: Destructive Changes
    uses: ./.github/workflows/sf-destructive-check.yml

  # ── Delta generation (prerequisite for analysis gates) ──────

  generate-delta:
    name: Delta Package
    uses: ./.github/workflows/sf-generate-delta.yml

  # ── Analysis gates (require delta) ──────────────────────────

  code-analyzer:
    name: Code Analysis
    needs: generate-delta
    if: needs.generate-delta.outputs.artifact-uploaded == 'true'
    uses: ./.github/workflows/sf-code-analyzer.yml
    with:
      mode: pr

  jest-tests:
    name: Jest Tests
    needs: generate-delta
    if: needs.generate-delta.outputs.artifact-uploaded == 'true'
    uses: ./.github/workflows/sf-jest-tests.yml
    secrets:
      CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

  apex-tests:
    name: Apex Tests
    needs: generate-delta
    if: needs.generate-delta.outputs.artifact-uploaded == 'true'
    uses: ./.github/workflows/sf-apex-tests-pr.yml
    secrets:
      SFDX_AUTH_URL: ${{ secrets.SFDX_AUTH_URL_STAGING }}
      CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

  # ── Deployment validation (final gate) ──────────────────────

  validate-deploy:
    name: Validation
    needs: [generate-delta, code-analyzer, apex-tests, destructive-check]
    if: needs.generate-delta.outputs.artifact-uploaded == 'true' && !failure() && !cancelled()
    uses: ./.github/workflows/sf-validate-deployment.yml
    secrets:
      SFDX_AUTH_URL_VALIDATION: ${{ secrets.SFDX_AUTH_URL_STAGING }}

A.1.4 - Scheduled Drift Detection

Weekly org surveillance. Runs metadata drift detection, Apex compilation, and a full-org Apex test run against production. Slack-notifies on any failure.

# .github/workflows/scheduled-drift-detection.yml
# Weekly Surveillance: scheduled monitoring of org health.
# Runs drift detection, compilation check, then full-org Apex tests.
# Creates GitHub issues on failures and notifies Slack.

name: Weekly Org Surveillance

on:
  schedule:
    - cron: '0 22 * * 2' # Tuesdays at 10:00 PM UTC
  workflow_dispatch: # Allow manual trigger

jobs:
  # ── Drift detection (parallel with compilation) ─────────────

  drift-detection:
    name: Drift Detection
    uses: ./.github/workflows/sf-drift-detection.yml
    secrets:
      SFDX_AUTH_URL: ${{ secrets.SFDX_AUTH_URL_PROD }}

  # ── Compilation check (must pass before Apex tests) ─────────

  apex-compilation:
    name: Apex Compilation
    uses: ./.github/workflows/sf-apex-compilation.yml
    secrets:
      SFDX_AUTH_URL: ${{ secrets.SFDX_AUTH_URL_PROD }}

  # ── Full-org Apex tests (after compilation passes) ──────────

  apex-tests:
    name: Full-Org Apex Tests
    needs: apex-compilation
    uses: ./.github/workflows/sf-apex-tests.yml
    secrets:
      SFDX_AUTH_URL: ${{ secrets.SFDX_AUTH_URL_PROD }}
      CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

  # ── Failure notification ────────────────────────────────────

  notify-failure:
    name: Notify on Failure
    needs: [drift-detection, apex-tests, apex-compilation]
    if: failure()
    uses: ./.github/workflows/sf-notify-slack.yml
    with:
      status: 'Failure'
      title: 'Weekly Surveillance Failed'
      message: 'One or more surveillance checks failed. Review the workflow run for details.'
      run-url: 'https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}'
    secrets:
      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

A.1.5 - Scheduled Nightly Test Runner

Nightly full-org Apex test run. Catches failures in components that depend on recently changed code but were not included in PR-scoped test execution. Lighter than the weekly surveillance workflow: no drift detection.

# .github/workflows/scheduled-test-runner.yml
# Nightly Apex test runner: compiles first, then runs full-org Apex tests,
# writes results to GITHUB_STEP_SUMMARY, and optionally uploads coverage to Codecov.

name: Nightly Apex Test Runner

on:
  schedule:
    - cron: '0 22 * * *' # Every night at 10:00 PM UTC
  workflow_dispatch: # Allow manual trigger

jobs:
  # ── Compilation check (must pass before Apex tests) ─────────

  apex-compilation:
    name: Apex Compilation
    uses: ./.github/workflows/sf-apex-compilation.yml
    secrets:
      SFDX_AUTH_URL: ${{ secrets.SFDX_AUTH_URL_PROD }}

  # ── Full-org Apex tests (after compilation passes) ──────────

  apex-tests:
    name: Full-Org Apex Tests
    needs: apex-compilation
    uses: ./.github/workflows/sf-apex-tests.yml
    secrets:
      SFDX_AUTH_URL: ${{ secrets.SFDX_AUTH_URL_PROD }}
      CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

  # ── Failure notification ────────────────────────────────────

  notify-failure:
    name: Notify on Failure
    needs: [apex-compilation, apex-tests]
    if: failure()
    uses: ./.github/workflows/sf-notify-slack.yml
    with:
      status: 'Failure'
      title: 'Nightly Test Runner Failed'
      message: 'Apex compilation or test execution failed. Review the workflow run for details.'
      run-url: 'https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}'
    secrets:
      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}