-
Notifications
You must be signed in to change notification settings - Fork 2
Keep scheduled workflows alive #128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 10 commits
f5d404e
1dc3437
6a88054
58da803
5b30f0d
cfa441d
769babd
37588ed
f031123
ba20ecb
34c7b1f
bb3a97c
4dc69d2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,165 @@ | ||||||||
| # Keep Scheduled Workflows Alive | ||||||||
| # | ||||||||
| # Purpose: | ||||||||
| # GitHub automatically disables scheduled workflows after 60 days of repository inactivity. | ||||||||
| # This workflow prevents that by creating minimal activity when needed. | ||||||||
| # | ||||||||
| # How it works: | ||||||||
| # 1. Runs on the first day of every month | ||||||||
| # 2. Checks if the keep-alive PR exists | ||||||||
| # 3. If PR doesn't exist, creates it with a persistent branch | ||||||||
| # 4. Reopens the PR (if closed) and immediately closes it again | ||||||||
| # 5. This activity prevents workflow deactivation | ||||||||
| # | ||||||||
| # Manual trigger: | ||||||||
| # This workflow can also be triggered manually via workflow_dispatch if needed. | ||||||||
| name: Keep Scheduled Workflows Alive | ||||||||
|
|
||||||||
| on: | ||||||||
| schedule: | ||||||||
| - cron: "0 0 1 * *" | ||||||||
| workflow_dispatch: | ||||||||
|
|
||||||||
| permissions: | ||||||||
| contents: write | ||||||||
| pull-requests: write | ||||||||
| issues: read | ||||||||
|
|
||||||||
| jobs: | ||||||||
| keep-alive: | ||||||||
| name: Keep repository GitHub Actions active | ||||||||
| runs-on: ubuntu-latest | ||||||||
| timeout-minutes: 5 | ||||||||
|
|
||||||||
| steps: | ||||||||
| - name: Git checkout | ||||||||
| uses: actions/checkout@v6 | ||||||||
| with: | ||||||||
| persist-credentials: false | ||||||||
|
|
||||||||
| - name: Check for recent activity | ||||||||
| id: check_activity | ||||||||
| env: | ||||||||
| GH_TOKEN: ${{ github.token }} | ||||||||
| shell: bash | ||||||||
| run: | | ||||||||
| # Check if the repository has been active in the last 30 days | ||||||||
| # We check the default branch for recent commits | ||||||||
|
|
||||||||
| DEFAULT_BRANCH="${{ github.event.repository.default_branch }}" | ||||||||
| if [ -z "$DEFAULT_BRANCH" ]; then | ||||||||
| DEFAULT_BRANCH="main" | ||||||||
| fi | ||||||||
|
|
||||||||
| echo "Checking activity on branch: $DEFAULT_BRANCH" | ||||||||
|
|
||||||||
| # Get the date of the last commit on the default branch | ||||||||
| last_commit_date=$(gh api "repos/${{ github.repository }}/commits/$DEFAULT_BRANCH" --jq '.commit.committer.date') | ||||||||
| echo "Last commit date: $last_commit_date" | ||||||||
|
|
||||||||
| # Calculate days since last commit | ||||||||
| last_commit_seconds=$(date -d "$last_commit_date" +%s) | ||||||||
| current_seconds=$(date +%s) | ||||||||
| days_diff=$(( (current_seconds - last_commit_seconds) / 86400 )) | ||||||||
|
|
||||||||
| echo "Days since last activity: $days_diff" | ||||||||
|
Comment on lines
+55
to
+56
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
|
||||||||
| # Threshold: 30 days (Run monthly, so if no activity in last month, we should act) | ||||||||
| if [ "$days_diff" -lt 30 ]; then | ||||||||
| echo "Repository is active enough (less than 30 days since last commit). No keep-alive action needed." | ||||||||
| echo "run_keep_alive=false" >> $GITHUB_OUTPUT | ||||||||
| else | ||||||||
| echo "Repository inactive for $days_diff days. Running keep-alive action." | ||||||||
| echo "run_keep_alive=true" >> $GITHUB_OUTPUT | ||||||||
| fi | ||||||||
|
|
||||||||
| - name: Ensure keep-alive branch and PR exist | ||||||||
| if: steps.check_activity.outputs.run_keep_alive == 'true' | ||||||||
| env: | ||||||||
| GH_TOKEN: ${{ github.token }} | ||||||||
| COMMIT_MSG: | | ||||||||
| chore: keep scheduled workflows alive | ||||||||
|
|
||||||||
| This branch is used by the keep-alive workflow to maintain repository activity. | ||||||||
| GitHub disables scheduled workflows after 60 days of repository inactivity. | ||||||||
| PR_BODY: | | ||||||||
| This automated PR maintains repository activity to prevent scheduled workflows from being disabled. | ||||||||
|
|
||||||||
| 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. | ||||||||
|
|
||||||||
| **Note:** This PR is managed by automation and will be reopened/closed automatically. Do not delete this PR or its branch. | ||||||||
| shell: bash | ||||||||
| run: | | ||||||||
| # Use a fixed branch name for persistence | ||||||||
| branch_name="keep-alive-workflow" | ||||||||
|
|
||||||||
| # Configure git | ||||||||
| git config --local user.name "github-actions[bot]" | ||||||||
| git config --local user.email "github-actions[bot]@users.noreply.github.com" | ||||||||
|
|
||||||||
| # Check if branch exists remotely | ||||||||
| if git ls-remote --heads origin "$branch_name" | grep -q "$branch_name"; then | ||||||||
| echo "Branch $branch_name already exists" | ||||||||
| git fetch origin "$branch_name" | ||||||||
| git checkout "$branch_name" | ||||||||
| git pull origin "$branch_name" | ||||||||
| else | ||||||||
| echo "Creating new branch $branch_name" | ||||||||
| git checkout -b "$branch_name" | ||||||||
| fi | ||||||||
|
|
||||||||
| # Create/Update commit to ensure activity | ||||||||
| git commit --allow-empty -m "$COMMIT_MSG" | ||||||||
| git push origin "$branch_name" | ||||||||
|
|
||||||||
| # Check if PR exists (open or closed) | ||||||||
| pr_number=$(gh pr list --head "$branch_name" --state all --json number --jq '.[0].number' 2>/dev/null || echo "") | ||||||||
|
|
||||||||
| if [ -z "$pr_number" ]; then | ||||||||
| echo "Creating new PR for keep-alive workflow" | ||||||||
| gh pr create \ | ||||||||
bart-vmware marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
| --head "$branch_name" \ | ||||||||
| --base ${{ github.event.repository.default_branch }} \ | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The step above has a fallback to |
||||||||
| --title "chore: keep scheduled workflows alive" \ | ||||||||
| --body "$PR_BODY" | ||||||||
|
|
||||||||
| # Get the newly created PR number | ||||||||
| pr_number=$(gh pr list --head "$branch_name" --state all --json number --jq '.[0].number') | ||||||||
| echo "Created PR #$pr_number" | ||||||||
| else | ||||||||
| echo "PR #$pr_number already exists" | ||||||||
| fi | ||||||||
|
|
||||||||
| # Store PR number for next step | ||||||||
| echo "pr_number=$pr_number" >> $GITHUB_OUTPUT | ||||||||
| id: setup | ||||||||
|
|
||||||||
| - name: Reopen and close PR to maintain activity | ||||||||
bart-vmware marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
| if: steps.check_activity.outputs.run_keep_alive == 'true' | ||||||||
| env: | ||||||||
| GH_TOKEN: ${{ github.token }} | ||||||||
| shell: bash | ||||||||
| run: | | ||||||||
| pr_number="${{ steps.setup.outputs.pr_number }}" | ||||||||
|
|
||||||||
| if [ -z "$pr_number" ]; then | ||||||||
| echo "Error: PR number not found" | ||||||||
| exit 1 | ||||||||
| fi | ||||||||
|
|
||||||||
| # Check PR state | ||||||||
| pr_state=$(gh pr view "$pr_number" --json state --jq '.state') | ||||||||
| echo "PR #$pr_number is currently: $pr_state" | ||||||||
|
|
||||||||
| # Reopen if closed | ||||||||
| if [ "$pr_state" = "CLOSED" ]; then | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm no bash expert, but this looks like an assignment to me. According to https://stackoverflow.com/a/4277753, the typical syntax uses double brackets: if [[ "$pr_state" == "CLOSED" ]] |
||||||||
| echo "Reopening PR #$pr_number" | ||||||||
| gh pr reopen "$pr_number" | ||||||||
| sleep 2 | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need to sleep? |
||||||||
| fi | ||||||||
|
|
||||||||
| # Close the PR with a timestamp comment | ||||||||
| echo "Closing PR #$pr_number" | ||||||||
| gh pr close "$pr_number" --comment "Keep-alive activity: $(date -u '+%Y-%m-%d %H:%M:%S UTC')" | ||||||||
|
|
||||||||
| echo "Keep-alive activity completed successfully" | ||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This and the
PR_BODYbelow don't indicate that an empty commit is being pushed.