Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions .github/workflows/create_ifu_tag.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
name: Create git tags for IFU PRs

on:
pull_request:
types: [closed]

permissions:
contents: write # create/push tags
pull-requests: write # edit PR body

jobs:
tag-ifu:
# Only proceed if: merged AND title has both markers
if: >
github.event.pull_request.merged == true &&
contains(github.event.pull_request.title, '[AUTOGENERATED]') &&
contains(github.event.pull_request.title, 'IFU')
runs-on: ubuntu-latest

steps:
- name: Checkout base repo (full history)
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.base.ref }}
fetch-depth: 0

- name: Configure Git user
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Derive key SHAs (rocm base, upstream main, merge)
id: shas
shell: bash
run: |
set -euo pipefail

PR_NUM="${{ github.event.pull_request.number }}"
BASE_REF="${{ github.event.pull_request.base.ref }}"
HEAD_SHA="${{ github.event.pull_request.head.sha }}"
MERGE_SHA="${{ github.event.pull_request.merge_commit_sha }}"

# The ROCm base commit is the first parent of the merge commit that landed the PR
# (i.e., the base branch tip BEFORE this PR merged).
ROCM_BASE_SHA=$(git rev-parse "${MERGE_SHA}^1")

# Add and fetch upstream to identify the upstream/main commit that HEAD integrated.
git remote add upstream "https://github.com/pytorch/pytorch.git"
git fetch upstream "$BASE_REF"

# Heuristic: the upstream commit integrated by the PR's head is the merge-base
# between the PR head commit and upstream/main as fetched now.
# This gives you the exact upstream commit (or the best common ancestor) that HEAD included.
UPSTREAM_MAIN_SHA=$(git merge-base "${HEAD_SHA}" "upstream/$BASE_REF")
echo "PR_NUM=$PR_NUM"
echo "BASE_REF=$BASE_REF"
echo "HEAD_SHA=$HEAD_SHA"
echo "MERGE_SHA=$MERGE_SHA"
echo "ROCM_BASE_SHA=$ROCM_BASE_SHA"
echo "UPSTREAM_MAIN_SHA=$UPSTREAM_MAIN_SHA"


echo "PR_NUM=$PR_NUM" >> "$GITHUB_OUTPUT"
echo "BASE_REF=$BASE_REF" >> "$GITHUB_OUTPUT"
echo "HEAD_SHA=$HEAD_SHA" >> "$GITHUB_OUTPUT"
echo "MERGE_SHA=$MERGE_SHA" >> "$GITHUB_OUTPUT"
echo "ROCM_BASE_SHA=$ROCM_BASE_SHA" >> "$GITHUB_OUTPUT"
echo "UPSTREAM_MAIN_SHA=$UPSTREAM_MAIN_SHA" >> "$GITHUB_OUTPUT"

- name: Extract tag base from PR title
id: tagname
run: |
TITLE="${{ github.event.pull_request.title }}"
# Remove everything up to and including "[AUTOGENERATED]"
BASE_TAG=$(echo "$TITLE" | sed -E 's/^\[AUTOGENERATED\][[:space:]]*//')

echo "BASE_TAG=$BASE_TAG"
echo "PRE_TAG=${BASE_TAG}_pre"
echo "POST_TAG=${BASE_TAG}_post"

echo "BASE_TAG=$BASE_TAG" >> $GITHUB_OUTPUT
echo "PRE_TAG=${BASE_TAG}_pre" >> $GITHUB_OUTPUT
echo "POST_TAG=${BASE_TAG}_post" >> $GITHUB_OUTPUT

- name: Create pre/post tags
shell: bash
run: |
set -euo pipefail
echo "Tagging:"
echo " ${{ steps.tagname.outputs.PRE_TAG }} @ ${{ steps.shas.outputs.ROCM_BASE_SHA }}"
echo " ${{ steps.tagname.outputs.POST_TAG }} @ ${{ steps.shas.outputs.MERGE_SHA }}"

git tag -a "${{ steps.tagname.outputs.PRE_TAG }}" -m "IFU pre (PR #${{ steps.shas.outputs.PR_NUM }})" "${{ steps.shas.outputs.ROCM_BASE_SHA }}"
git tag -a "${{ steps.tagname.outputs.POST_TAG }}" -m "IFU post (PR #${{ steps.shas.outputs.PR_NUM }})" "${{ steps.shas.outputs.MERGE_SHA }}"

#Force pushing is safe. If we land a new PR, we'd wanna retag a commit if we have to.
git push origin "refs/tags/${{ steps.tagname.outputs.PRE_TAG }}" -f
git push origin "refs/tags/${{ steps.tagname.outputs.POST_TAG }}" -f

- name: Append rocm_base & upstream_main to PR body
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: bash
run: |
set -euo pipefail
# Read current body
PR="${{ steps.shas.outputs.PR_NUM }}"
CURR=$(gh api repos/${{ github.repository }}/pulls/$PR --jq .body)
APPEND=$'\n'"rocm_base: ${{ steps.shas.outputs.ROCM_BASE_SHA }}"$'\n'"upstream_main: ${{ steps.shas.outputs.UPSTREAM_MAIN_SHA }}"$'\n'
NEW_BODY="${CURR}${APPEND}"

# Write to a temp file and update PR body
printf '%s' "$NEW_BODY" > body.txt
gh api --method PATCH -H "Accept: application/vnd.github+json" \
repos/${{ github.repository }}/pulls/$PR -F body=@body.txt

145 changes: 145 additions & 0 deletions .github/workflows/pytorch_ifu.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
name: PyTorch IFU (Sync with upstream)

on:
workflow_dispatch:
inputs:
ifu_target_repo:
description: "Target repo for IFU"
required: false
default: "ROCm/pytorch"
type: string
ifu_target_branch:
description: "Target branch for IFU"
required: true
default: "rocm7.1_internal_testing"
type: string
ifu_source_repo:
description: "Source repo for IFU"
required: false
default: "pytorch/pytorch"
type: string
ifu_source_branch:
description: "Source branch for IFU"
required: false
default: "main"
type: string
# schedule:
# # Runs every 14 days at 09:00 AM UTC/ 04:00 AM CST
# - cron: "0 9 */14 * *"

permissions:
contents: write # push branches/tags
pull-requests: write # create PRs

concurrency:
group: ifu
# If two jobs are running simultaneously, we will queue them (not cancel the one running)
cancel-in-progress: false

jobs:
ifu:
runs-on: ubuntu-latest
env:
UPSTREAM_REMOTE: upstream # IFU source remote name
UPSTREAM_REPO: ${{ inputs.ifu_source_repo }} # source repo for IFU
UPSTREAM_BRANCH: ${{ inputs.ifu_source_branch }} # source branch for IFU
DOWNSTREAM_REMOTE: origin # IFU target remote name
DOWNSTREAM_REPO: ${{ inputs.ifu_target_repo }} # target repo for IFU (fork); actions/checkout sets this to origin
DOWNSTREAM_BRANCH: ${{ inputs.ifu_target_branch }} # target branch for IFU
GH_TOKEN: ${{ secrets.IFU_GITHUB_TOKEN }} # used by gh; provided by Action
steps:
- name: Checkout repository (${{ env.DOWNSTREAM_REPO }}) (full history)
uses: actions/checkout@v4
with:
repository: ${{ env.DOWNSTREAM_REPO }}
path: ${{ env.DOWNSTREAM_REPO }}
ref: ${{ env.DOWNSTREAM_BRANCH }}
token: ${{ env.GH_TOKEN }}
fetch-depth: 0 # need full history for merges/tags
submodules: recursive

- name: Add upstream remote (${{ env.UPSTREAM_REPO }})
working-directory: ${{ env.DOWNSTREAM_REPO }}
run: |
if ! git remote get-url ${UPSTREAM_REMOTE} >/dev/null 2>&1; then
git remote add ${UPSTREAM_REMOTE} https://github.com/${UPSTREAM_REPO}.git
fi
# Confirm remotes
git remote -v

- name: Configure Git user
working-directory: ${{ env.DOWNSTREAM_REPO }}
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Fetch upstream and local branch
working-directory: ${{ env.DOWNSTREAM_REPO }}
run: |
git fetch ${UPSTREAM_REMOTE} ${UPSTREAM_BRANCH}
git fetch ${DOWNSTREAM_REMOTE} ${DOWNSTREAM_BRANCH}

- name: Compute date tag and create working branch
working-directory: ${{ env.DOWNSTREAM_REPO }}
id: tag
shell: bash
run: |
DATE="$(date +"%Y-%m-%d")"
TAG="${DOWNSTREAM_BRANCH}_IFU_${DATE}"
echo "TAG=${TAG}" >> $GITHUB_OUTPUT
# Start from rocm branch
git checkout -b "$TAG" "${DOWNSTREAM_REMOTE}/${DOWNSTREAM_BRANCH}"

- name: Save ROCm base commit
working-directory: ${{ env.DOWNSTREAM_REPO }}
id: rocm_base
run: |
base_commit=`git rev-parse --short HEAD`
echo "ROCM_BASE_COMMIT=$base_commit" >> $GITHUB_OUTPUT

- name: Merge upstream into working branch (non-interactive)
working-directory: ${{ env.DOWNSTREAM_REPO }}
id: merge
run: |
if git merge "${UPSTREAM_REMOTE}/${UPSTREAM_BRANCH}" --no-edit; then
echo "merge_status=clean" >> $GITHUB_OUTPUT
else
echo "Merge conflicts detected. Committing current resolution snapshot."
git submodule sync
git submodule update --init --recursive
git add -A
git status
git commit --no-edit
echo "merge_status=conflict" >> $GITHUB_OUTPUT
fi

- name: Push branch & tag to fork
working-directory: ${{ env.DOWNSTREAM_REPO }}
run: |
git push ${DOWNSTREAM_REMOTE} "${{ steps.tag.outputs.TAG }}"

- name: Authenticate gh (non-interactive)
working-directory: ${{ env.DOWNSTREAM_REPO }}
run: |
# The GitHub-hosted runner has gh preinstalled.
gh auth status || echo "$GH_TOKEN" | gh auth login --with-token
gh repo set-default "${{ env.DOWNSTREAM_REPO }}"

- name: Create Pull Request with gh
working-directory: ${{ env.DOWNSTREAM_REPO }}
run: |
BASE="${DOWNSTREAM_BRANCH}"
HEAD="${{ steps.tag.outputs.TAG }}"
TITLE="[AUTOGENERATED] $HEAD"
BODY="rocm_base: ${{ steps.rocm_base.outputs.ROCM_BASE_COMMIT }}"

# If a PR for this head already exists, skip creating a new one
if gh pr list --head "$HEAD" --base "$BASE" --state all --json number | grep -q '[0-9]'; then
echo "PR already exists for $HEAD -> $BASE. Skipping creation."
else
gh pr create --base "$BASE" --head "$HEAD" --title "$TITLE" --body "$BODY"
fi

- name: Summarize
run: |
echo "::notice title=IFU Completed::Branch ${{ steps.tag.outputs.TAG }} pushed. PR created (or already existed). Merge status: ${{ steps.merge.outputs.merge_status }}"