mirror of
				https://github.com/meilisearch/meilisearch.git
				synced 2025-11-04 09:56:28 +00:00 
			
		
		
		
	Introduce a CI to check milestones and branches
This commit is contained in:
		
							
								
								
									
										100
									
								
								.github/workflows/check-valid-milestone.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								.github/workflows/check-valid-milestone.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
			
		||||
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@v6
 | 
			
		||||
        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!');
 | 
			
		||||
		Reference in New Issue
	
	Block a user