Skip to content

Configure the repository ​

Make a fork's main behave like the original's: squash-only merges titled by the PR, CI required.

You need: gh signed in as a repository admin; replace OWNER/REPO.

1. Merge settings ​

sh
gh api -X PATCH repos/OWNER/REPO \
  -F allow_squash_merge=true -F allow_merge_commit=false -F allow_rebase_merge=false \
  -f squash_merge_commit_title=PR_TITLE -f squash_merge_commit_message=BLANK \
  -F delete_branch_on_merge=true

The title is the whole commit, so breaking changes are feat(config)!: … — after the public launch; while release-please-config.json pins the next version (release-as), the check refuses a ! and the change ships as a minor.

2. The title check ​

.depot/workflows/pr-title.yml checks type(scope)!: description against release-please-config.json and the code map's Areas; ! needs Migration notes.

sh
npm run check:pr-title -- "feat(slack): thread routing"

During the Depot CI trial, CI and PR title checks run automatically only from .depot/workflows/; their GitHub Actions copies are manual rollback options. CodeQL, Scorecard, release-please, production deployment and review auto-approval use GitHub Actions on Depot runners. Release publishing retains its GitHub OIDC identity for npm trusted publishing and image attestations. Each workflow has one automatic owner.

3. The ruleset for main ​

Checks are job names; each must report on merge_group. Save as main-ruleset.json:

json
{
  "name": "main",
  "target": "branch",
  "enforcement": "active",
  "conditions": { "ref_name": { "include": ["~DEFAULT_BRANCH"], "exclude": [] } },
  "rules": [
    { "type": "deletion" },
    { "type": "non_fast_forward" },
    {
      "type": "pull_request",
      "parameters": {
        "allowed_merge_methods": ["squash"],
        "dismiss_stale_reviews_on_push": false,
        "require_code_owner_review": false,
        "require_last_push_approval": false,
        "required_approving_review_count": 0,
        "required_review_thread_resolution": false
      }
    },
    {
      "type": "required_status_checks",
      "parameters": {
        "strict_required_status_checks_policy": false,
        "do_not_enforce_on_create": false,
        "required_status_checks": [
          { "context": "bot", "integration_id": 15368 },
          { "context": "web", "integration_id": 15368 },
          { "context": "docs", "integration_id": 15368 },
          { "context": "workers", "integration_id": 15368 },
          { "context": "image", "integration_id": 15368 },
          { "context": "package", "integration_id": 15368 },
          { "context": "title", "integration_id": 15368 }
        ]
      }
    }
  ]
}
sh
gh api -X POST repos/OWNER/REPO/rulesets --input main-ruleset.json
# later: list, then update in place
gh api repos/OWNER/REPO/rulesets --jq '.[] | {id, name}'
gh api -X PUT repos/OWNER/REPO/rulesets/RULESET_ID --input main-ruleset.json

15368 is the GitHub Actions app; the agent's LGTM reviews.

Merge queue (optional) ​

One more rule in the ruleset:

json
{
  "type": "merge_queue",
  "parameters": {
    "merge_method": "SQUASH",
    "grouping_strategy": "ALLGREEN",
    "check_response_timeout_minutes": 60,
    "max_entries_to_build": 5,
    "max_entries_to_merge": 5,
    "min_entries_to_merge": 1,
    "min_entries_to_merge_wait_minutes": 5
  }
}

4. Actions permissions ​

release-please.yml and auto-approve-review-lgtm.yml need this:

sh
gh api -X PUT repos/OWNER/REPO/actions/permissions/workflow \
  -f default_workflow_permissions=read -F can_approve_pull_request_reviews=true

5. Repository secrets and variables ​

Secrets: CLOUDFLARE_DEPLOY_TOKEN, MEMORY_TOKEN, RESIDENT_READ_TOKEN, optionally SANDBOX_TOKEN; CLOUDFLARE_API_TOKEN for the docs deploy (Rotate a secret); and the GitHub App release-please acts as and the deploy reads your configuration repository with — its client ID and a private key (.pem), as CONFIG_REPO_APP_CLIENT_ID and CONFIG_REPO_APP_PRIVATE_KEY. Repository secrets, not a vault: they are encrypted at rest, never shown again, and an organization secret scoped to private repositories would vanish the day the repository goes public.

sh
gh secret set CONFIG_REPO_APP_CLIENT_ID < client-id.txt
gh secret set CONFIG_REPO_APP_PRIVATE_KEY < <your-app>.private-key.pem
sh
gh variable set SWITCHBOARD_PUBLISH_NPM --body true
gh variable set SWITCHBOARD_DEPLOY_PROFILE --body "github://OWNER/CONFIG-REPO/switchboard/profile.json@main"
gh variable set CONFIG_REPO_OWNER --body "OWNER"
gh variable set CONFIG_REPO_NAME --body "CONFIG-REPO"

Automatic releases default to targets=affected and cli=checkout. Set SWITCHBOARD_RELEASE_DEPLOY_TARGETS to affected, all, or comma-separated Worker names (memory, bot, resident, sandbox), and SWITCHBOARD_RELEASE_DEPLOY_CLI to checkout or package to use the reusable workflow's existing selection. A scoped memory,bot selection preserves the execution Workers. Package mode waits for successful npm publication at the exact released tag's version; disabled, skipped or failed publication refuses package deployment. The manifest must match that version. Unset the selection variables to restore the defaults. Neither setting overrides the profile, preflights, smoke requirements or live readiness checks.

npm publishing uses no token. Once, before turning the variable on: an admin of the npm org publishes a placeholder 0.0.0 of the package from an empty directory (npm init --scope=@OWNER -y, npm pkg set name=… version=0.0.0, npm publish --access public), then on the package's npm settings adds a Trusted Publisher: GitHub Actions, this repository, workflow file release-please.yml. From then on every release cut from the default branch publishes with the workflow's own identity. No provenance attestation (--provenance=false): trusted publishing would generate one by default, npm accepts it from GitHub-hosted runners alone, and this project's CI runs on Namespace runners. A release line on another branch never publishes to npm; to skip one release, set the variable to false before merging its release PR (the run says so in a notice).

Approve on the agent's LGTM ​

auto-approve-review-lgtm.yml approves on this App's LGTM: … review comment (Agent review). Switchboard mints that line only when every finding sits below the severity to address (review.addressSeverity, default minor; item 5a): an approve over a major or minor finding is posted as Changes requested:, so the workflow never approves over one.

sh
gh api users/YOUR-APP[bot] --jq '{login, id}'       # the App's bot user: its slug plus "[bot]"
gh variable set REVIEW_BOT_LOGIN --body 'YOUR-APP[bot]'
gh variable set REVIEW_BOT_ID --body 'THE-ID'

Without section 4 it fails with 422.

6. Dependabot ​

Beside .github/dependabot.yml:

sh
gh api -X PUT repos/OWNER/REPO/vulnerability-alerts
gh api -X PUT repos/OWNER/REPO/automated-security-fixes

7. Description, homepage and topics ​

project.json is the source; check:project-facts validates it.

sh
gh repo edit OWNER/REPO \
  --description "$(jq -r .description project.json)" \
  --homepage "$(jq -r .docs project.json)" \
  $(jq -r '.topics[] | "--add-topic " + .' project.json)

--remove-topic NAME drops one.

Next ​