Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions .github/workflows/safe_settings_sync.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Workflow to apply safe-settings org configuration.
# Manual dispatch only — add push/schedule triggers after initial validation.
# Runs daily to reconcile settings and on manual dispatch.
# Uses a dedicated safe-settings-bot GitHub App for authentication.
#
# safe-settings reads config from the admin repo's default branch (main).
Expand All @@ -9,6 +9,9 @@
name: Safe Settings Sync

"on":
schedule:
# Daily at 07:00 UTC — after peribolos apply (05:30 UTC, ~40 min)
- cron: '0 7 * * *'
workflow_dispatch:
inputs:
dry-run:
Expand Down Expand Up @@ -122,8 +125,8 @@ jobs:
DEPLOYMENT_CONFIG_FILE: >-
${{ inputs.repos != '' && '/tmp/scoped-deployment-settings.yml'
|| format('{0}/safe-settings/deployment-settings.yml', github.workspace) }}
FULL_SYNC_NOP: ${{ inputs.dry-run }}
LOG_LEVEL: ${{ inputs.dry-run && 'debug' || 'info' }}
FULL_SYNC_NOP: ${{ github.event_name == 'schedule' && 'false' || inputs.dry-run }}
LOG_LEVEL: ${{ (github.event_name == 'schedule' || !inputs.dry-run) && 'info' || 'debug' }}
run: |
if [ "$FULL_SYNC_NOP" = "true" ]; then
echo "=== DRY-RUN MODE: Showing what would change ==="
Expand Down
46 changes: 18 additions & 28 deletions MAINTAINING.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,17 +108,21 @@ code review auto-assignment is not used for this team.
in `safe-settings/settings.yml`. **Both files must be updated** — the
suborg controls settings inheritance, the ruleset controls branch
protection.
4. Submit a PR. CI boundary tests validate consistency.
5. After merge, trigger `workflow_dispatch` on the "Safe Settings Sync"
workflow to apply.
4. Add the repo to `safe-settings/deployment-settings.yml` under
`restrictedRepos.include` so safe-settings manages it.
5. Submit a PR. CI boundary tests validate consistency.
6. After merge, the daily safe-settings sync (07:00 UTC) applies the
change automatically. For immediate application, trigger a manual
`workflow_dispatch` run.

### Change Branch Protection Rules or Rulesets

1. Edit `safe-settings/settings.yml` — modify the ruleset under `rulesets`.
2. The `safe-settings: code repos` ruleset applies to code repos.
3. The `safe-settings: non-code repos` ruleset applies to non-code repos.
4. Submit a PR and merge.
5. Trigger `workflow_dispatch` to apply.
5. The daily sync applies the change automatically. For immediate
application, trigger a manual `workflow_dispatch` run.

### Add a Repo-Specific Override

Expand Down Expand Up @@ -265,22 +269,20 @@ Go to Actions > "Safe Settings Sync" > "Run workflow":
`complytime-demos,community`). Leave empty to apply to all managed
repos.

### Future automation
### Automation

After initial validation, the workflow can be extended with:
- `push` trigger on `safe-settings/**` path changes to main
- `schedule` trigger (daily at 06:00 UTC) for drift correction

These triggers are intentionally disabled during the initial rollout to
ensure full manual control.
The Safe Settings Sync workflow runs daily at 07:00 UTC (after
peribolos apply at 05:30 UTC) to reconcile settings automatically.
Manual dispatch is available for immediate application or dry-run
previews.

## Troubleshooting

### Settings not applied after merge

1. Trigger `workflow_dispatch` manually — safe-settings only runs on
manual dispatch during initial rollout (no push/schedule triggers).
2. Check the "Safe Settings Sync" workflow run in the Actions tab.
1. Check the "Safe Settings Sync" workflow run in the Actions tab —
the daily sync at 07:00 UTC should have applied the change.
2. If it hasn't run yet, trigger `workflow_dispatch` manually.
3. Look for errors in the workflow logs (credential expiry, API errors).

### Boundary test failures
Expand Down Expand Up @@ -355,22 +357,10 @@ GitHub uses two distinct mechanisms, each with different conflict behavior:

## Excluded Repos

The following repos are excluded from safe-settings management:
The following repos are excluded from safe-settings management
(not listed in `deployment-settings.yml` `restrictedRepos.include`):

- `.github` — the admin repo (avoids circular dependency). Its
ruleset ("verify") is managed manually via the GitHub UI.
- `complyscribe` — archived.
- `gemara-content-service` — archived (moved to complytime-labs).

These are listed in `safe-settings/deployment-settings.yml` under
`restrictedRepos` and/or excluded from suborg files.

## Migration Notes

Existing repo-level rulesets (created manually via the GitHub UI) coexist
with the new org-level rulesets managed by safe-settings. GitHub evaluates
all active rulesets and the most restrictive rule wins.

After verifying the org-level rulesets work correctly, the old repo-level
rulesets should be deleted via the GitHub UI. The full list is documented
in comments at the top of `safe-settings/settings.yml`.
10 changes: 2 additions & 8 deletions safe-settings/repos/complyctl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,8 @@
# This override is applied on top of the code-repos suborg settings,
# which inherit from org-wide settings.yml.

# Supplement the org-level "safe-settings: code repos" ruleset to require
# 2 approvers (org baseline is 1). This matches the current
# general-rules ruleset on complyctl (id=2569356).
#
# NOTE: safe-settings rulesets defined here are repo-level rulesets,
# separate from the org-level rulesets in settings.yml. The org-level
# ruleset still applies; GitHub evaluates both and the most restrictive
# rule wins.
# Require 2 approvers (org baseline is 1). GitHub evaluates both
# org-level and repo-level rulesets — the most restrictive wins.
rulesets:
- name: "safe-settings: complyctl stricter review"
target: branch
Expand Down
13 changes: 4 additions & 9 deletions safe-settings/repos/complytime.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,10 @@
# This override is applied on top of the non-code-repos suborg
# settings, which inherit from org-wide settings.yml.

# Supplement the org-level "safe-settings: non-code repos" ruleset
# to require 2 approvers and dismiss stale reviews (non-code repos
# baseline is 1 approver, no stale review dismissal). This matches
# the current "main" ruleset on complytime (id=17986337).
#
# NOTE: safe-settings rulesets defined here are repo-level rulesets,
# separate from the org-level rulesets in settings.yml. The org-level
# ruleset still applies; GitHub evaluates both and the most restrictive
# rule wins.
# Require 2 approvers and dismiss stale reviews (non-code repos
# baseline is 1 approver, no stale review dismissal). GitHub
# evaluates both org-level and repo-level rulesets — the most
# restrictive wins.
rulesets:
- name: "safe-settings: complytime stricter review"
target: branch
Expand Down
34 changes: 4 additions & 30 deletions safe-settings/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,14 @@
# description, has_projects, default_branch
# See MAINTAINING.md for the full tool boundary.
#
# MIGRATION NOTE: Existing repo-level rulesets (created manually via the
# GitHub UI) are being replaced by safe-settings managed rulesets.
# GitHub evaluates all active rulesets and the most restrictive rule
# wins, so both can coexist during migration. After verifying the
# safe-settings rulesets work correctly, the old repo-level rulesets
# should be deleted manually.
#
# Remaining repo-level rulesets to clean up:
# complypack: tags (active) — replaced by "release tag protection"
# complytime: main (active) — replaced by repos/complytime.yml
#
# Excluded from safe-settings management:
# complyscribe: archived
# gemara-content-service: archived (moved to complytime-labs)
# complyscribe: archived

repository:
# Allow auto-merge on pull requests when all requirements are met.
# Currently enabled on 7 repos; this will enable it on the remaining 4
# (complytime, complytime-demos, website, complytime-policies).
allow_auto_merge: true

# Automatically delete head branches after pull requests are merged.
# Currently only on complyctl; this enables it org-wide.
delete_branch_on_merge: true

# Merge strategies.
Expand All @@ -42,16 +27,12 @@ repository:
allow_rebase_merge: false

# Allow the "Update branch" button on PRs.
# Currently only on complyctl; this enables it org-wide.
allow_update_branch: true

# Disable wiki org-wide. Documentation lives in dedicated repos.
# Currently enabled on all repos; this is an intentional hardening.
has_wiki: false

# Dependabot vulnerability alerts and automated security fixes.
# Currently only complyctl and org-infra have dependabot_security_updates
# enabled; this enables it org-wide.
security:
enableVulnerabilityAlerts: true
enableAutomatedSecurityFixes: true
Expand Down Expand Up @@ -100,14 +81,8 @@ rulesets:
- type: non_fast_forward

# Pull request requirements.
# Baseline: 1 approver, dismiss stale reviews, code owner review,
# last push approval. This matches the org-infra ruleset.
#
# complyctl currently requires 2 approvers — preserved via a
# repo-level override in repos/complyctl.yml.
#
# required_review_thread_resolution is false everywhere today.
# Kept false to match current state. Can tighten later.
# Repos needing stricter review (e.g. 2 approvers) use
# repo-level overrides in repos/*.yml.
- type: pull_request
parameters:
required_approving_review_count: 1
Expand Down Expand Up @@ -175,8 +150,7 @@ rulesets:

# Ruleset for tag protection — prevent deletion or modification
# of release tags. Protects supply chain integrity by ensuring
# published version tags remain immutable. Replaces the manual
# "tags" ruleset on complypack (id=18348763).
# published version tags remain immutable.
- name: "safe-settings: release tag protection"
target: tag
enforcement: active
Expand Down
2 changes: 1 addition & 1 deletion safe-settings/suborgs/code-repos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# Only override settings here if code repos need different values
# than the org-wide defaults.
#
# Excluded: complyscribe (archived), gemara-content-service (archived)
# Excluded: complyscribe (archived)

suborgrepos:
- complyapi
Expand Down
3 changes: 1 addition & 2 deletions safe-settings/suborgs/non-code-repos.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Suborg: non-code repositories.
# These repos hold community content, demos, releases, and the website.
# They use lighter branch protection: no required signatures, no code
# owner review requirement.
# They use lighter branch protection than code repos.
#
# Org-wide defaults from settings.yml are inherited automatically.
# Only override settings here if non-code repos need different values
Expand Down
Loading