Skip to content

Commit fde7ebd

Browse files
CopilotTimHessbart-vmware
authored
Keep scheduled workflows alive (#128)
* Initial plan * Add keep-alive workflow to prevent scheduled workflow deactivation Co-authored-by: TimHess <3947063+TimHess@users.noreply.github.com> * Add error handling to keep-alive workflow Co-authored-by: TimHess <3947063+TimHess@users.noreply.github.com> * Address code review feedback: improve regex, branch handling, and documentation Co-authored-by: TimHess <3947063+TimHess@users.noreply.github.com> * Add comprehensive documentation to keep-alive workflow Co-authored-by: TimHess <3947063+TimHess@users.noreply.github.com> * Simplify keep-alive workflow to reuse same PR every ~59 days Co-authored-by: TimHess <3947063+TimHess@users.noreply.github.com> * run keep-alive every month - bump a couple other action refs - whitespace cleanup * move commit message and pr body to env vars for easier formatting * add step to check for activity in the last 30 days to reduce noise * Clarify why workflow runs every 30 days instead of 60 Co-authored-by: TimHess <3947063+TimHess@users.noreply.github.com> * Reduce verbosity, add draft PR flag, and document empty commits Co-authored-by: TimHess <3947063+TimHess@users.noreply.github.com> * further comment cleanup * Update .github/workflows/keep-alive.yml Co-authored-by: Bart Koelman <104792814+bart-vmware@users.noreply.github.com> * pr feedback & polish - shell vars all lowercase_with_underscores, env vars UPPER_SNAKE - consistent conditional formatting - consistent fallback for branch - reduce verbosity --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: TimHess <3947063+TimHess@users.noreply.github.com> Co-authored-by: Tim Hess <tim.hess@broadcom.com> Co-authored-by: Bart Koelman <104792814+bart-vmware@users.noreply.github.com>
1 parent 84d3ec9 commit fde7ebd

2 files changed

Lines changed: 131 additions & 3 deletions

File tree

.github/workflows/build.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ jobs:
4646
10.0.*
4747
4848
- name: Git checkout
49-
uses: actions/checkout@v4
49+
uses: actions/checkout@v6
50+
with:
51+
persist-credentials: false
5052

5153
- name: Restore packages
5254
run: dotnet restore --verbosity minimal
@@ -204,7 +206,7 @@ jobs:
204206
path: packages
205207

206208
- name: Setup .NET
207-
uses: actions/setup-dotnet@v4
209+
uses: actions/setup-dotnet@v5
208210
with:
209211
dotnet-version: 10.0.x
210212
source-url: ${{ vars.AZURE_ARTIFACTS_FEED_URL }}
@@ -235,7 +237,7 @@ jobs:
235237

236238
steps:
237239
- name: Setup .NET
238-
uses: actions/setup-dotnet@v4
240+
uses: actions/setup-dotnet@v5
239241
with:
240242
dotnet-version: 10.0.x
241243

.github/workflows/keep-alive.yml

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Prevents scheduled workflows from being disabled by GitHub after 60 days of repository inactivity.
2+
name: Keep Scheduled Workflows Alive
3+
4+
on:
5+
schedule:
6+
- cron: "0 0 1 * *"
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: write
11+
pull-requests: write
12+
issues: read
13+
14+
jobs:
15+
keep-alive:
16+
name: Keep repository GitHub Actions active
17+
runs-on: ubuntu-latest
18+
timeout-minutes: 5
19+
20+
steps:
21+
- name: Git checkout
22+
uses: actions/checkout@v6
23+
with:
24+
persist-credentials: false
25+
26+
- name: Check for recent activity
27+
id: check_activity
28+
env:
29+
GH_TOKEN: ${{ github.token }}
30+
shell: bash
31+
run: |
32+
default_branch="${{ github.event.repository.default_branch }}"
33+
if [ -z "$default_branch" ]; then
34+
default_branch="main"
35+
fi
36+
37+
echo "Checking activity on branch: $default_branch"
38+
last_commit_date=$(gh api "repos/${{ github.repository }}/commits/$default_branch" --jq '.commit.committer.date')
39+
echo "Last commit date: $last_commit_date"
40+
41+
last_commit_seconds=$(date -d "$last_commit_date" +%s)
42+
current_seconds=$(date +%s)
43+
days_diff=$(( (current_seconds - last_commit_seconds) / 86400 ))
44+
echo "Days since last activity: $days_diff"
45+
46+
if [ "$days_diff" -lt 30 ]; then
47+
echo "Active (< 30 days). No keep-alive needed."
48+
echo "run_keep_alive=false" >> $GITHUB_OUTPUT
49+
else
50+
echo "Inactive ($days_diff days). Running keep-alive."
51+
echo "run_keep_alive=true" >> $GITHUB_OUTPUT
52+
fi
53+
54+
- name: Ensure keep-alive branch and PR exist
55+
if: ${{ steps.check_activity.outputs.run_keep_alive == 'true' }}
56+
env:
57+
GH_TOKEN: ${{ github.token }}
58+
COMMIT_MSG: |
59+
chore: keep scheduled workflows alive
60+
PR_BODY: |
61+
Draft PR maintained by the keep-alive workflow. Do not merge or delete.
62+
shell: bash
63+
run: |
64+
branch_name="keep-alive-workflow"
65+
default_branch="${{ github.event.repository.default_branch }}"
66+
if [ -z "$default_branch" ]; then
67+
default_branch="main"
68+
fi
69+
70+
git config --local user.name "github-actions[bot]"
71+
git config --local user.email "github-actions[bot]@users.noreply.github.com"
72+
73+
if git ls-remote --heads origin "$branch_name" | grep -q "$branch_name"; then
74+
echo "Branch exists"
75+
git fetch origin "$branch_name"
76+
git checkout "$branch_name"
77+
git pull origin "$branch_name"
78+
else
79+
echo "Creating branch"
80+
git checkout -b "$branch_name"
81+
fi
82+
83+
git commit --allow-empty -m "$COMMIT_MSG"
84+
git push origin "$branch_name"
85+
86+
pr_number=$(gh pr list --head "$branch_name" --state all --json number --jq '.[0].number' 2>/dev/null || echo "")
87+
88+
if [ -z "$pr_number" ]; then
89+
echo "Creating draft PR"
90+
gh pr create --draft --head "$branch_name" --base "$default_branch" \
91+
--title "chore: keep scheduled workflows alive" --body "$PR_BODY"
92+
93+
pr_number=$(gh pr list --head "$branch_name" --state all --json number --jq '.[0].number')
94+
echo "Created PR #$pr_number"
95+
else
96+
echo "PR #$pr_number exists"
97+
fi
98+
99+
echo "pr_number=$pr_number" >> $GITHUB_OUTPUT
100+
id: setup
101+
102+
- name: Reopen and close PR to maintain activity
103+
if: ${{ steps.check_activity.outputs.run_keep_alive == 'true' }}
104+
env:
105+
GH_TOKEN: ${{ github.token }}
106+
shell: bash
107+
run: |
108+
pr_number="${{ steps.setup.outputs.pr_number }}"
109+
110+
if [ -z "$pr_number" ]; then
111+
echo "Error: PR number not found"
112+
exit 1
113+
fi
114+
115+
pr_state=$(gh pr view "$pr_number" --json state --jq '.state')
116+
echo "PR #$pr_number is $pr_state"
117+
118+
if [[ "$pr_state" == "CLOSED" ]]; then
119+
echo "Reopening PR #$pr_number"
120+
gh pr reopen "$pr_number"
121+
fi
122+
123+
echo "Closing PR #$pr_number"
124+
gh pr close "$pr_number" --comment "Keep-alive: $(date -u '+%Y-%m-%d %H:%M:%S UTC')"
125+
126+
echo "Keep-alive completed"

0 commit comments

Comments
 (0)