Skip to content

Commit cfa441d

Browse files
CopilotTimHess
andcommitted
Simplify keep-alive workflow to reuse same PR every ~59 days
Co-authored-by: TimHess <3947063+TimHess@users.noreply.github.com>
1 parent 5b30f0d commit cfa441d

File tree

1 file changed

+72
-80
lines changed

1 file changed

+72
-80
lines changed

.github/workflows/keep-alive.yml

Lines changed: 72 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@
55
# This workflow prevents that by creating minimal activity when needed.
66
#
77
# How it works:
8-
# 1. Runs monthly on the 1st of each month
9-
# 2. Checks for any commits, issues, or PRs in the last 50 days
10-
# 3. If no activity is found:
11-
# - Creates a temporary branch with an empty commit
12-
# - Opens a pull request
13-
# - Immediately closes the PR
14-
# - Deletes the temporary branch
15-
# 4. If recent activity exists, does nothing
8+
# 1. Runs every 59 days (using approximation via cron)
9+
# 2. Checks if the keep-alive PR exists
10+
# 3. If PR doesn't exist, creates it with a persistent branch
11+
# 4. Reopens the PR (if closed) and immediately closes it again
12+
# 5. This activity prevents workflow deactivation
13+
#
14+
# Benefits:
15+
# - Uses the same PR repeatedly (minimal noise)
16+
# - No human intervention required
17+
# - Runs every ~59 days (close to 60-day limit but safe)
1618
#
1719
# Manual trigger:
1820
# This workflow can also be triggered manually via workflow_dispatch if needed.
@@ -23,10 +25,9 @@ name: Keep Scheduled Workflows Alive
2325

2426
on:
2527
schedule:
26-
# Run on the 1st of each month (checks for activity in the last 50 days before taking action)
27-
# This conservative frequency ensures we never hit the 60-day GitHub inactivity limit
28-
# even accounting for holidays, weekends, or workflow execution delays
29-
- cron: "0 0 1 * *"
28+
# Run every 59 days (approximate using twice per 4 months = ~60 days)
29+
# This is close to GitHub's 60-day limit but provides a safety margin
30+
- cron: "0 0 1 */2 *"
3031
workflow_dispatch:
3132

3233
permissions:
@@ -44,91 +45,82 @@ jobs:
4445
- name: Git checkout
4546
uses: actions/checkout@v4
4647

47-
- name: Check for recent activity
48-
id: check_activity
48+
- name: Ensure keep-alive branch and PR exist
4949
env:
5050
GH_TOKEN: ${{ github.token }}
5151
shell: bash
5252
run: |
53-
# Check for any activity in the last 50 days
54-
# Note: date -d is GNU-specific, but this workflow runs on ubuntu-latest which has GNU date
55-
cutoff_date=$(date -u -d '50 days ago' '+%Y-%m-%dT%H:%M:%SZ')
56-
echo "Checking for activity since: $cutoff_date"
53+
# Use a fixed branch name for persistence
54+
branch_name="keep-alive-workflow"
5755
58-
# Check for recent commits
59-
recent_commits=$(gh api \
60-
-H "Accept: application/vnd.github+json" \
61-
-H "X-GitHub-Api-Version: 2022-11-28" \
62-
"/repos/${{ github.repository }}/commits?since=$cutoff_date&per_page=1" \
63-
--jq 'length' 2>/dev/null || echo "0")
56+
# Configure git
57+
git config --local user.name "github-actions[bot]"
58+
git config --local user.email "github-actions[bot]@users.noreply.github.com"
6459
65-
# Check for recent issues/PRs
66-
recent_issues=$(gh api \
67-
-H "Accept: application/vnd.github+json" \
68-
-H "X-GitHub-Api-Version: 2022-11-28" \
69-
"/repos/${{ github.repository }}/issues?since=$cutoff_date&per_page=1&state=all" \
70-
--jq 'length' 2>/dev/null || echo "0")
60+
# Check if branch exists remotely
61+
if git ls-remote --heads origin "$branch_name" | grep -q "$branch_name"; then
62+
echo "Branch $branch_name already exists"
63+
else
64+
echo "Creating new branch $branch_name"
65+
git checkout -b "$branch_name"
66+
git commit --allow-empty -m "chore: keep scheduled workflows alive
67+
68+
This branch is used by the keep-alive workflow to maintain repository activity.
69+
GitHub disables scheduled workflows after 60 days of repository inactivity."
70+
git push --set-upstream origin "$branch_name"
71+
fi
7172

72-
echo "Recent commits: $recent_commits"
73-
echo "Recent issues/PRs: $recent_issues"
73+
# Check if PR exists (open or closed)
74+
pr_number=$(gh pr list --head "$branch_name" --state all --json number --jq '.[0].number' 2>/dev/null || echo "")
7475

75-
if [ "$recent_commits" -gt 0 ] || [ "$recent_issues" -gt 0 ]; then
76-
echo "Recent activity detected. No action needed."
77-
echo "needs_activity=false" >> $GITHUB_OUTPUT
76+
if [ -z "$pr_number" ]; then
77+
echo "Creating new PR for keep-alive workflow"
78+
gh pr create \
79+
--head "$branch_name" \
80+
--base ${{ github.event.repository.default_branch }} \
81+
--title "chore: keep scheduled workflows alive" \
82+
--body "This automated PR maintains repository activity to prevent scheduled workflows from being disabled.
83+
84+
GitHub automatically disables scheduled workflows after 60 days of repository inactivity. This PR is reopened and closed periodically by the keep-alive workflow to ensure continuous operation.
85+
86+
**Note:** This PR is managed by automation and will be reopened/closed automatically. Do not delete this PR or its branch."
87+
88+
# Get the newly created PR number
89+
pr_number=$(gh pr list --head "$branch_name" --state all --json number --jq '.[0].number')
90+
echo "Created PR #$pr_number"
7891
else
79-
echo "No recent activity. Will create keep-alive activity."
80-
echo "needs_activity=true" >> $GITHUB_OUTPUT
92+
echo "PR #$pr_number already exists"
8193
fi
94+
95+
# Store PR number for next step
96+
echo "pr_number=$pr_number" >> $GITHUB_OUTPUT
97+
id: setup
8298

83-
- name: Create and close PR to maintain activity
84-
if: steps.check_activity.outputs.needs_activity == 'true'
99+
- name: Reopen and close PR to maintain activity
85100
env:
86101
GH_TOKEN: ${{ github.token }}
87102
shell: bash
88103
run: |
89-
# Configure git
90-
git config --local user.name "github-actions[bot]"
91-
git config --local user.email "github-actions[bot]@users.noreply.github.com"
104+
pr_number="${{ steps.setup.outputs.pr_number }}"
92105
93-
# Create a unique branch name
94-
branch_name="keep-alive-$(date +%Y%m%d-%H%M%S)"
95-
96-
# Create a new branch and make an empty commit
97-
git checkout -b "$branch_name"
98-
git commit --allow-empty -m "chore: keep scheduled workflows alive
99-
100-
This automated commit ensures scheduled workflows remain active.
101-
GitHub disables scheduled workflows after 60 days of repository inactivity."
106+
if [ -z "$pr_number" ]; then
107+
echo "Error: PR number not found"
108+
exit 1
109+
fi
102110
103-
git push --set-upstream origin "$branch_name"
111+
# Check PR state
112+
pr_state=$(gh pr view "$pr_number" --json state --jq '.state')
113+
echo "PR #$pr_number is currently: $pr_state"
104114
105-
# Create PR
106-
pr_url=$(gh pr create \
107-
--head "$branch_name" \
108-
--base ${{ github.event.repository.default_branch }} \
109-
--title "chore: keep scheduled workflows alive" \
110-
--body "This automated PR is created to prevent scheduled workflows from being disabled due to inactivity.
111-
112-
GitHub automatically disables scheduled workflows when no repository activity has occurred in 60 days. This PR ensures continuous operation of our scheduled builds and tests.
113-
114-
This PR contains an empty commit and will be automatically closed without merging.")
115-
116-
echo "Created PR: $pr_url"
115+
# Reopen if closed
116+
if [ "$pr_state" = "CLOSED" ]; then
117+
echo "Reopening PR #$pr_number"
118+
gh pr reopen "$pr_number"
119+
sleep 2
120+
fi
117121
118-
# Extract PR number from URL (require at least one digit)
119-
pr_number=$(echo "$pr_url" | grep -oE '[0-9]+$')
122+
# Close the PR with a timestamp comment
123+
echo "Closing PR #$pr_number"
124+
gh pr close "$pr_number" --comment "Keep-alive activity: $(date -u '+%Y-%m-%d %H:%M:%S UTC')"
120125
121-
if [ -n "$pr_number" ]; then
122-
# Close the PR immediately
123-
gh pr close "$pr_number" --comment "Closing this keep-alive PR as its purpose (maintaining repository activity) has been fulfilled."
124-
echo "Closed PR #$pr_number"
125-
126-
# Clean up the branch
127-
git push origin --delete "$branch_name"
128-
echo "Deleted branch: $branch_name"
129-
else
130-
echo "Warning: Could not extract PR number from URL: $pr_url"
131-
echo "The branch $branch_name was created but PR may not have been properly closed."
132-
echo "Attempting to clean up branch anyway..."
133-
git push origin --delete "$branch_name" 2>/dev/null || echo "Branch cleanup failed, may need manual cleanup"
134-
fi
126+
echo "Keep-alive activity completed successfully"

0 commit comments

Comments
 (0)