Skip to content

Appendix C: GitHub Rulesets Configuration Reference

This appendix provides a practical reference for configuring GitHub Rulesets to enforce the governance model described throughout this whitepaper. Rulesets are the enforcement mechanism that transforms documented standards into non-negotiable pipeline controls - applied at the organization level so that protection policies are consistent across all repositories without requiring per-repository configuration.

Full GitHub Rulesets documentation: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/about-rulesets

Organization-Level vs. Repository-Level Rulesets

Organization-level Rulesets apply across all repositories in the GitHub organization by repository and branch name pattern - they are the correct scope for the governance controls described in this whitepaper. Repository-level Rulesets apply only to a single repository and are appropriate for project-specific rules. Repository maintainers may add repository-level Rulesets for project-specific requirements, but they cannot override or weaken organization-level Rulesets.

Tiered Branch Protection Rulesets

Ruleset 1 - Integration Branch Protection

{
    "name": "integration-branch-protection",
    "target": "branch",
    "enforcement": "active",
    "conditions": {
        "ref_name": {
            "include": ["refs/heads/integration", "refs/heads/dev/*"],
            "exclude": []
        }
    },
    "rules": [
        {
            "type": "pull_request",
            "parameters": {
                "required_approving_review_count": 1,
                "dismiss_stale_reviews_on_push": true,
                "require_code_owner_review": false,
                "require_last_push_approval": false
            }
        },
        {
            "type": "required_status_checks",
            "parameters": {
                "strict_required_status_checks_policy": false,
                "required_status_checks": [{ "context": "sf-code-analyzer" }, { "context": "sf-prettier-verify" }, { "context": "sf-apex-tests" }, { "context": "sf-jest-tests" }]
            }
        },
        { "type": "non_fast_forward" }
    ]
}

Ruleset 2 - Staging and UAT Branch Protection

{
    "name": "staging-branch-protection",
    "target": "branch",
    "enforcement": "active",
    "conditions": {
        "ref_name": {
            "include": ["refs/heads/staging", "refs/heads/uat"],
            "exclude": []
        }
    },
    "rules": [
        {
            "type": "pull_request",
            "parameters": {
                "required_approving_review_count": 2,
                "dismiss_stale_reviews_on_push": true,
                "require_code_owner_review": true,
                "require_last_push_approval": true
            }
        },
        {
            "type": "required_status_checks",
            "parameters": {
                "strict_required_status_checks_policy": true,
                "required_status_checks": [
                    { "context": "sf-code-analyzer" },
                    { "context": "sf-prettier-verify" },
                    { "context": "sf-apex-tests" },
                    { "context": "sf-jest-tests" },
                    { "context": "sf-validate-deploy" },
                    { "context": "sf-secret-scan" },
                    { "context": "sf-semver-check" }
                ]
            }
        },
        { "type": "required_merge_queue" },
        { "type": "non_fast_forward" },
        { "type": "deletion" }
    ]
}

Ruleset 3 - Production Branch Protection (main)

{
    "name": "production-branch-protection",
    "target": "branch",
    "enforcement": "active",
    "conditions": {
        "ref_name": {
            "include": ["refs/heads/main"],
            "exclude": []
        }
    },
    "rules": [
        {
            "type": "pull_request",
            "parameters": {
                "required_approving_review_count": 2,
                "dismiss_stale_reviews_on_push": true,
                "require_code_owner_review": true,
                "require_last_push_approval": true,
                "allowed_merge_methods": ["squash"]
            }
        },
        {
            "type": "required_status_checks",
            "parameters": {
                "strict_required_status_checks_policy": true,
                "required_status_checks": [
                    { "context": "sf-code-analyzer" },
                    { "context": "sf-prettier-verify" },
                    { "context": "sf-apex-tests" },
                    { "context": "sf-jest-tests" },
                    { "context": "sf-validate-deploy" },
                    { "context": "sf-secret-scan" },
                    { "context": "sf-destructive-check" },
                    { "context": "sf-semver-check" }
                ]
            }
        },
        { "type": "non_fast_forward" },
        { "type": "deletion" },
        { "type": "required_signatures" }
    ]
}

Required Workflows Ruleset

{
    "name": "required-workflows",
    "target": "branch",
    "enforcement": "active",
    "conditions": {
        "ref_name": {
            "include": ["refs/heads/main", "refs/heads/staging", "refs/heads/uat"],
            "exclude": []
        }
    },
    "rules": [
        {
            "type": "workflows",
            "parameters": {
                "workflows": [
                    {
                        "repository_id": "<template-repo-id>",
                        "path": ".github/workflows/sf-code-analyzer.yml",
                        "ref": "refs/heads/main"
                    },
                    {
                        "repository_id": "<template-repo-id>",
                        "path": ".github/workflows/sf-apex-tests.yml",
                        "ref": "refs/heads/main"
                    },
                    {
                        "repository_id": "<template-repo-id>",
                        "path": ".github/workflows/sf-secret-scan.yml",
                        "ref": "refs/heads/main"
                    }
                ]
            }
        }
    ]
}

Replace <template-repo-id> with the numeric ID of the configuration repository, retrievable via the GitHub API or the repository's Settings page. If the consuming repositories pin to versioned template references, the ref should point to the appropriate version tag rather than refs/heads/main.

Bypass Lists

{
    "bypass_actors": [
        {
            "actor_id": "<release-please-app-id>",
            "actor_type": "Integration",
            "bypass_mode": "always"
        },
        {
            "actor_id": "<deployment-service-account-id>",
            "actor_type": "Team",
            "bypass_mode": "pull_request"
        }
    ]
}

The bypass_mode of pull_request allows the actor to bypass pull request requirements but not status check requirements. The always bypass mode should be reserved for the Release Please integration and similar automation operating on already-validated commits. All bypass actor assignments should be documented in the configuration repository's docs/ directory and reviewed periodically.

Importing and Exporting Rulesets

GitHub Rulesets can be exported from the organization settings UI as JSON and committed to the configuration repository's rulesets/ directory for version control. The GitHub CLI can apply Ruleset configuration programmatically from these exported files, enabling Ruleset configuration to be part of a new organization bootstrap script:

gh api \
  --method POST \
  -H "Accept: application/vnd.github+json" \
  /orgs/{org}/rulesets \
  --input rulesets/production-branch-protection.json