Vectorize weighted distance in the sonic similarity provider #3711
This file contains hidden or 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
| name: Backport to stable | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| on: | |
| push: | |
| branches: | |
| - dev | |
| pull_request_target: | |
| types: [labeled] | |
| branches: | |
| - dev | |
| jobs: | |
| backport: | |
| name: Backport PRs with 'backport-to-stable' label to stable | |
| runs-on: ubuntu-latest | |
| if: | | |
| (github.event_name == 'push' && github.event.commits[0].distinct == true) || | |
| (github.event_name == 'pull_request_target') | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 # Needed for full git history | |
| - name: Determine workflow trigger and context | |
| id: trigger | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| // Determine if this is a push or label event | |
| const isPushEvent = context.eventName === 'push'; | |
| const isLabelEvent = context.eventName === 'pull_request_target'; | |
| core.setOutput('is_push_event', isPushEvent); | |
| core.setOutput('is_label_event', isLabelEvent); | |
| // Early exit for wrong label in label events | |
| if (isLabelEvent) { | |
| const labelName = context.payload.label?.name; | |
| if (labelName !== 'backport-to-stable') { | |
| console.log(`Label '${labelName}' is not backport-to-stable, skipping`); | |
| process.exit(0); | |
| } | |
| } | |
| - name: Get merged PR info | |
| id: prinfo | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| const isPushEvent = '${{ steps.trigger.outputs.is_push_event }}' === 'true'; | |
| const isLabelEvent = '${{ steps.trigger.outputs.is_label_event }}' === 'true'; | |
| let merged; | |
| if (isPushEvent) { | |
| // Existing logic: Find PR from commit | |
| const pr = await github.rest.pulls.list({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| state: 'closed', | |
| base: 'dev', | |
| sort: 'updated', | |
| direction: 'desc', | |
| per_page: 10 | |
| }); | |
| merged = pr.data.find(p => p.merge_commit_sha === context.payload.head_commit.id); | |
| if (!merged) return core.setFailed('No merged PR found for this commit.'); | |
| } else if (isLabelEvent) { | |
| // New logic: Get PR from label event context | |
| const pr = context.payload.pull_request; | |
| // Verify PR is merged (exit gracefully if not) | |
| if (!pr.merged_at) { | |
| console.log('PR is not merged yet, skipping backport'); | |
| process.exit(0); | |
| } | |
| // Fetch full PR details to get merge commit SHA | |
| const fullPR = await github.rest.pulls.get({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: pr.number | |
| }); | |
| merged = fullPR.data; | |
| } | |
| core.setOutput('pr_number', merged.number); | |
| core.setOutput('pr_title', merged.title); | |
| core.setOutput('pr_labels', merged.labels.map(l => l.name).join(',')); | |
| core.setOutput('merge_commit_sha', merged.merge_commit_sha); | |
| - name: Check for backport-to-stable label | |
| id: checklabel | |
| run: | | |
| echo "PR labels: ${{ steps.prinfo.outputs.pr_labels }}" | |
| if [[ "${{ steps.prinfo.outputs.pr_labels }}" == *"backport-to-stable"* ]]; then | |
| echo "backport-to-stable label found, proceeding with backport." | |
| echo "should_backport=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "No backport-to-stable label found, skipping backport." | |
| echo "should_backport=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Set up Git user | |
| if: steps.checklabel.outputs.should_backport == 'true' | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| - name: Calculate next patch version | |
| if: steps.checklabel.outputs.should_backport == 'true' | |
| id: nextver | |
| run: | | |
| git fetch origin stable --tags | |
| # Filter out beta/rc tags and get only stable versions (e.g., 2.5.5, v2.5.5) | |
| latest_tag=$(git tag --merged origin/stable --sort=-v:refname | grep -E '^v?[0-9]+\.[0-9]+\.[0-9]+$' | head -1) | |
| if [[ -z "$latest_tag" ]]; then | |
| echo "No stable tags found on stable branch" >&2 | |
| exit 1 | |
| fi | |
| echo "Latest stable tag: $latest_tag" | |
| # Remove 'v' prefix if present | |
| version="$latest_tag" | |
| if [[ "$version" =~ ^v ]]; then | |
| version="${version#v}" | |
| fi | |
| # Parse version components | |
| if [[ "$version" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then | |
| major="${BASH_REMATCH[1]}" | |
| minor="${BASH_REMATCH[2]}" | |
| patch="${BASH_REMATCH[3]}" | |
| else | |
| echo "Invalid version format: $version" >&2 | |
| exit 1 | |
| fi | |
| next_patch=$((patch + 1)) | |
| next_version="$major.$minor.$next_patch" | |
| echo "Current version: $version" | |
| echo "Next version: $next_version" | |
| echo "next_patch_version=$next_version" >> $GITHUB_OUTPUT | |
| - name: Create or update backport branch | |
| if: steps.checklabel.outputs.should_backport == 'true' | |
| id: create_or_update_backport_branch | |
| run: | | |
| next_version="${{ steps.nextver.outputs.next_patch_version }}" | |
| branch_name="backport/$next_version" | |
| echo "Creating/updating branch: $branch_name" | |
| # Check if branch already exists on remote | |
| git fetch origin $branch_name || true | |
| if git show-ref --verify --quiet refs/remotes/origin/$branch_name; then | |
| echo "Branch $branch_name already exists, checking out" | |
| git checkout -B $branch_name origin/$branch_name | |
| else | |
| echo "Branch $branch_name does not exist, creating from stable" | |
| git checkout -b $branch_name origin/stable | |
| fi | |
| echo "branch_name=$branch_name" >> $GITHUB_OUTPUT | |
| - name: Cherry-pick commit | |
| if: steps.checklabel.outputs.should_backport == 'true' | |
| run: | | |
| # Check if commit is already in the branch to avoid redundant cherry-picks | |
| if git log --format=%H | grep -q "^${{ steps.prinfo.outputs.merge_commit_sha }}$"; then | |
| echo "Commit ${{ steps.prinfo.outputs.merge_commit_sha }} already exists in backport branch, skipping cherry-pick" | |
| exit 0 | |
| fi | |
| # Try cherry-pick with --empty=drop to handle redundant commits gracefully | |
| if git cherry-pick --empty=drop ${{ steps.prinfo.outputs.merge_commit_sha }}; then | |
| echo "Cherry-pick successful" | |
| else | |
| echo 'Cherry-pick failed, please resolve conflicts manually.' | |
| exit 1 | |
| fi | |
| - name: Push backport branch | |
| if: steps.checklabel.outputs.should_backport == 'true' | |
| run: | | |
| git push origin ${{ steps.create_or_update_backport_branch.outputs.branch_name }}:${{ steps.create_or_update_backport_branch.outputs.branch_name }} --force | |
| - name: Create or update backport PR with cherry-picked commits | |
| if: steps.checklabel.outputs.should_backport == 'true' | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| const pr_number = process.env.pr_number; | |
| const pr_title = process.env.pr_title; | |
| const next_patch_version = process.env.next_patch_version; | |
| const branch = process.env.branch_name; | |
| const cherry_commit = process.env.cherry_commit; | |
| console.log(`Processing backport for PR #${pr_number}: ${pr_title}`); | |
| console.log(`Next patch version: ${next_patch_version}`); | |
| console.log(`Branch: ${branch}`); | |
| console.log(`Cherry-pick commit: ${cherry_commit}`); | |
| const prs = await github.rest.pulls.list({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| state: 'open', | |
| head: `${context.repo.owner}:${branch}`, | |
| base: 'stable' | |
| }); | |
| const commit_url = `https://github.com/${context.repo.owner}/${context.repo.repo}/commit/${cherry_commit}`; | |
| const commit_item = `- [${cherry_commit.substring(0,7)}](${commit_url}) - ${pr_title} (#${pr_number})`; | |
| if (prs.data.length === 0) { | |
| // Create new PR with initial commit in body | |
| console.log('Creating new backport PR'); | |
| await github.rest.pulls.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| title: `[Backport to stable] ${next_patch_version}`, | |
| head: branch, | |
| base: 'stable', | |
| body: `Automated backport PR for stable release ${next_patch_version} with cherry-picked commits:\n\n${commit_item}` | |
| }); | |
| } else { | |
| // Update PR body to append new commit if not already present | |
| console.log('Updating existing backport PR'); | |
| const pr = prs.data[0]; | |
| let body = pr.body || ''; | |
| if (!body.includes(cherry_commit.substring(0,7))) { | |
| // Try to find the start of the list (case-insensitive) | |
| const listMatch = body.match(/(cherry-picked commits:\n\n)([\s\S]*)/i); | |
| if (listMatch) { | |
| // Append to existing list | |
| const before = listMatch[1]; | |
| const list = listMatch[2].trim(); | |
| const newList = list + '\n' + commit_item; | |
| body = body.replace(/(cherry-picked commits:\n\n)([\s\S]*)/i, before + newList); | |
| } else { | |
| // Add new list | |
| body = body.trim() + `\n\nCherry-picked commits:\n\n${commit_item}`; | |
| } | |
| await github.rest.pulls.update({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: pr.number, | |
| body | |
| }); | |
| } else { | |
| console.log('Commit already exists in PR body, skipping update'); | |
| } | |
| } | |
| env: | |
| pr_number: ${{ steps.prinfo.outputs.pr_number }} | |
| pr_title: ${{ steps.prinfo.outputs.pr_title }} | |
| next_patch_version: ${{ steps.nextver.outputs.next_patch_version }} | |
| branch_name: ${{ steps.create_or_update_backport_branch.outputs.branch_name }} | |
| cherry_commit: ${{ steps.prinfo.outputs.merge_commit_sha }} |