-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add script+workflow to update IREE requirement pins. (#827)
Progress on #760, built off of the work in iree-org/iree-turbine#388. This adds a new workflow that runs once a day to update all pinned IREE versions. I also looked into using Dependabot but found that it struggles with `--find-links`, `--index-url`, and with there being multiple `requirements.txt` files in a repository. While I would love to not need to reinvent this wheel, I do like keeping full control over the process. This PR includes: * A new `build_tools/update_iree_requirement_pins.py` script handles updating the pins in `requirements-iree-pinned.txt` and `shortfin/CMakeLists.txt`. The script also sets some variables in `GITHUB_ENV`. * A new `.github/workflows/update_iree_requirement_pins.yml` workflow runs that script then calls https://github.com/peter-evans/create-pull-request to create or update a pull request if there are local changes after running that script. The commit message and pull request body are constructed using the variables set by the script. Test action run: https://github.com/ScottTodd/shark-ai/actions/runs/12777789320 Test pull request: ScottTodd#1
- Loading branch information
Showing
2 changed files
with
248 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# Copyright 2025 Advanced Micro Devices, Inc. | ||
# | ||
# Licensed under the Apache License v2.0 with LLVM Exceptions. | ||
# See https://llvm.org/LICENSE.txt for license information. | ||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
name: Update IREE requirement pins | ||
|
||
on: | ||
workflow_dispatch: | ||
schedule: | ||
# Weekdays at 11:00 AM UTC = 03:00 AM PST / 04:00 AM PDT | ||
- cron: "0 11 * * 1-5" | ||
|
||
permissions: | ||
contents: write | ||
pull-requests: write | ||
|
||
jobs: | ||
update-iree: | ||
if: ${{ github.repository_owner == 'nod-ai' || github.event_name != 'schedule' }} | ||
runs-on: ubuntu-24.04 | ||
|
||
steps: | ||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||
|
||
- name: "Setting up Python" | ||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 | ||
with: | ||
python-version: 3.11 | ||
|
||
# This sets a few environment variables used below. | ||
- name: Update IREE requirement pins | ||
run: build_tools/update_iree_requirement_pins.py | ||
|
||
- name: Create or update pull request | ||
if: | | ||
${{ env.CURRENT_IREE_BASE_COMPILER_VERSION }} != ${{ env.LATEST_IREE_BASE_COMPILER_VERSION }} || \ | ||
${{ env.CURRENT_IREE_BASE_RUNTIME_VERSION }} != ${{ env.LATEST_IREE_BASE_RUNTIME_VERSION }} || \ | ||
${{ env.CURRENT_IREE_TURBINE_VERSION }} != ${{ env.LATEST_IREE_TURBINE_VERSION }} | ||
${{ env.CURRENT_SHORTFIN_IREE_GIT_TAG }} != ${{ env.LATEST_SHORTFIN_IREE_GIT_TAG }} | ||
uses: peter-evans/create-pull-request@67ccf781d68cd99b580ae25a5c18a1cc84ffff1f # v7.0.6 | ||
with: | ||
base: main | ||
branch: integrates/iree | ||
delete-branch: true | ||
signoff: true | ||
title: "Bump IREE requirement pins to their latest versions." | ||
body: | | ||
Diff: https://github.com/iree-org/iree/compare/iree-${{ env.CURRENT_IREE_BASE_COMPILER_VERSION }}...iree-${{ env.LATEST_IREE_BASE_COMPILER_VERSION }} | ||
Auto-generated by GitHub Actions using [`.github/workflows/update_iree_requirement_pins.yml`](https://github.com/${{ github.repository }}/blob/main/.github/workflows/update_iree_requirement_pins.yml). | ||
commit-message: "Bump IREE to ${{ env.LATEST_IREE_BASE_COMPILER_VERSION }}." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
#!/usr/bin/env python | ||
|
||
# Copyright 2025 Advanced Micro Devices, Inc. | ||
# | ||
# Licensed under the Apache License v2.0 with LLVM Exceptions. | ||
# See https://llvm.org/LICENSE.txt for license information. | ||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
"""Updates the pinned IREE versions in this repository. | ||
Usage: | ||
update_iree_requirement_pins.py | ||
Environment variable outputs (via GITHUB_ENV) for GitHub Actions: | ||
CURRENT_IREE_BASE_COMPILER_VERSION | ||
CURRENT_IREE_BASE_RUNTIME_VERSION | ||
CURRENT_IREE_TURBINE_VERSION | ||
LATEST_IREE_BASE_COMPILER_VERSION | ||
LATEST_IREE_BASE_RUNTIME_VERSION | ||
LATEST_IREE_TURBINE_VERSION | ||
""" | ||
|
||
from pathlib import Path | ||
import os | ||
import re | ||
import subprocess | ||
import sys | ||
import textwrap | ||
|
||
REPO_ROOT = Path(__file__).parent.parent | ||
REQUIREMENTS_IREE_PINNED_PATH = REPO_ROOT / "requirements-iree-pinned.txt" | ||
SHORTFIN_CMAKELISTS_PATH = REPO_ROOT / "shortfin" / "CMakeLists.txt" | ||
|
||
|
||
def get_current_version(package_name): | ||
with open(REQUIREMENTS_IREE_PINNED_PATH, "r") as f: | ||
text = f.read() | ||
return re.findall(f"{package_name}==(.*)", text)[0] | ||
|
||
|
||
def get_latest_version(package_name, extra_pip_args=[]): | ||
print("\n-------------------------------------------------------------------------") | ||
print(f"Finding latest available package version for package '{package_name}'\n") | ||
|
||
# This queries the pip index to get the latest version. | ||
# | ||
# This doesn't require downloading or installing, so it should be more | ||
# portable across operating systems than other approaches. | ||
# | ||
# Note: the `index` subcommand is experimental. We could instead: | ||
# * Install (into a venv) then check what was installed with `--report`, | ||
# `pip freeze`, or regex parsing (as in `get_current_version()` above) | ||
# * Download then check what was downloaded | ||
# * Scrape the package index and/or release page (https://iree.dev/pip-release-links.html) | ||
subprocess_args = [ | ||
sys.executable, | ||
"-m", | ||
"pip", | ||
"index", | ||
"versions", | ||
package_name, | ||
"--disable-pip-version-check", | ||
] | ||
subprocess_args.extend(extra_pip_args) | ||
|
||
print(f"Running command:\n {subprocess.list2cmdline(subprocess_args)}\n") | ||
result = subprocess.run(subprocess_args, stdout=subprocess.PIPE) | ||
output = result.stdout.decode("utf-8") | ||
print(f"Command output:\n{textwrap.indent(output, ' ')}") | ||
|
||
# Search for text like `iree-base-compiler (3.2.0rc20250109)` within the | ||
# multiple lines of output from the command. | ||
# WARNING: The output from `pip index` is UNSTABLE and UNSTRUCTURED, but | ||
# this seems to work using Python 3.11.2 and pip 22.3.1. | ||
version_search_regex = re.compile(f"{package_name}\s\((.*)\)") | ||
matches = version_search_regex.match(output) | ||
if not matches: | ||
raise RuntimeError("Failed to find a package version using regex") | ||
version = matches.groups()[0] | ||
print( | ||
f"Found package version for '{package_name}' in output using regex: '{version}'" | ||
) | ||
return version | ||
|
||
|
||
def get_current_git_tag(): | ||
with open(SHORTFIN_CMAKELISTS_PATH, "r") as f: | ||
text = f.read() | ||
return re.findall('SHORTFIN_IREE_GIT_TAG "(.*)"', text)[0] | ||
|
||
|
||
def main(): | ||
print("Updating IREE version pins!") | ||
|
||
current_compiler_version = get_current_version("iree-base-compiler") | ||
current_runtime_version = get_current_version("iree-base-runtime") | ||
current_turbine_version = get_current_version("iree-turbine") | ||
current_git_tag = get_current_git_tag() | ||
|
||
nightly_pip_args = [ | ||
"--pre", | ||
"--find-links", | ||
"https://iree.dev/pip-release-links.html", | ||
] | ||
latest_compiler_version = get_latest_version("iree-base-compiler", nightly_pip_args) | ||
latest_runtime_version = get_latest_version("iree-base-runtime", nightly_pip_args) | ||
latest_turbine_version = get_latest_version("iree-turbine", nightly_pip_args) | ||
# TODO(scotttodd): Get this from git? It should generally be in sync with | ||
# the python packages and follow a naming convention. If that isn't | ||
# true, such as right after a stable release, then this may break. | ||
latest_git_tag = f"iree-{latest_runtime_version}" | ||
|
||
print("\n-------------------------------------------------------------------------") | ||
print("Current versions:") | ||
print(f" iree-base-compiler=={current_compiler_version}") | ||
print(f" iree-base-runtime=={current_runtime_version}") | ||
print(f" iree-turbine=={current_turbine_version}") | ||
print(f' SHORTFIN_IREE_GIT_TAG "{current_git_tag}"') | ||
print("Latest versions:") | ||
print(f" iree-base-compiler=={latest_compiler_version}") | ||
print(f" iree-base-runtime=={latest_runtime_version}") | ||
print(f" iree-turbine=={latest_turbine_version}") | ||
print(f' SHORTFIN_IREE_GIT_TAG "{latest_git_tag}"') | ||
|
||
# Write to GitHub Actions environment variables for future steps to use if they want. | ||
github_env = os.getenv("GITHUB_ENV") | ||
if github_env: | ||
with open(github_env, "a") as fh: | ||
print( | ||
f"CURRENT_IREE_BASE_COMPILER_VERSION={current_compiler_version}", | ||
file=fh, | ||
) | ||
print( | ||
f"CURRENT_IREE_BASE_RUNTIME_VERSION={current_runtime_version}", file=fh | ||
) | ||
print(f"CURRENT_IREE_TURBINE_VERSION={current_turbine_version}", file=fh) | ||
print(f"CURRENT_SHORTFIN_IREE_GIT_TAG={current_git_tag}", file=fh) | ||
print( | ||
f"LATEST_IREE_BASE_COMPILER_VERSION={latest_compiler_version}", file=fh | ||
) | ||
print(f"LATEST_IREE_BASE_RUNTIME_VERSION={latest_runtime_version}", file=fh) | ||
print(f"LATEST_IREE_TURBINE_VERSION={latest_turbine_version}", file=fh) | ||
print(f"LATEST_SHORTFIN_IREE_GIT_TAG={latest_git_tag}", file=fh) | ||
|
||
if ( | ||
current_compiler_version == latest_compiler_version | ||
and current_runtime_version == latest_runtime_version | ||
and current_turbine_version == latest_turbine_version | ||
and current_git_tag == latest_git_tag | ||
): | ||
print("Already using the latest versions, exiting") | ||
return | ||
|
||
print("\n-------------------------------------------------------------------------") | ||
print(f"Editing version pins in '{REQUIREMENTS_IREE_PINNED_PATH}'") | ||
with open(REQUIREMENTS_IREE_PINNED_PATH, "r") as f: | ||
text = f.read() | ||
print(f"Original text:\n{textwrap.indent(text, ' ')}\n") | ||
|
||
text = re.sub( | ||
"iree-base-compiler==.*", | ||
f"iree-base-compiler=={latest_compiler_version}", | ||
text, | ||
) | ||
text = re.sub( | ||
"iree-base-runtime==.*", | ||
f"iree-base-runtime=={latest_runtime_version}", | ||
text, | ||
) | ||
text = re.sub( | ||
"iree-turbine==.*", | ||
f"iree-turbine=={latest_turbine_version}", | ||
text, | ||
) | ||
print(f"New text:\n{textwrap.indent(text, ' ')}\n") | ||
with open(REQUIREMENTS_IREE_PINNED_PATH, "w") as f: | ||
f.write(text) | ||
|
||
print(f"Editing git tag in '{SHORTFIN_CMAKELISTS_PATH}'") | ||
with open(SHORTFIN_CMAKELISTS_PATH, "r") as f: | ||
text = f.read() | ||
text = re.sub( | ||
'SHORTFIN_IREE_GIT_TAG ".*"', | ||
f'SHORTFIN_IREE_GIT_TAG "{latest_git_tag}"', | ||
text, | ||
) | ||
with open(SHORTFIN_CMAKELISTS_PATH, "w") as f: | ||
f.write(text) | ||
|
||
print("-------------------------------------------------------------------------") | ||
print("Edits complete") | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |