Chat route #928
Workflow file for this run
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: PR Milestone Check | |
on: | |
pull_request: | |
types: [opened, reopened, edited, synchronize, milestoned, demilestoned] | |
branches: | |
- "main" | |
- "release-v*.*.*" | |
jobs: | |
check-milestone: | |
name: Check PR Milestone | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v3 | |
- name: Validate PR milestone | |
uses: actions/github-script@v7 | |
with: | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
script: | | |
// Get PR number directly from the event payload | |
const prNumber = context.payload.pull_request.number; | |
// Get PR details | |
const { data: prData } = await github.rest.pulls.get({ | |
owner: 'meilisearch', | |
repo: 'meilisearch', | |
pull_number: prNumber | |
}); | |
// Get base branch name | |
const baseBranch = prData.base.ref; | |
console.log(`Base branch: ${baseBranch}`); | |
// Get PR milestone | |
const prMilestone = prData.milestone; | |
if (!prMilestone) { | |
core.setFailed('PR must have a milestone assigned'); | |
return; | |
} | |
console.log(`PR milestone: ${prMilestone.title}`); | |
// Validate milestone format: vx.y.z | |
const milestoneRegex = /^v\d+\.\d+\.\d+$/; | |
if (!milestoneRegex.test(prMilestone.title)) { | |
core.setFailed(`Milestone "${prMilestone.title}" does not follow the required format vx.y.z`); | |
return; | |
} | |
// For main branch PRs, check if the milestone is the highest one | |
if (baseBranch === 'main') { | |
// Get all milestones | |
const { data: milestones } = await github.rest.issues.listMilestones({ | |
owner: 'meilisearch', | |
repo: 'meilisearch', | |
state: 'open', | |
sort: 'due_on', | |
direction: 'desc' | |
}); | |
// Sort milestones by version number (vx.y.z) | |
const sortedMilestones = milestones | |
.filter(m => milestoneRegex.test(m.title)) | |
.sort((a, b) => { | |
const versionA = a.title.substring(1).split('.').map(Number); | |
const versionB = b.title.substring(1).split('.').map(Number); | |
// Compare major version | |
if (versionA[0] !== versionB[0]) return versionB[0] - versionA[0]; | |
// Compare minor version | |
if (versionA[1] !== versionB[1]) return versionB[1] - versionA[1]; | |
// Compare patch version | |
return versionB[2] - versionA[2]; | |
}); | |
if (sortedMilestones.length === 0) { | |
core.setFailed('No valid milestones found in the repository. Please create at least one milestone with the format vx.y.z'); | |
return; | |
} | |
const highestMilestone = sortedMilestones[0]; | |
console.log(`Highest milestone: ${highestMilestone.title}`); | |
if (prMilestone.title !== highestMilestone.title) { | |
core.setFailed(`PRs targeting the main branch must use the highest milestone (${highestMilestone.title}), but this PR uses ${prMilestone.title}`); | |
return; | |
} | |
} else { | |
// For release branches, the milestone should match the branch version | |
const branchVersion = baseBranch.substring(8); // remove 'release-' | |
if (prMilestone.title !== branchVersion) { | |
core.setFailed(`PRs targeting release branch "${baseBranch}" must use the matching milestone "${branchVersion}", but this PR uses "${prMilestone.title}"`); | |
return; | |
} | |
} | |
console.log('PR milestone validation passed!'); |