Skip to content

Commit

Permalink
change action to clean workflows
Browse files Browse the repository at this point in the history
  • Loading branch information
bodsch committed Aug 19, 2024
1 parent 3a20c99 commit 61bc214
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 74 deletions.
36 changes: 30 additions & 6 deletions .github/workflows/clean-workflows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ name: delete workflow runs

on:
schedule:
- cron: "10 4 * * 0"
- cron: "20 4 * * 0"
workflow_dispatch:
inputs:
logLevel:
Expand All @@ -16,16 +16,40 @@ on:
- info
- warning
- debug
minimum_kept:
description: 'Minimum number per workflow to be kept.'
required: true
default: 2

jobs:

delete-workflow-runs:
runs-on: ubuntu-latest
name: delete old workflow runs
permissions:
actions: write
contents: read
steps:
- name: Delete workflow runs
uses: MajorScruffy/delete-old-workflow-runs@v0.3.0
- name: Check out the codebase.
uses: actions/checkout@v4
with:
ref: ${{ github.event.workflow_run.head_branch }}

- name: 🐍 set up python
uses: actions/setup-python@v5
with:
repository: bodsch/ansible-urbanterror
older-than-seconds: 2592000 # remove all workflow runs older than 30 day
python-version: "3.12"

- name: install dependencies
run: |
python -m pip install --upgrade pip
pip install requests
- name: clean workflow
run: |
make \
gh-clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_TOKEN: ${{ github.token }}
GH_KEEP_WORKFLOWS: ${{ github.event.inputs.minimum_kept }}
2 changes: 1 addition & 1 deletion .github/workflows/galaxy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- name: Check out the codebase
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
path: 'ansible-urbanterror'

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: 🛎 Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: lint
uses: docker://ghcr.io/github/super-linter:slim-v4
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ jobs:

steps:
- name: check out the codebase.
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
path: 'ansible-urbanterror'
ref: ${{ github.event.workflow_run.head_branch }}

- name: 🐍 set up python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "${{ matrix.python_version }}"

Expand Down
68 changes: 4 additions & 64 deletions hooks/gh-clean
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -5,68 +5,8 @@ set -e
org=bodsch
repo=$(basename $(git rev-parse --show-toplevel))

keep_first_two() {
local arr=("$@") # Das Array wird als Argument übergeben
local new_arr=("${arr[@]:0:2}") # Die ersten beiden Elemente werden beibehalten
echo "${new_arr[@]}" # Das neue Array wird ausgegeben
}
export GH_REPOSITORY="${repo}"
export GH_USERNAME="${org:-bodsch}"
export GH_KEEP_WORKFLOWS="${GH_KEEP_WORKFLOWS:-2}"

remove_elements() {
local arr=("$@")
local result=()
local length=${#arr[@]}

# Check whether the array has more than two elements
if [ $length -le 2 ]
then
return
fi

# Keep the first two elements
for ((i=2; i<length; i++))
do
result+=("${arr[i]}") # Collect removed elements
done

echo "${result[@]}"
}


if [ -n "${org}" ] && [ -n "${repo}" ]
then

# Get workflow IDs with status "active"
workflow_ids=($(gh api repos/$org/$repo/actions/workflows --paginate | jq '.workflows[] | select(.["state"] | contains("active")) | .id'))

for workflow_id in "${workflow_ids[@]}"
do
echo "Listing runs for the workflow ID $workflow_id"
run_ids=( $(gh api repos/$org/$repo/actions/workflows/$workflow_id/runs --paginate | jq '.workflow_runs[].id') )

# echo "${run_ids[@]}"

# count array
count_ids=${#run_ids[@]}
# echo " - ${count_ids} entries"

if [ ${count_ids} -gt 2 ]
then
# remove the first two elements of the list
array=$(remove_elements "${run_ids[@]}")

for run_id in ${array}
do
echo "Deleting Run ID $run_id"
gh api repos/$org/$repo/actions/runs/$run_id -X DELETE >/dev/null
done

echo "-------------------------------------------------"
fi
done
else
echo "missing values:"
echo " - org : '${org}'"
echo " - repo: '${repo}'"

exit 1
fi
python hooks/gh-clean.py
156 changes: 156 additions & 0 deletions hooks/gh-clean.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
#!/bin/python

import os
import sys
import requests
# import json


class GitHub:

def __init__(self):
""" """
self.github_access_token = os.environ.get('GH_TOKEN', None)
self.github_repository = os.environ.get('GH_REPOSITORY', None)
self.github_username = os.environ.get('GH_USERNAME', None)
self.github_keep_workflows = os.environ.get('GH_KEEP_WORKFLOWS', 2)

self.github_base_url = "https://api.github.com"

if not self.github_access_token:
print("missing environment variable 'GH_TOKEN'")
sys.exit(1)

if not self.github_repository:
print("missing environment variable 'GH_REPOSITORY'")
sys.exit(1)

if not self.github_username:
print("missing environment variable 'GH_USERNAME'")
sys.exit(1)

self.headers = {
"Authorization": f"token {self.github_access_token}",
}

def header(self):
""" """
print("")
print(f"Delete old workflows for the repository {self.github_repository}")
print(f" {self.github_keep_workflows} log files are kept.")
print("")

def get_user_repos(self, username):
url = f"{self.github_base_url}/users/{self.github_username}/repos"

query_params = {
"sort": "updated",
"per_page": 5
}

response = requests.get(url, params=query_params)

if response.status_code == 200:
repositories_data = response.json()
return repositories_data
else:
return None

def create_repo(self, repo_name, repo_descr=None):
url = f"{self.github_base_url}/user/repos"

# create json data to send using the post request
data = {
"name": repo_name,
"description": repo_descr,
}

response = requests.post(url, headers=self.headers, json=data)

if response.status_code == 201:
repo_data = response.json()
return repo_data
else:
return None

def list_defined_workflows(self):
url = f"{self.github_base_url}/repos/{self.github_username}/{self.github_repository}/actions/workflows"

response = requests.get(url, headers=self.headers)

if response.status_code == 200:
repositories_data = response.json()
return repositories_data
else:
return None

def active_workflows(self, workflows):
""" """
return [x for x in workflows.get("workflows", []) if x.get("state", None) in ["active", "disabled_inactivity", "skipped"]]

def remove_old_workflows(self, workflows):
""" """
for wf in workflows:
wf_id = wf.get("id")
wf_name = wf.get("name")

print(f"- Workflow name: '{wf_name}'")

runned_wf = self.list_workflow(wf_id)

total_count = runned_wf.get("total_count")

print(f" found {total_count} workflows")

if int(total_count) > int(self.github_keep_workflows):
workflow_runs = runned_wf.get("workflow_runs")

runned_wf = self.remove_elements(workflow_runs, int(self.github_keep_workflows))

msg_wf = ','.join(str(x) for x in runned_wf)

print(" delete the following workflows:")
self.remove_workflows(runned_wf)

def list_workflow(self, wf_id):

url = f"{self.github_base_url}/repos/{self.github_username}/{self.github_repository}/actions/workflows/{wf_id}/runs"

response = requests.get(url, headers=self.headers)

if response.status_code == 200:
repositories_data = response.json()
return repositories_data
else:
return None

def remove_elements(self, workflow, keep_elements):

runned_wf_ids = [x.get("id") for x in workflow]
runned_wf_ids = runned_wf_ids[keep_elements:]

return runned_wf_ids

def remove_workflows(self, workflow_ids=[]):
""" """
result = []
for wf_id in workflow_ids:
print(f" - id {wf_id}")
url = f"{self.github_base_url}/repos/{self.github_username}/{self.github_repository}/actions/runs/{wf_id}"

response = requests.delete(url, headers=self.headers)

# print(f" = {response}")

return result


gh = GitHub()
gh.header()
workflows = gh.list_defined_workflows()

if workflows:
# print(workflows)
wf = gh.active_workflows(workflows)
# print(json.dumps(wf, sort_keys=True, indent=2))
gh.remove_old_workflows(wf)

0 comments on commit 61bc214

Please sign in to comment.