Skip to content
Merged
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
145 changes: 145 additions & 0 deletions .github/workflows/pr-import.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# Import Subrepo PR Workflow
# --------------------------
# This workflow imports an open PR from a sub-repository into the monorepo.
# It is intended for maintainers to migrate pending pull requests from
# the subrepos, to help developers onboard to the monorepo sooner.
#
# Trigger: Manually via `workflow_dispatch` with the following inputs:
# - subrepo-prefix: Path within the monorepo where the subrepo lives (e.g., "projects/rocblas")
# - subrepo-pr-number: PR number in the subrepo to import
# - subrepo-repo: Full subrepo or fork name (e.g., "ROCm/rocBLAS" or "user/rocBLAS-fork")
# - subrepo-upstream: Canonical subrepo repo name (e.g., "ROCm/rocBLAS")
#
# Steps:
# 1. Validate that the caller has 'admin' or 'maintain' permission on the monorepo
# 2. Generate a GitHub App token for authenticated API access
# 3. Checkout only the necessary parts of the monorepo (sparse checkout)
# 4. Fetch PR metadata from the subrepo using GitHub CLI
# 5. Create a new branch and import the PR using `git subtree pull`
# 6. Create a corresponding draft PR in the monorepo with metadata preserved
#
# Notes:
# - This workflow requires GitHub App credentials (APP_ID and APP_PRIVATE_KEY)
# - The resulting monorepo PR is a draft and includes attribution to the original author

name: Import Subrepo PR

on:
workflow_dispatch:
inputs:
subrepo-prefix:
description: "Monorepo path prefix (e.g., projects/rocblas)"
required: true
subrepo-pr-number:
description: "Subrepo PR number to import"
required: true
subrepo-repo:
description: "Full name of subrepo repo or fork (e.g., ROCm/rocBLAS or user/rocBLAS-fork)"
required: true
subrepo-upstream:
description: "Canonical subrepo repo (e.g., ROCm/rocBLAS)"
required: true

jobs:
import:
runs-on: ubuntu-24.04
steps:
- name: Validate maintainer permissions
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "Actor is: ${{ github.actor }}"
PERMISSION=$(gh api \
repos/${{ github.repository }}/collaborators/${{ github.actor }}/permission \
--jq .permission)
if [[ "$PERMISSION" != "admin" && "$PERMISSION" != "maintain" ]]; then
echo "❌ User ${{ github.actor }} is not authorized to run this workflow"
exit 1
fi

- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}

- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
sparse-checkout: |
.github
${{ github.event.inputs.subrepo-prefix }}
sparse-checkout-cone-mode: true
token: ${{ steps.generate-token.outputs.token }}
fetch-depth: 0 #for subtree operations

- name: Set up Git user
run: |
git config user.name "assistant-librarian[bot]"
git config user.email "assistant-librarian[bot]@users.noreply.github.com"

- name: Fetch subrepo PR info using gh
id: prdata
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
PR_JSON=$(gh pr view ${{ github.event.inputs.subrepo-pr-number }} \
--repo ${{ github.event.inputs.subrepo-repo }} \
--json title,body,headRefName,headRepository \
--jq '{title: .title, body: .body, head_ref: .headRefName, head_repo: .headRepository.cloneUrl}')

echo "$PR_JSON" > pr.json

echo "title=$(jq -r .title pr.json)" >> $GITHUB_OUTPUT

{
echo 'body<<EOF'
jq -r .body pr.json
echo 'EOF'
} >> $GITHUB_OUTPUT

echo "head_ref=$(jq -r .head_ref pr.json)" >> $GITHUB_OUTPUT
echo "head_repo=$(jq -r .head_repo pr.json)" >> $GITHUB_OUTPUT

- name: Create new branch for import
id: import-branch
run: |
BRANCH_NAME=$(echo "${{ steps.prdata.outputs.head_ref }}" | sed 's|/|_|g')
IMPORT_BRANCH="import/$BRANCH_NAME"
echo "import_branch=$IMPORT_BRANCH" >> $GITHUB_OUTPUT
git checkout -b "$IMPORT_BRANCH"

- name: Split subrepo prefix from main branch
run: |
git subtree pull --prefix=${{ github.event.inputs.subrepo-prefix }} https://github.com/${{ github.event.inputs.subrepo-repo }} ${{ steps.prdata.outputs.head_ref }}
git push origin ${{ steps.import-branch.outputs.import_branch }}

- name: Create monorepo PR
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
IMPORT_BRANCH="import/${{ github.event.inputs.subrepo-prefix }}/pr-${{ github.event.inputs.subrepo-pr-number }}"
PR_TITLE="${{ steps.prdata.outputs.title }}"
SUBREPO_REPO="${{ github.event.inputs.subrepo-repo }}"
SUBREPO_PR_NUMBER="${{ github.event.inputs.subrepo-pr-number }}"
SUBREPO_URL="https://github.com/$SUBREPO_REPO/pull/$SUBREPO_PR_NUMBER"

AUTHOR=$(gh pr view "$SUBREPO_PR_NUMBER" --repo "$SUBREPO_REPO" --json author --jq .author.login)

echo "${{ steps.prdata.outputs.body }}" > pr_body.txt

{
echo ""
echo "---"
echo "🔁 Imported from [$SUBREPO_REPO#$SUBREPO_PR_NUMBER]($SUBREPO_URL)"
echo "🧑‍💻 Originally authored by @$AUTHOR"
} >> pr_body.txt

gh pr create \
--draft \
--base main \
--head "${{ steps.import-branch.outputs.import_branch }}" \
--title "$PR_TITLE" \
--body-file pr_body.txt