Skip to content
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

devsecops/emvaldes/workflow-housekeeper #17025

Merged
merged 4 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/actions/workflow-housekeeper/.gitignore
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will have this file manually removed as it has no direct value but it's important to preserve it if it's already defined in the imported GitHub Action.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.git
_git
.github
_github
55 changes: 55 additions & 0 deletions .github/actions/workflow-housekeeper/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Workflow Housekeeper

Retain a time period or quantity of workflow runs.

[![Test action](https://github.com/CDCgov/prime-reportstream/.github/workflows/workflow-housekeeper--test_action.yml/badge.svg)](https://github.com/CDCgov/prime-reportstream/.github/workflows/workflow-housekeeper--test_action.yml)

### Dependencies:

>Change in repo: `Settings -> Actions -> General -> Workflow Permissions to allow read and write`

## Inputs
```yml
ignore-branch-workflows:
description: 'Ignore runs from workflows currently in ./github/workflow'
required: false
retention-time:
description: 'Period of time to maintain history. E.g. "2 weeks", "3 days", etc.'
required: false
retain-run-count:
description: 'Number of latest runs to keep'
required: false
dry-run:
description: 'Only list runs pending deletion'
required: false
```

## Usage
```yml
- name: Checkout
uses: actions/checkout@v3
- name: Run workflow housekeeper
uses: josiahsiegel/workflow-housekeeper@<CURRENT_VERSION>
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```
or
```yml
- name: Checkout
uses: actions/checkout@v3
- name: Run workflow housekeeper
uses: josiahsiegel/workflow-housekeeper@<CURRENT_VERSION>
id: scan
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
ignore-branch-workflows: true
retention-time: '1 days'
retain-run-count: 1
dry-run: false
```

## Generated summary
### ✨ Workflow Housekeeper ✨
* .github/workflows/test_action.yml 4618840926
* .github/workflows/test_action.yml 4618827035
41 changes: 41 additions & 0 deletions .github/actions/workflow-housekeeper/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# action.yml
name: 'Workflow Housekeeper'
description: 'Retain a time period or quantity of workflow runs.'
branding:
icon: 'trash-2'
color: 'red'
inputs:
ignore-branch-workflows:
description: 'Ignore runs from workflows currently in ./github/workflow'
required: false
retention-time:
description: 'Period of time to maintain history. E.g. "2 weeks", "3 days", etc.'
required: false
retain-run-count:
description: 'Number of latest runs to keep'
required: false
dry-run:
description: 'Only list runs pending deletion'
required: false
outputs:
housekeeping_output:
description: 'Output of housekeeping steps'
value: ${{ steps.local-action.outputs.housekeeping_output }}
runs:
using: "composite"
steps:
- name: Run local action
id: local-action
run: |
${{ github.action_path }}/lib/housekeeper.sh \
"${{ github.repository }}" \
"${{ inputs.ignore-branch-workflows }}" \
"${{ inputs.retention-time }}" \
"${{ inputs.retain-run-count }}" \
"${{ inputs.dry-run }}"
shell: bash
- name: Create summary
run: |
echo "### :sparkles: Workflow Housekeeper :sparkles:" >> $GITHUB_STEP_SUMMARY
echo -e "${{ steps.local-action.outputs.housekeeping_output }}" >> $GITHUB_STEP_SUMMARY
shell: bash
72 changes: 72 additions & 0 deletions .github/actions/workflow-housekeeper/lib/housekeeper.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/bin/bash

# Init
repo="$1"
ignore_branch_workflows=$2
retention_time=$3
retain_run_count=$4
dry_run=$5

# ignore_branch_workflows
if [[ -z $ignore_branch_workflows ]]; then
ignore_branch_workflows=false
fi
echo "ignore_branch_workflows: $ignore_branch_workflows"

if [[ $ignore_branch_workflows = true ]]; then
files=$(ls -1 .github/workflows/ | sed 's/^/and .path != \".github\/workflows\//;s/$/\"/')
else
files=""
fi

# retention_time
if [[ -z $retention_time ]]; then
retention_time=""
else
keep_date=$(date -d "$date -$retention_time" +%s)
keep_stmt="| select (.run_started_at | . == null or fromdateiso8601 < $keep_date)"
fi
echo "time_threshold: $retention_time"

# retain_run_count
if [[ -z $retain_run_count ]]; then
retain_run_count=0
fi
let retain_run_count2=retain_run_count*2
echo "retain_run_count: $retain_run_count2"

# dry_run
if [[ -z $dry_run ]]; then
dry_run=false
fi
echo "dry_run: $dry_run"

# Build jq query
runs="repos/$repo/actions/runs"
query=".workflow_runs[] \
| select( \
.path != \".github/workflows/placeholder.yaml\" \
"$files"
)
$keep_stmt
| (.path,.id)"

# Get run ids
output=$(gh api --paginate $runs --jq "$query")
output=($(echo $output | tr " " "\n"))
output=${output[@]:$retain_run_count2}

# Delete or echo run ids
for id in $output; do
if [[ $dry_run = false ]]; then
[[ $id != ".git"* ]] && gh api --silent $runs/$id -X DELETE
else
[[ $id != ".git"* ]] && echo "gh api --silent $runs/$id -X DELETE" || echo "$id"
fi
[[ $id = ".git"* ]] && summary+=" * $id" || summary+=" $id\n"

# Prevent rate limit
sleep 1;
done

echo "housekeeping_output=$(echo "${summary}")" >>$GITHUB_OUTPUT
Loading