Skip to content

Commit

Permalink
Merge pull request #657 from Wabri/experiment/discussion/421
Browse files Browse the repository at this point in the history
feat(workflows): create a workflow to open issue when outdate deps
  • Loading branch information
Wabri authored Mar 5, 2024
2 parents d047f93 + de8b054 commit d36cc15
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 0 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/check_outdated_dependencies.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---

name: Check outdated dependencies

on:
schedule:
- cron: '0 7 1,15 * *'

workflow_dispatch:

jobs:
check_outdate_dependencies:
runs-on: ubuntu-latest

steps:
- name: Check out the code
uses: actions/checkout@main

- name: Check workflow dependencies
uses: ./workflows/check_outdate_deps
env:
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REQUIREMENT_FILE: "requirements-workflow.txt"
4 changes: 4 additions & 0 deletions requirements-workflow.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ansible==9.1.0
ansible-compat==4.1.10
ansible-core==2.16.2
ansible-lint==6.22.1
10 changes: 10 additions & 0 deletions workflows/check_outdate_deps/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM python:3.12-slim

COPY check_outdate_deps.sh /check_outdate_deps.sh

RUN chmod +x /check_outdate_deps.sh

# needed for the open_issue.py
RUN pip3 install requests

ENTRYPOINT [ "/check_outdate_deps.sh" ]
5 changes: 5 additions & 0 deletions workflows/check_outdate_deps/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: 'Check dependencies and try to solve it'

Check failure on line 1 in workflows/check_outdate_deps/action.yml

View workflow job for this annotation

GitHub Actions / ansible-lint

yaml[document-start]

Missing document start "---"

Check failure on line 1 in workflows/check_outdate_deps/action.yml

View workflow job for this annotation

GitHub Actions / ansible-lint

yaml[document-start]

Missing document start "---"

Check failure on line 1 in workflows/check_outdate_deps/action.yml

View workflow job for this annotation

GitHub Actions / ansible-lint

yaml[document-start]

Missing document start "---"

Check failure on line 1 in workflows/check_outdate_deps/action.yml

View workflow job for this annotation

GitHub Actions / ansible-lint

yaml[document-start]

Missing document start "---"

Check failure on line 1 in workflows/check_outdate_deps/action.yml

View workflow job for this annotation

GitHub Actions / ansible-lint

yaml[document-start]

Missing document start "---"
description: 'This action will check dependencies in .github/workflows that are installed using pip and open issue and create a pull request to solve the problem'
runs:
using: 'docker'
image: 'Dockerfile'
34 changes: 34 additions & 0 deletions workflows/check_outdate_deps/check_outdate_deps.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env bash

pip3 install -r "$REQUIREMENT_FILE"
input=$(pip3 list --outdated)

compare_versions() {
local version1=$1
local version2=$2
local IFS='.'

read -ra version1_splitted <<< "$version1"
read -ra version2_splitted <<< "$version2"

for ((i=0;i<${#version1_splitted[@]};i++)); do
delta=$(( version1_splitted[i] - version2_splitted[i] ))
if (( delta != 0 )); then
echo $delta
return
fi
done
echo 0
}

while read -r line; do
if [[ $line =~ ^([a-zA-Z0-9-]+)\ +([0-9]+\.[0-9]+\.[0-9]+)\ +([0-9]+\.[0-9]+\.[0-9]+)\ +([a-zA-Z]+) ]]; then
package="${BASH_REMATCH[1]}"
version="${BASH_REMATCH[2]}"
latest="${BASH_REMATCH[3]}"

if [ "$(compare_versions "$version" "$latest")" -lt 0 ]; then
./workflows/check_outdate_deps/open_issue.py "$package" "$version" "$latest"
fi
fi
done <<< "$input"
60 changes: 60 additions & 0 deletions workflows/check_outdate_deps/open_issue.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/usr/bin/env python

import argparse
import requests
import os
import json


def get_description(requirement_file, package, latest):
return f"""The package {package} is outdated in {requirement_file}. The latest version is {latest}. Please update the package to the latest version.
Check the package [here](https://pypi.org/project/{package}/{latest}/) for more information.
"""


def get_title(requirement_file, package_name, current_version, latest_version):
return f"Dependency outdated in {requirement_file}: {package_name}:{current_version} -> {latest_version}"


if __name__ == '__main__':
# Arguments parsing
parser = argparse.ArgumentParser(description="Open issue with the correct argument")
parser.add_argument("package", type=str, help='The name of the package')
parser.add_argument("version", type=str, help='The current version of the package')
parser.add_argument("latest", type=str, help='The latest version of the package')
args = parser.parse_args()

# Environment variable
repo = os.environ.get("GITHUB_REPOSITORY")
requirement_file = str(os.environ.get("REQUIREMENT_FILE"))

# Define the title
issue_title = get_title(requirement_file, args.package, args.version, args.latest)

# The double quote on the issue_title is necessary to avoid duplicate issues
query = f"repo:{repo} type:issue in:title \"{issue_title}\""

# Send the query
response = requests.get("https://api.github.com/search/issues", params={"q": query})
data = response.json()

# There is this error that we somehow try to avoid
# {'message': "API rate limit exceeded for 93.45.31.205. (But here's the good news: Authenticated requests get a higher rate limit. Check
# out the documentation for more details.)", 'documentation_url': 'https://docs.github.com/rest/overview/resources-in-the-rest-api#rat
# e-limiting'}
if data["total_count"] > 0:
print("There is already an issue with this title!")
else:
issue_description = get_description(requirement_file, args.package, args.latest)
token = os.environ.get("GITHUB_TOKEN")
issue = {"title": issue_title, "body": issue_description}
headers = {"Authorization": f"token {token}"}

response = requests.post(f"https://api.github.com/repos/{repo}/issues", headers=headers, data=json.dumps(issue))

# Check the response
if response.status_code == 201:
print("Issue created successfully.")
else:
print(f"Failed to create issue. Status code: {response.status_code}.")

0 comments on commit d36cc15

Please sign in to comment.