From 1a822dc4b485c523770a6972470c5747ac606c09 Mon Sep 17 00:00:00 2001 From: ammallya Date: Wed, 3 Dec 2025 09:44:36 -0800 Subject: [PATCH 1/7] Automation to bump rocm-libraries submodule daily --- .github/workflows/bump_rocm_libraries.yml | 75 +++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 .github/workflows/bump_rocm_libraries.yml diff --git a/.github/workflows/bump_rocm_libraries.yml b/.github/workflows/bump_rocm_libraries.yml new file mode 100644 index 0000000000..4643a93283 --- /dev/null +++ b/.github/workflows/bump_rocm_libraries.yml @@ -0,0 +1,75 @@ +name: Bump rocm-libraries submodule + +on: + workflow_dispatch: + schedule: + - cron: "0 11 * * *" + +permissions: + contents: write + pull-requests: write + +jobs: + bump-submodules: + runs-on: ubuntu-24.04 + + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 + with: + python-version: '3.12' + + - name: Configure Git Identity + run: | + git config --global user.name "therockbot" + git config --global user.email "therockbot@amd.com" + + - name: Set branch name + id: set-branch + run: | + DATE=$(date +%Y%m%d) + BRANCH="github-action/bump-rocm-libraries-submodule-$DATE" + echo "branch-name=$BRANCH" >> $GITHUB_OUTPUT + + - name: Run bump_submodules.py + run: | + CMD="python3 ./build_tools/bump_submodules.py --push-branch --branch-name ${{ steps.set-branch.outputs.branch-name }} --components rocm-libraries" + echo "Running command: $CMD" + eval $CMD + + - name: Prepare PR body with diff info + run: | + echo "Automated daily submodule bump" > pr_body.txt + echo "This PR was automatically created by a GitHub App to update submodules." >> pr_body.txt + echo "" >> pr_body.txt + git fetch origin main + echo "## Submodule changes" >> pr_body.txt + echo "" >> pr_body.txt + git diff origin/main ${{ steps.set-branch.outputs.branch-name }} | \ + grep -E '^diff --git |^\+\+\+|^---|^\+Subproject commit|^-Subproject commit' | \ + sed \ + -e 's/^diff --git/### diff --git/g' \ + -e 's/^---/Old path:/g' \ + -e 's/^\+\+\+/New path:/g' \ + -e 's/^-Subproject commit/ Old commit:/g' \ + -e 's/^\+Subproject commit/ New commit:/g' \ + >> pr_body.txt + echo "" >> pr_body.txt + + - name: Generate GitHub App token + uses: actions/create-github-app-token@b36a0b4db3c4ce0a0d11a8d6c20d7b19d4c89d2f # v2.1.0 + id: generate-token + with: + app-id: ${{ secrets.PULL_REQUEST_APP_ID }} + private-key: ${{ secrets.PULL_REQUEST_APP_KEY }} + + - name: Create pull request + env: + GH_TOKEN: ${{ steps.generate-token.outputs.token }} + run: | + DATE=$(date +%Y%m%d) + gh pr create \ + --base main \ + --head ${{ steps.set-branch.outputs.branch-name }} \ + --title "rocm-libraries Submodule Bump-$DATE" \ + --body-file pr_body.txt From 8e2661a15b2e3d63486b5772746fad4e12ef3160 Mon Sep 17 00:00:00 2001 From: ammallya Date: Wed, 3 Dec 2025 09:51:12 -0800 Subject: [PATCH 2/7] Fixing pinned commit after github reorg --- .github/workflows/bump_rocm_libraries.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/bump_rocm_libraries.yml b/.github/workflows/bump_rocm_libraries.yml index 4643a93283..3acd71d753 100644 --- a/.github/workflows/bump_rocm_libraries.yml +++ b/.github/workflows/bump_rocm_libraries.yml @@ -57,7 +57,7 @@ jobs: echo "" >> pr_body.txt - name: Generate GitHub App token - uses: actions/create-github-app-token@b36a0b4db3c4ce0a0d11a8d6c20d7b19d4c89d2f # v2.1.0 + uses: actions/github-app-token@a96d5af8931ace9d219a3d6ff62babbaeff72eb7 # v1.1.0 id: generate-token with: app-id: ${{ secrets.PULL_REQUEST_APP_ID }} From a5e3cee66b388b41a5dc61b3d456fed648e6b1f4 Mon Sep 17 00:00:00 2001 From: ammallya Date: Wed, 3 Dec 2025 10:04:24 -0800 Subject: [PATCH 3/7] Fix correct token generation --- .github/workflows/bump_rocm_libraries.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/bump_rocm_libraries.yml b/.github/workflows/bump_rocm_libraries.yml index 3acd71d753..d92757cfe0 100644 --- a/.github/workflows/bump_rocm_libraries.yml +++ b/.github/workflows/bump_rocm_libraries.yml @@ -57,7 +57,7 @@ jobs: echo "" >> pr_body.txt - name: Generate GitHub App token - uses: actions/github-app-token@a96d5af8931ace9d219a3d6ff62babbaeff72eb7 # v1.1.0 + uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94 # v2.2.0 id: generate-token with: app-id: ${{ secrets.PULL_REQUEST_APP_ID }} From 9bdb816df9e5503282b3cdebdb4a04cb2977b607 Mon Sep 17 00:00:00 2001 From: ammallya Date: Wed, 3 Dec 2025 10:27:28 -0800 Subject: [PATCH 4/7] Fixing pre-commit --- .github/workflows/bump_rocm_libraries.yml | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/.github/workflows/bump_rocm_libraries.yml b/.github/workflows/bump_rocm_libraries.yml index d92757cfe0..883c693c70 100644 --- a/.github/workflows/bump_rocm_libraries.yml +++ b/.github/workflows/bump_rocm_libraries.yml @@ -4,39 +4,32 @@ on: workflow_dispatch: schedule: - cron: "0 11 * * *" - permissions: contents: write pull-requests: write - jobs: bump-submodules: runs-on: ubuntu-24.04 - steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 with: python-version: '3.12' - - name: Configure Git Identity run: | git config --global user.name "therockbot" - git config --global user.email "therockbot@amd.com" - + git config --global user.email "therockbot@amd.com" - name: Set branch name id: set-branch run: | DATE=$(date +%Y%m%d) BRANCH="github-action/bump-rocm-libraries-submodule-$DATE" echo "branch-name=$BRANCH" >> $GITHUB_OUTPUT - - name: Run bump_submodules.py run: | CMD="python3 ./build_tools/bump_submodules.py --push-branch --branch-name ${{ steps.set-branch.outputs.branch-name }} --components rocm-libraries" echo "Running command: $CMD" - eval $CMD - + eval $CMD - name: Prepare PR body with diff info run: | echo "Automated daily submodule bump" > pr_body.txt @@ -55,14 +48,12 @@ jobs: -e 's/^\+Subproject commit/ New commit:/g' \ >> pr_body.txt echo "" >> pr_body.txt - - name: Generate GitHub App token uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94 # v2.2.0 id: generate-token with: app-id: ${{ secrets.PULL_REQUEST_APP_ID }} private-key: ${{ secrets.PULL_REQUEST_APP_KEY }} - - name: Create pull request env: GH_TOKEN: ${{ steps.generate-token.outputs.token }} From 25ecb89613be45b005e83b7b92ffd2f524f65e78 Mon Sep 17 00:00:00 2001 From: ammallya Date: Wed, 3 Dec 2025 10:45:36 -0800 Subject: [PATCH 5/7] Fixing trailing whitespace --- .github/workflows/bump_rocm_libraries.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/bump_rocm_libraries.yml b/.github/workflows/bump_rocm_libraries.yml index 883c693c70..034b4bbd3d 100644 --- a/.github/workflows/bump_rocm_libraries.yml +++ b/.github/workflows/bump_rocm_libraries.yml @@ -18,7 +18,7 @@ jobs: - name: Configure Git Identity run: | git config --global user.name "therockbot" - git config --global user.email "therockbot@amd.com" + git config --global user.email "therockbot@amd.com" - name: Set branch name id: set-branch run: | @@ -29,7 +29,7 @@ jobs: run: | CMD="python3 ./build_tools/bump_submodules.py --push-branch --branch-name ${{ steps.set-branch.outputs.branch-name }} --components rocm-libraries" echo "Running command: $CMD" - eval $CMD + eval $CMD - name: Prepare PR body with diff info run: | echo "Automated daily submodule bump" > pr_body.txt From a574083aa27808b058ddddf55b6c28f2456a2bad Mon Sep 17 00:00:00 2001 From: Ameya Keshava Mallya Date: Fri, 5 Dec 2025 20:29:26 +0000 Subject: [PATCH 6/7] Moving logic from workflow to python script --- .github/workflows/bump_rocm_libraries.yml | 40 +++------- build_tools/bump_submodules.py | 96 ++++++++++++++++++++++- 2 files changed, 102 insertions(+), 34 deletions(-) diff --git a/.github/workflows/bump_rocm_libraries.yml b/.github/workflows/bump_rocm_libraries.yml index 034b4bbd3d..f9b695170f 100644 --- a/.github/workflows/bump_rocm_libraries.yml +++ b/.github/workflows/bump_rocm_libraries.yml @@ -3,7 +3,8 @@ name: Bump rocm-libraries submodule on: workflow_dispatch: schedule: - - cron: "0 11 * * *" + # 2:00 AM PST → 10:00 UTC + - cron: "0 10 * * *" permissions: contents: write pull-requests: write @@ -19,48 +20,25 @@ jobs: run: | git config --global user.name "therockbot" git config --global user.email "therockbot@amd.com" + - name: Set branch name id: set-branch run: | DATE=$(date +%Y%m%d) BRANCH="github-action/bump-rocm-libraries-submodule-$DATE" echo "branch-name=$BRANCH" >> $GITHUB_OUTPUT - - name: Run bump_submodules.py - run: | - CMD="python3 ./build_tools/bump_submodules.py --push-branch --branch-name ${{ steps.set-branch.outputs.branch-name }} --components rocm-libraries" - echo "Running command: $CMD" - eval $CMD - - name: Prepare PR body with diff info - run: | - echo "Automated daily submodule bump" > pr_body.txt - echo "This PR was automatically created by a GitHub App to update submodules." >> pr_body.txt - echo "" >> pr_body.txt - git fetch origin main - echo "## Submodule changes" >> pr_body.txt - echo "" >> pr_body.txt - git diff origin/main ${{ steps.set-branch.outputs.branch-name }} | \ - grep -E '^diff --git |^\+\+\+|^---|^\+Subproject commit|^-Subproject commit' | \ - sed \ - -e 's/^diff --git/### diff --git/g' \ - -e 's/^---/Old path:/g' \ - -e 's/^\+\+\+/New path:/g' \ - -e 's/^-Subproject commit/ Old commit:/g' \ - -e 's/^\+Subproject commit/ New commit:/g' \ - >> pr_body.txt - echo "" >> pr_body.txt + - name: Generate GitHub App token uses: actions/create-github-app-token@7e473efe3cb98aa54f8d4bac15400b15fad77d94 # v2.2.0 id: generate-token with: app-id: ${{ secrets.PULL_REQUEST_APP_ID }} private-key: ${{ secrets.PULL_REQUEST_APP_KEY }} - - name: Create pull request + + - name: Run bump_submodules.py env: GH_TOKEN: ${{ steps.generate-token.outputs.token }} run: | - DATE=$(date +%Y%m%d) - gh pr create \ - --base main \ - --head ${{ steps.set-branch.outputs.branch-name }} \ - --title "rocm-libraries Submodule Bump-$DATE" \ - --body-file pr_body.txt + python3 ./build_tools/bump_submodules.py --push-branch \ + --branch-name ${{ steps.set-branch.outputs.branch-name }} \ + --components rocm-libraries" diff --git a/build_tools/bump_submodules.py b/build_tools/bump_submodules.py index 0c58cfeee8..50d9e93091 100755 --- a/build_tools/bump_submodules.py +++ b/build_tools/bump_submodules.py @@ -36,7 +36,6 @@ def log(*args, **kwargs): print(*args, **kwargs) sys.stdout.flush() - def exec(args: list[str | Path], cwd: Path): args = [str(arg) for arg in args] log(f"++ Exec [{cwd}]$ {shlex.join(args)}") @@ -63,6 +62,69 @@ def pin_ck(): cwd=THEROCK_DIR / "ml-libs" / "composable_kernel", ) +def get_component_submodules(component: str) -> list[str]: + """ + Returns the list of submodule paths belonging to the component. + Reads .gitmodules to ensure accuracy. + """ + + gitmodules_path = THEROCK_DIR / ".gitmodules" + content = gitmodules_path.read_text() + + paths = [] + + for line in content.splitlines(): + line = line.strip() + if line.startswith("path = "): + sub_path = line.split("=", 1)[1].strip() + if sub_path == component or sub_path.startswith(component + "/"): + paths.append(sub_path) + return paths + + +def get_submodule_hash(path: str) -> str: + """ + Returns the commit hash for a submodule path. + """ + output = subprocess.check_output( + ["git", "submodule", "status", path], + cwd=str(THEROCK_DIR), + text=True + ).strip() + + commit = output.split()[0].lstrip("+ -") + return commit + + +def get_hashes_for_component(component: str) -> dict: + """ + Returns {submodule_path: hash} for the component. + """ + submodules = get_component_submodules(component) + + hashes = {} + for sm in submodules: + try: + h = get_submodule_hash(sm) + hashes[sm] = h + except Exception as e: + log(f"Failed to read hash for {sm}: {e}") + return hashes + + +def detect_hash_change(old: dict, new: dict): + """ + Return (old_hash, new_hash, path) for the first changed submodule. + """ + for path in new: + old_h = old.get(path) + new_h = new[path] + if old_h != new_h: + log(f"CHANGE DETECTED in {path}: {old_h} -> {new_h}") + return old_h, new_h, path + + log("No changes detected for component") + return None, None, None def parse_components(components: list[str]) -> list[list]: arguments = [] @@ -131,6 +193,9 @@ def run(args: argparse.Namespace, fetch_args: list[str], system_projects: list[s cwd=THEROCK_DIR, ) + component = args.components[0] + old_hashes = get_hashes_for_component(component) + if system_projects: projects_args = ["--system-projects"] + system_projects else: @@ -170,7 +235,32 @@ def run(args: argparse.Namespace, fetch_args: list[str], system_projects: list[s ["git", "push", "-u", "origin", args.branch_name], cwd=THEROCK_DIR, ) - + new_hashes = get_hashes_for_component(component) + old_h, new_h, changed_path = detect_hash_change(old_hashes, new_hashes) + if not old_h or not new_h: + log("WARNING: No submodule hash changes detected for the component.") + pr_title = f"Bump {component} from unknown to unknown" + else: + pr_title = f"Bump {component} from {old_h[:7]} to {new_h[:7]}" + pr_body = f"Bump happened on {datetime.today().strftime('%m%d%Y')}\n\n" + pr_body += "### Submodule changes:\n" + for sm in new_hashes: + pr_body += f"- `{sm}`: {old_hashes.get(sm)} → {new_hashes.get(sm)}\n" + # Create PR + exec( + [ + "gh", "pr", "create", + "--title", pr_title, + "--body", pr_body, + "--head", args.branch_name, + "--base", "main", + "--reviewer", "ScottTodd", + "--reviewer", "marbre", + "--reviewer", "geomin12", + "--reviewer", "jayhawk-commits", + ], + cwd=THEROCK_DIR, + ) def main(argv): parser = argparse.ArgumentParser(prog="bump_submodules") @@ -220,4 +310,4 @@ def main(argv): if __name__ == "__main__": - main(sys.argv[1:]) + main(sys.argv[1:]) \ No newline at end of file From 684853c34c3669f0ea686b8bec08cc362f429afc Mon Sep 17 00:00:00 2001 From: Ameya Keshava Mallya Date: Mon, 8 Dec 2025 22:58:11 +0000 Subject: [PATCH 7/7] Adding a seperate flag to create a PR and modifying commit message --- .github/workflows/bump_rocm_libraries.yml | 4 +- build_tools/bump_submodules.py | 83 ++++++++++++----------- 2 files changed, 46 insertions(+), 41 deletions(-) diff --git a/.github/workflows/bump_rocm_libraries.yml b/.github/workflows/bump_rocm_libraries.yml index f9b695170f..9ceec12cfc 100644 --- a/.github/workflows/bump_rocm_libraries.yml +++ b/.github/workflows/bump_rocm_libraries.yml @@ -3,8 +3,8 @@ name: Bump rocm-libraries submodule on: workflow_dispatch: schedule: - # 2:00 AM PST → 10:00 UTC - - cron: "0 10 * * *" + # 2:00 AM PST → 10:00 UTC, Monday–Friday + - cron: "0 10 * * 1-5" permissions: contents: write pull-requests: write diff --git a/build_tools/bump_submodules.py b/build_tools/bump_submodules.py index 50d9e93091..529c3bfe8c 100755 --- a/build_tools/bump_submodules.py +++ b/build_tools/bump_submodules.py @@ -2,9 +2,9 @@ """Helper script to bump TheRock's submodules, doing the following: * (Optional) Creates a new branch * Updates submodules from remote using `fetch_sources.py` - * Creares a commit and tries to apply local patches + * Creates a commit and tries to apply local patches * (Optional) Pushed the new branch to origin - + * (Optional) Create pull request from the new branch to origin (requires gh cli installed) The submodules to bump can be specified via `--components`. Examples: @@ -27,6 +27,7 @@ import shlex import subprocess import sys +import shutil THIS_SCRIPT_DIR = Path(__file__).resolve().parent THEROCK_DIR = THIS_SCRIPT_DIR.parent @@ -185,14 +186,6 @@ def parse_components(components: list[str]) -> list[list]: def run(args: argparse.Namespace, fetch_args: list[str], system_projects: list[str]): - date = datetime.today().strftime("%Y%m%d") - - if args.create_branch or args.push_branch: - exec( - ["git", "checkout", "-b", args.branch_name], - cwd=THEROCK_DIR, - ) - component = args.components[0] old_hashes = get_hashes_for_component(component) @@ -216,10 +209,28 @@ def run(args: argparse.Namespace, fetch_args: list[str], system_projects: list[s if args.pin_ck: pin_ck() - exec( - ["git", "commit", "-a", "-m", "Bump submodules " + date], - cwd=THEROCK_DIR, + # Detect new hashes BEFORE commit/branch creation + new_hashes = get_hashes_for_component(component) + old_h, new_h, changed_path = detect_hash_change(old_hashes, new_hashes) + if not old_h or not new_h: + log("No submodule changes detected – aborting without commit, branch, or PR.") + return + + if args.create_branch or args.push_branch or args.create_pr: + exec(["git", "checkout", "-b", args.branch_name], cwd=THEROCK_DIR) + + # Prepare commit/PR title/body + pr_title = f"Bump {component} from {old_h[:7]} to {new_h[:7]}" + pr_body = ( + f"Bump happened on {datetime.today().strftime('%m%d%Y')}\n\n" + "### Submodule changes:\n" + + "".join( + f"- `{sm}`: {old_hashes.get(sm)} → {new_hashes.get(sm)}\n" + for sm in new_hashes + ) ) + commit_msg = pr_title + "\n\n" + pr_body + exec(["git", "commit", "-a", "-m", commit_msg], cwd=THEROCK_DIR) try: exec( @@ -234,33 +245,21 @@ def run(args: argparse.Namespace, fetch_args: list[str], system_projects: list[s exec( ["git", "push", "-u", "origin", args.branch_name], cwd=THEROCK_DIR, - ) - new_hashes = get_hashes_for_component(component) - old_h, new_h, changed_path = detect_hash_change(old_hashes, new_hashes) - if not old_h or not new_h: - log("WARNING: No submodule hash changes detected for the component.") - pr_title = f"Bump {component} from unknown to unknown" - else: - pr_title = f"Bump {component} from {old_h[:7]} to {new_h[:7]}" - pr_body = f"Bump happened on {datetime.today().strftime('%m%d%Y')}\n\n" - pr_body += "### Submodule changes:\n" - for sm in new_hashes: - pr_body += f"- `{sm}`: {old_hashes.get(sm)} → {new_hashes.get(sm)}\n" + ) # Create PR - exec( - [ - "gh", "pr", "create", - "--title", pr_title, - "--body", pr_body, - "--head", args.branch_name, - "--base", "main", - "--reviewer", "ScottTodd", - "--reviewer", "marbre", - "--reviewer", "geomin12", - "--reviewer", "jayhawk-commits", - ], - cwd=THEROCK_DIR, - ) + if args.create_pr: + if not shutil.which("gh"): + raise SystemExit("ERROR: --create-pr requires the `gh` CLI.\n") + exec( + [ + "gh", "pr", "create", + "--title", pr_title, + "--body", pr_body, + "--head", args.branch_name, + "--base", "main", + ], + cwd=THEROCK_DIR, + ) def main(argv): parser = argparse.ArgumentParser(prog="bump_submodules") @@ -304,6 +303,12 @@ def main(argv): profiler """, ) + parser.add_argument( + "--create-pr", + default=False, + action=argparse.BooleanOptionalAction, + help="Create a GitHub PR (requires `gh` CLI)", + ) args = parser.parse_args(argv) fetch_args, system_projects = parse_components(args.components) run(args, fetch_args, system_projects)