diff --git a/.github/workflows/mirror-to-main.yml b/.github/workflows/mirror-to-main.yml
new file mode 100644
index 00000000000..94446c33ade
--- /dev/null
+++ b/.github/workflows/mirror-to-main.yml
@@ -0,0 +1,116 @@
+name: Mirror Dev to Main
+
+on:
+ push:
+ branches:
+ - "pull-request/[0-9]+"
+
+jobs:
+ cherry-pick-to-main:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ pull-requests: write
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ token: ${{ secrets.PAT }}
+
+ - name: Get PR info
+ id: get-pr-info
+ uses: nv-gha-runners/get-pr-info@main
+
+ - name: Configure Git
+ run: |
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
+ git config --global user.name "GitHub Actions Bot"
+
+ - name: Cherry-pick to main
+ env:
+ GH_TOKEN: ${{ secrets.PAT }}
+ run: |
+ set -x
+
+ PR_NUMBER=${{ fromJSON(steps.get-pr-info.outputs.pr-info || '{}').number }}
+ BASE_REF="${{ fromJSON(steps.get-pr-info.outputs.pr-info).base.ref }}"
+ HAS_MIRROR_MAIN_LABEL=$(gh pr view $PR_NUMBER --json labels | jq '[.labels[].name] | any(. == "mirror-to-main")' || echo "false")
+ TARGET_BRANCH="cherry-pick-$PR_NUMBER-into-main"
+
+ # Skip if not labeled with mirror-to-main
+ if [ "$HAS_MIRROR_MAIN_LABEL" != "true" ]; then
+ echo "PR is not labeled with mirror-to-main, will not mirror to main."
+ exit 0
+ fi
+
+ # Skip if not targeting dev
+ if [ "$BASE_REF" != "dev" ]; then
+ echo "PR is not targeting dev, will not mirror to main."
+ exit 0
+ fi
+
+ # Check if target branch already exists
+ if git ls-remote --heads origin "refs/heads/$TARGET_BRANCH" | grep -q .; then
+ echo "Target branch already exists, will not cherry-pick again."
+ exit 0
+ fi
+
+ # Get PR details
+ PR_AUTHOR="${{ fromJSON(steps.get-pr-info.outputs.pr-info).user.login }}"
+ PR_TITLE="${{ fromJSON(steps.get-pr-info.outputs.pr-info).title }}"
+ SOURCE_BRANCH="${{ fromJSON(steps.get-pr-info.outputs.pr-info).head.ref }}"
+ SOURCE_REPO="${{ fromJSON(steps.get-pr-info.outputs.pr-info).head.repo.full_name }}"
+
+ # Fetch all branches
+ git fetch origin dev
+
+ # Handle forks vs same repo
+ if [ "$SOURCE_REPO" = "${{ github.repository }}" ]; then
+ git fetch origin "$SOURCE_BRANCH"
+ git checkout "$SOURCE_BRANCH"
+ else
+ git fetch "https://github.com/$SOURCE_REPO.git" "$SOURCE_BRANCH"
+ git checkout FETCH_HEAD
+ fi
+
+ # Find commit range to cherry-pick
+ START_COMMIT=$(git merge-base origin/dev HEAD)
+ END_COMMIT=$(git rev-parse HEAD)
+
+ # Create cherry-pick branch from main
+ git fetch origin main
+ git checkout main
+ git checkout -b "$TARGET_BRANCH"
+
+ # Cherry-pick commits
+ if ! git cherry-pick "$START_COMMIT..$END_COMMIT"; then
+ # Comment on the original PR about the failure
+ COMMENT_BODY=$(cat <<'EOF'
+ ❌ **Cherry-pick to main failed**
+
+ The cherry-pick encountered conflicts and could not be completed automatically.
+
+ **Next steps:**
+ 1. Manually create a PR with these changes to main
+ 2. Resolve any conflicts
+ EOF
+ )
+
+ gh pr comment $PR_NUMBER --body "$COMMENT_BODY"
+ exit 1
+ fi
+
+ # Push branch
+ git push -u origin "$TARGET_BRANCH"
+
+ # Create PR to main
+ gh pr create \
+ --base main \
+ --head "$TARGET_BRANCH" \
+ --title "cp: \`$PR_TITLE ($PR_NUMBER)\` into \`main\`" \
+ --body "[🤖]: Hi @$PR_AUTHOR 👋
We've cherry-picked \`$PR_TITLE (#$PR_NUMBER)\` into \`main\` for you! 🚀
Please review and approve this cherry-pick at your convenience!" \
+ --label "cherry-pick" \
+ --reviewer "$PR_AUTHOR"
+