Skip to content

Commit 57437c4

Browse files
⚙️ [Maintenance]: Implement PR Supersedence for Font Data Updater (#147)
The font data updater now automatically closes older Auto-Update pull requests when a new update is created, similar to Dependabot's supersedence behavior. This keeps your repository tidy by ensuring only the most recent font data update PR remains open. - Fixes #146 ## PR Supersedence Behavior When the font data updater creates a new Auto-Update PR, it now automatically: 1. Retrieves the newly created PR (with retry logic for API timing) 2. Searches for any existing open `Auto-Update*` PRs 3. Posts a comment on each explaining it has been superseded 4. Closes each superseded PR The comment posted on superseded PRs references the new PR number: ```text This PR has been superseded by #[NEW_PR_NUMBER] and will be closed automatically. The font data has been updated in the newer PR. Please refer to #[NEW_PR_NUMBER] for the most current changes. ``` ## Documentation A new `scripts/README.md` documents: - How the font data updater works - The PR supersedence behavior and lifecycle - Manual execution steps via GitHub Actions - Configuration options - Troubleshooting guidance --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: MariusStorhaug <17722253+MariusStorhaug@users.noreply.github.com> Co-authored-by: Marius Storhaug <marstor@hotmail.com>
1 parent c57ac2f commit 57437c4

2 files changed

Lines changed: 143 additions & 0 deletions

File tree

scripts/README.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Font Data Updater
2+
3+
This directory contains scripts for automating the maintenance of the GoogleFonts module.
4+
5+
## Update-FontsData.ps1
6+
7+
This script automatically updates the `src/FontsData.json` file with the latest font metadata from Google Fonts API.
8+
9+
### Features
10+
11+
- **Automatic Updates**: Runs daily via GitHub Actions to fetch the latest font data
12+
- **PR Supersedence**: Automatically closes older update pull requests when a new update is created
13+
- **Clean Repository**: Ensures only the most recent update PR remains open
14+
15+
### How It Works
16+
17+
1. **Scheduled Execution**: The script runs daily at midnight UTC via the `Update-FontsData` workflow
18+
2. **Data Fetching**: Retrieves the latest font metadata from Google Fonts API
19+
3. **Change Detection**: Compares new data with existing `FontsData.json`
20+
4. **PR Creation**: If changes are detected:
21+
- Creates a new branch named `auto-update-YYYYMMDD-HHmmss`
22+
- Commits the updated `FontsData.json`
23+
- Opens a pull request with title `Auto-Update YYYYMMDD-HHmmss`
24+
5. **PR Supersedence**: After creating a new PR, the script:
25+
- Searches for existing open PRs with titles matching `Auto-Update*` (excluding the newly created PR)
26+
- Closes each superseded PR with a comment referencing the new PR number
27+
- Ensures only the latest update PR remains open
28+
29+
### PR Lifecycle Management
30+
31+
The font data updater implements PR supersedence similar to Dependabot. When a new update PR is created:
32+
33+
- The script first creates the new PR
34+
- Then checks for existing open `Auto-Update*` PRs (excluding the newly created one)
35+
- Each existing PR receives a comment referencing the new PR number:
36+
```text
37+
This PR has been superseded by #[NEW_PR_NUMBER] and will be closed automatically.
38+
39+
The font data has been updated in the newer PR. Please refer to #[NEW_PR_NUMBER] for the most current changes.
40+
```
41+
- All superseded PRs are automatically closed
42+
43+
This means there is no need for a separate cleanup workflow on merge — by the time a PR is merged, it is already the only open Auto-Update PR.
44+
45+
### Workflow
46+
47+
#### Update-FontsData.yml
48+
49+
Handles the scheduled updates, PR creation, and supersedence:
50+
- **Trigger**: Daily at midnight UTC, or manual via `workflow_dispatch`
51+
- **Authentication**: Uses GitHub App credentials for API access
52+
- **Permissions**: Requires secrets:
53+
- `GOOGLE_DEVELOPER_API_KEY`: For accessing Google Fonts API
54+
- `GOOGLEFONTS_UPDATER_BOT_CLIENT_ID`: GitHub App client ID
55+
- `GOOGLEFONTS_UPDATER_BOT_PRIVATE_KEY`: GitHub App private key
56+
57+
### Manual Execution
58+
59+
You can manually trigger an update using the GitHub Actions UI:
60+
61+
1. Go to the **Actions** tab in the repository
62+
2. Select the **Update-FontsData** workflow
63+
3. Click **Run workflow**
64+
4. Select the branch and click **Run workflow**
65+
66+
### Configuration
67+
68+
The supersedence behavior is built into the script and requires no additional configuration. The message posted when closing superseded PRs can be
69+
customized by modifying `scripts/Update-FontsData.ps1`.
70+
71+
### Development
72+
73+
To test changes to the update script:
74+
75+
1. Create a feature branch
76+
2. Modify `scripts/Update-FontsData.ps1`
77+
3. Push the branch
78+
4. Manually trigger the workflow on your feature branch
79+
5. The script will detect it's running on a feature branch and update the existing branch instead of creating a new PR
80+
81+
### Troubleshooting
82+
83+
- **No updates available**: If the Google Fonts API returns the same data, no PR will be created
84+
- **Authentication errors**: Ensure the GitHub App credentials are correctly configured
85+
- **API rate limits**: The Google Fonts API key must have sufficient quota for daily requests

scripts/Update-FontsData.ps1

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,5 +129,63 @@ LogGroup 'Process changes' {
129129
--body 'This PR updates FontsData.json with the latest metadata.'
130130

131131
Write-Output "Changes detected and PR opened for branch: $targetBranch"
132+
133+
# Close any existing open Auto-Update PRs after creating the new one
134+
LogGroup 'Close superseded PRs' {
135+
Write-Output 'Checking for existing open Auto-Update PRs to supersede...'
136+
137+
# Get the newly created PR with retry logic
138+
$newPRJson = $null
139+
$retryCount = 0
140+
$maxRetries = 3
141+
$retryDelays = @(1, 2, 3) # Progressive delays in seconds
142+
while ($null -eq $newPRJson -and $retryCount -lt $maxRetries) {
143+
if ($retryCount -gt 0) {
144+
Start-Sleep -Seconds $retryDelays[$retryCount - 1]
145+
}
146+
$newPRJson = Run gh pr list --repo 'PSModule/GoogleFonts' --head $targetBranch --state open --json number, title --limit 1
147+
$newPR = $newPRJson | ConvertFrom-Json | Select-Object -First 1
148+
if ($null -eq $newPR -or $null -eq $newPR.number) {
149+
$newPR = $null
150+
$newPRJson = $null
151+
}
152+
$retryCount++
153+
if ($null -eq $newPR -and $retryCount -lt $maxRetries) {
154+
Write-Output "PR not found yet, retrying in $($retryDelays[$retryCount - 1]) seconds... (attempt $retryCount/$maxRetries)"
155+
}
156+
}
157+
158+
if ($null -ne $newPR) {
159+
Write-Output "Found new PR #$($newPR.number): $($newPR.title)"
160+
161+
# Find existing open Auto-Update PRs (excluding the one we just created)
162+
$existingPRsJson = Run gh pr list --repo 'PSModule/GoogleFonts' --state open --search 'Auto-Update in:title' --json number, title
163+
$existingPRs = $existingPRsJson | ConvertFrom-Json | Where-Object { $_.number -ne $newPR.number }
164+
165+
if ($existingPRs) {
166+
Write-Output "Found $(@($existingPRs).Count) existing Auto-Update PR(s) to close."
167+
foreach ($pr in $existingPRs) {
168+
Write-Output "Closing PR #$($pr.number): $($pr.title)"
169+
170+
# Add a comment explaining the supersedence
171+
$comment = @"
172+
This PR has been superseded by #$($newPR.number) and will be closed automatically.
173+
174+
The font data has been updated in the newer PR. Please refer to #$($newPR.number) for the most current changes.
175+
"@
176+
Run gh pr comment $pr.number --repo 'PSModule/GoogleFonts' --body $comment
177+
178+
# Close the PR
179+
Run h pr close $pr.number --repo 'PSModule/GoogleFonts'
180+
181+
Write-Output "Successfully closed PR #$($pr.number)"
182+
}
183+
} else {
184+
Write-Output 'No existing open Auto-Update PRs to close.'
185+
}
186+
} else {
187+
Write-Warning "Could not retrieve the newly created PR after $maxRetries attempts. Skipping supersedence logic."
188+
}
189+
}
132190
}
133191
}

0 commit comments

Comments
 (0)