Skip to content

Set up automation for updating pytype and pyright versions. #11491

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

Closed
wants to merge 8 commits into from
50 changes: 50 additions & 0 deletions .github/workflows/update_mypy_pyright.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Update mypy, pytype and pyright

on:
schedule:
# Runs every day at 00:00 UTC
- cron: '0 0 * * *'

jobs:
build:
strategy:
matrix:
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: Install dependencies
run: |
pip install requests
- name: Run script
run: python scripts/check_for_update_dependency.py
- uses: peter-evans/create-pull-request@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
title: "Daily dependencies update"
commit-message: "Updated dependencies after the daily check"
body: |
There appear to be some dependency updates in ${{ github.sha }}. This pull request
uses the script to find and update these dependencies.
base: ${{ github.head_ref }}
# https://github.community/t/run-github-actions-job-only-if-previous-job-has-failed/174786/2
create-issue-on-failure:
name: Create an issue if Update mypy, pytype and pyright failed
runs-on: ubuntu-latest
needs: [build]
if: ${{ github.repository == 'python/typeshed' && always() && (needs.build.result == 'failure') }}
steps:
- uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
await github.rest.issues.create({
owner: "python",
repo: "typeshed",
title: `Update mypy, pytype and pyright failed on ${new Date().toDateString()}`,
body: "Update mypy, pytype and pyright runs are listed here: https://github.com/python/typeshed/actions/workflows/update_mypy_pyright.yml",
})
65 changes: 65 additions & 0 deletions scripts/check_for_update_dependency.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import re
import requests
from typing import List

from typing import Optional


def get_latest_version(package_name: str) -> Optional[str]:
"""Fetch the latest version of a package from PyPI."""
response = requests.get(f"https://pypi.org/pypi/{package_name}/json")
response.raise_for_status()
data = response.json()
return str(data["info"]["version"])


def update_versions(file_path: str) -> None:
with open(file_path, "r") as file:
content = file.readlines()

pattern = re.compile(r"^(pytype|mypy)==([\d.]+)")

updated_content: List[str] = []

for line in content:
match = pattern.match(line)
if match:
package_name = match.group(1)
current_version = match.group(2)
latest_version = get_latest_version(package_name)
if latest_version and current_version != latest_version:
print(f"Updating {package_name} from {current_version} to {latest_version}")
line = line.replace(current_version, latest_version)
updated_content.append(line)

with open(file_path, "w") as file:
file.writelines(updated_content)


def update_pyright_version(file_path: str) -> None:
"""Update pyright version in a TOML configuration file."""
with open(file_path, "r", encoding="utf-8") as file:
lines = file.readlines()

latest_version = get_latest_version("pyright")
if latest_version:
updated_lines = []
for line in lines:
if line.startswith("pyright_version = "):
updated_lines.append(f'pyright_version = "{latest_version}"\n')
print(f"Updated pyright to version {latest_version} in {file_path}")
else:
updated_lines.append(line)

with open(file_path, "w", encoding="utf-8") as file:
file.writelines(updated_lines)


file_paths: List[str] = ["requirements-tests.txt", "pyproject.toml"]

if __name__ == "__main__":
for file_path in file_paths:
if file_path.endswith(".txt"):
update_versions(file_path)
elif file_path.endswith(".toml"):
update_pyright_version(file_path)