From 61bc214750b7219b83938cd2ae53069e3313de4a Mon Sep 17 00:00:00 2001 From: Bodo Schulz Date: Mon, 19 Aug 2024 16:56:26 +0200 Subject: [PATCH] change action to clean workflows --- .github/workflows/clean-workflows.yml | 36 +++++- .github/workflows/galaxy.yml | 2 +- .github/workflows/linter.yml | 2 +- .github/workflows/main.yml | 4 +- hooks/gh-clean | 68 +---------- hooks/gh-clean.py | 156 ++++++++++++++++++++++++++ 6 files changed, 194 insertions(+), 74 deletions(-) mode change 100644 => 100755 hooks/gh-clean create mode 100755 hooks/gh-clean.py diff --git a/.github/workflows/clean-workflows.yml b/.github/workflows/clean-workflows.yml index 2f475de..11232df 100644 --- a/.github/workflows/clean-workflows.yml +++ b/.github/workflows/clean-workflows.yml @@ -4,7 +4,7 @@ name: delete workflow runs on: schedule: - - cron: "10 4 * * 0" + - cron: "20 4 * * 0" workflow_dispatch: inputs: logLevel: @@ -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 }} diff --git a/.github/workflows/galaxy.yml b/.github/workflows/galaxy.yml index 2a7875e..ac43d13 100644 --- a/.github/workflows/galaxy.yml +++ b/.github/workflows/galaxy.yml @@ -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' diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 256a1a8..8c75e39 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -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 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7e3c252..666d356 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -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 }}" diff --git a/hooks/gh-clean b/hooks/gh-clean old mode 100644 new mode 100755 index 4605d95..6b6452f --- a/hooks/gh-clean +++ b/hooks/gh-clean @@ -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/dev/null - done - - echo "-------------------------------------------------" - fi - done -else - echo "missing values:" - echo " - org : '${org}'" - echo " - repo: '${repo}'" - - exit 1 -fi +python hooks/gh-clean.py diff --git a/hooks/gh-clean.py b/hooks/gh-clean.py new file mode 100755 index 0000000..4a5a842 --- /dev/null +++ b/hooks/gh-clean.py @@ -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)