|
1 | | -# oncall |
| 1 | +# Oncall Rotation System |
| 2 | + |
| 3 | +Automated oncall rotation management system that syncs the current oncall schedule to a Google Group. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +This repository contains: |
| 8 | +- **`dev.oncall`**: Oncall rotation schedule (CSV format) |
| 9 | +- **`synconcall/`**: Go CLI tool that syncs current rotation to Google Group |
| 10 | +- **GitHub Actions**: Automated daily sync workflow |
| 11 | + |
| 12 | +## Quick Start |
| 13 | + |
| 14 | +### Schedule File Format |
| 15 | + |
| 16 | +Edit `dev.oncall` to define your rotation schedule: |
| 17 | + |
| 18 | +```csv |
| 19 | +2026-01-12T00:00:00Z,d@bytebase.com,vh@bytebase.com |
| 20 | +2026-02-09T00:00:00Z,vh@bytebase.com,xz@bytebase.com |
| 21 | +2026-03-09T00:00:00Z,xz@bytebase.com,zp@bytebase.com |
| 22 | +``` |
| 23 | + |
| 24 | +Each line: `start_time,primary_email,secondary_email` |
| 25 | +- Timestamps in RFC3339 format (ISO 8601) |
| 26 | +- Rotations in chronological order |
| 27 | +- Each rotation period starts at the specified timestamp |
| 28 | + |
| 29 | +### How It Works |
| 30 | + |
| 31 | +1. GitHub Actions runs daily (configurable) |
| 32 | +2. Reads `dev.oncall` to determine current rotation |
| 33 | +3. Syncs Google Group membership to match current primary + secondary |
| 34 | +4. Old oncall members are removed, current ones are added |
| 35 | + |
| 36 | +The sync is **declarative** - the group always reflects exactly who is currently oncall. |
| 37 | + |
| 38 | +## Setup |
| 39 | + |
| 40 | +**Service Account:** `dev-tools@bytebase-dev.iam.gserviceaccount.com` |
| 41 | + |
| 42 | +### 1. Create Service Account |
| 43 | + |
| 44 | +1. Go to [Google Cloud Console](https://console.cloud.google.com/) |
| 45 | +2. Create a service account |
| 46 | +3. Download JSON key file |
| 47 | +4. Enable domain-wide delegation |
| 48 | + |
| 49 | +### 2. Grant API Permissions |
| 50 | + |
| 51 | +In Google Workspace Admin Console: |
| 52 | +1. Go to Security > API Controls > Domain-wide Delegation |
| 53 | +2. Add the service account client ID |
| 54 | +3. Grant OAuth scopes (comma-separated): |
| 55 | + - `https://www.googleapis.com/auth/admin.directory.group,https://www.googleapis.com/auth/admin.directory.group.member` |
| 56 | + |
| 57 | +**Note:** The service account uses domain-wide delegation to impersonate a domain admin user (`d@bytebase.com`) to access the Admin SDK. |
| 58 | + |
| 59 | +### 3. Configure GitHub Secrets |
| 60 | + |
| 61 | +Add repository secret: |
| 62 | +- Name: `GOOGLE_SERVICE_ACCOUNT` |
| 63 | +- Value: Contents of the service account JSON key file |
| 64 | + |
| 65 | +### 4. Customize Workflow |
| 66 | + |
| 67 | +Edit `.github/workflows/sync-oncall.yml`: |
| 68 | +- Change cron schedule (default: daily at midnight UTC) |
| 69 | +- Update group email if different from `dev-oncall@bytebase.com` |
| 70 | + |
| 71 | +## Manual Sync |
| 72 | + |
| 73 | +Build and run locally: |
| 74 | + |
| 75 | +```bash |
| 76 | +cd synconcall |
| 77 | +go build -o synconcall |
| 78 | + |
| 79 | +GOOGLE_CREDENTIALS="$(cat /path/to/service-account.json)" \ |
| 80 | + ./synconcall --config=../dev.oncall --group=dev-oncall@bytebase.com --admin-user=d@bytebase.com |
| 81 | +``` |
| 82 | + |
| 83 | +## Updating the Schedule |
| 84 | + |
| 85 | +1. Edit `dev.oncall` to add new rotation periods |
| 86 | +2. Commit and push changes |
| 87 | +3. Next scheduled run will pick up the changes |
| 88 | +4. Or trigger manually: Actions tab → "Sync Oncall to Google Group" → Run workflow |
| 89 | + |
| 90 | +## Project Structure |
| 91 | + |
| 92 | +``` |
| 93 | +oncall/ |
| 94 | +├── dev.oncall # Rotation schedule |
| 95 | +├── synconcall/ # Sync tool |
| 96 | +│ ├── main.go # CLI entry point |
| 97 | +│ ├── schedule.go # Schedule parsing |
| 98 | +│ ├── groups.go # Google API client |
| 99 | +│ ├── sync.go # Sync logic |
| 100 | +│ ├── *_test.go # Comprehensive tests |
| 101 | +│ └── README.md # Tool documentation |
| 102 | +├── .github/workflows/ |
| 103 | +│ └── sync-oncall.yml # Automated sync workflow |
| 104 | +└── docs/plans/ |
| 105 | + └── 2026-01-23-oncall-sync-design.md # Design document |
| 106 | +``` |
| 107 | + |
| 108 | +## Testing |
| 109 | + |
| 110 | +Run tests: |
| 111 | +```bash |
| 112 | +cd synconcall |
| 113 | +go test -v |
| 114 | +``` |
| 115 | + |
| 116 | +## Troubleshooting |
| 117 | + |
| 118 | +### Sync fails with authentication error |
| 119 | +- Check service account has domain-wide delegation enabled |
| 120 | +- Verify OAuth scopes are granted correctly |
| 121 | +- Ensure JSON key is valid in GitHub secrets |
| 122 | + |
| 123 | +### Members not updating |
| 124 | +- Check schedule file format (timestamps, emails) |
| 125 | +- Verify current time falls within a rotation period |
| 126 | +- Check GitHub Actions logs for errors |
| 127 | + |
| 128 | +### Wrong people in group |
| 129 | +- Verify `dev.oncall` has correct rotation schedule |
| 130 | +- Check timestamps are in chronological order |
| 131 | +- Ensure timestamps use RFC3339 format with timezone |
| 132 | + |
| 133 | +## Design Documentation |
| 134 | + |
| 135 | +See [docs/plans/2026-01-23-oncall-sync-design.md](docs/plans/2026-01-23-oncall-sync-design.md) for detailed design decisions and architecture. |
0 commit comments