Skip to content
Latchkey

Assign Latest Milestone workflow (Unidata/siphon)

The Assign Latest Milestone workflow from Unidata/siphon, explained and optimized by Latchkey.

A

CI health: A - excellent

Point runs-on at Latchkey and get job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: Unidata/siphon.github/workflows/assign-milestone.ymlLicense BSD-3-ClauseView source

What it does

This is the Assign Latest Milestone workflow from the Unidata/siphon repository, a real project running GitHub Actions. It is shown here with attribution under its BSD-3-Clause license.

Below, Latchkey shows a faster, safer version produced by its optimization engine.

The workflow

workflow (.yml)
# If a PR doesn't have a milestone assigned when it's merged, assign it the
# one that's scheduled next.
name: Assign Latest Milestone
on:
  pull_request_target:
    types: [closed]
    branches: [main]

permissions:
  pull-requests: write
  issues: write

jobs:
  sync:
    name: Assign Latest Milestone
    runs-on: ubuntu-latest
    steps:
      - uses: actions/github-script@v9
        name: Run script
        with:
          script: |
            if (!context.payload.pull_request.merged) {
              console.log('PR was not merged, skipping.');
              return;
            }
            if (!!context.payload.pull_request.milestone) {
              console.log('PR has existing milestone, skipping.');
              return;
            }
            if (context.payload.pull_request.user.type === 'Bot') {
              console.log('Ignoring Bot PR');
              return;
            }
            milestones = await github.rest.issues.listMilestones({
              owner: context.repo.owner,
              repo: context.repo.repo,
              state: 'open',
              sort: 'due_on',
              direction: 'asc'
            })

            if (milestones.data.length === 0) {
              console.log('There are no milestones, skipping.');
              return;
            }

            console.log(`Adding to milestone: ${milestones.data[0].number}`);
            result = await github.rest.issues.update({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.payload.number,
              milestone: milestones.data[0].number
            });
            console.log(result);

The same workflow, on Latchkey

Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.

# If a PR doesn't have a milestone assigned when it's merged, assign it the
# one that's scheduled next.
name: Assign Latest Milestone
on:
  pull_request_target:
    types: [closed]
    branches: [main]
 
permissions:
  pull-requests: write
  issues: write
 
jobs:
  sync:
    timeout-minutes: 30
    name: Assign Latest Milestone
    runs-on: latchkey-small
    steps:
      - uses: actions/github-script@v9
        name: Run script
        with:
          script: |
            if (!context.payload.pull_request.merged) {
              console.log('PR was not merged, skipping.');
              return;
            }
            if (!!context.payload.pull_request.milestone) {
              console.log('PR has existing milestone, skipping.');
              return;
            }
            if (context.payload.pull_request.user.type === 'Bot') {
              console.log('Ignoring Bot PR');
              return;
            }
            milestones = await github.rest.issues.listMilestones({
              owner: context.repo.owner,
              repo: context.repo.repo,
              state: 'open',
              sort: 'due_on',
              direction: 'asc'
            })
 
            if (milestones.data.length === 0) {
              console.log('There are no milestones, skipping.');
              return;
            }
 
            console.log(`Adding to milestone: ${milestones.data[0].number}`);
            result = await github.rest.issues.update({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.payload.number,
              milestone: milestones.data[0].number
            });
            console.log(result);
 

What changed

This workflow runs 1 job per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow