Skip to content

Vectorize weighted distance in the sonic similarity provider #3711

Vectorize weighted distance in the sonic similarity provider

Vectorize weighted distance in the sonic similarity provider #3711

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 }}