LFX Export Merge Notify workflow (cncf/mentoring)
The LFX Export Merge Notify workflow from cncf/mentoring, explained and optimized by Latchkey.
CI health: C - fair
Point runs-on at Latchkey and get run de-duplication, job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.
What it does
This is the LFX Export Merge Notify workflow from the cncf/mentoring repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
name: LFX Export Merge Notify
on:
pull_request:
types: [closed]
branches: [main]
permissions:
issues: write
contents: write # delete the merged export branch
jobs:
notify:
# Skip fork PRs: only same-repo export PRs should notify and delete branches.
if: >-
github.event.pull_request.merged == true
&& github.event.pull_request.head.repo.full_name == github.repository
&& startsWith(github.event.pull_request.head.ref, 'automation/lfx-export-')
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Notify exported issues
uses: actions/github-script@v7
with:
script: |
const path = require('path');
const _lib = (m) => require(path.join(process.env.GITHUB_WORKSPACE || process.cwd(), 'programs/lfx-mentorship/automation/lib', m));
const { parseExportedIssueNumbers } = _lib('notify.js');
const { owner, repo } = context.repo;
const pr = context.payload.pull_request;
const prNumber = pr.number;
const issueNums = parseExportedIssueNumbers(pr.body);
if (issueNums.length === 0) {
console.log('No linked issues found in PR body.');
return;
}
for (const issue_number of issueNums) {
await github.rest.issues.createComment({
owner, repo, issue_number,
body: `✅ Export PR #${prNumber} has been merged.\n\n` +
`The program files are now on \`main\`. Next step: post to LFX platform.\n\n` +
`This issue will be updated when the program is live on LFX.`,
});
console.log(`Notified #${issue_number} about merge of PR #${prNumber}`);
}
- name: Delete merged export branch
uses: actions/github-script@v7
with:
script: |
const path = require('path');
const _lib = (m) => require(path.join(process.env.GITHUB_WORKSPACE || process.cwd(), 'programs/lfx-mentorship/automation/lib', m));
const { isExportBranch } = _lib('notify.js');
const { owner, repo } = context.repo;
const branch = context.payload.pull_request.head.ref;
if (!isExportBranch(branch)) {
console.log(`Not an export branch, skipping delete: ${branch}`);
return;
}
try {
await github.rest.git.deleteRef({ owner, repo, ref: `heads/${branch}` });
console.log(`Deleted merged export branch: ${branch}`);
} catch (e) {
console.log(`Could not delete branch ${branch}: ${e.message}`);
}
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
name: LFX Export Merge Notify on: pull_request: types: [closed] branches: [main] permissions: issues: write contents: write # delete the merged export branch concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: notify: timeout-minutes: 30 # Skip fork PRs: only same-repo export PRs should notify and delete branches. if: >- github.event.pull_request.merged == true && github.event.pull_request.head.repo.full_name == github.repository && startsWith(github.event.pull_request.head.ref, 'automation/lfx-export-') runs-on: latchkey-small steps: - name: Checkout uses: actions/checkout@v4 - name: Notify exported issues uses: actions/github-script@v7 with: script: | const path = require('path'); const _lib = (m) => require(path.join(process.env.GITHUB_WORKSPACE || process.cwd(), 'programs/lfx-mentorship/automation/lib', m)); const { parseExportedIssueNumbers } = _lib('notify.js'); const { owner, repo } = context.repo; const pr = context.payload.pull_request; const prNumber = pr.number; const issueNums = parseExportedIssueNumbers(pr.body); if (issueNums.length === 0) { console.log('No linked issues found in PR body.'); return; } for (const issue_number of issueNums) { await github.rest.issues.createComment({ owner, repo, issue_number, body: `✅ Export PR #${prNumber} has been merged.\n\n` + `The program files are now on \`main\`. Next step: post to LFX platform.\n\n` + `This issue will be updated when the program is live on LFX.`, }); console.log(`Notified #${issue_number} about merge of PR #${prNumber}`); } - name: Delete merged export branch uses: actions/github-script@v7 with: script: | const path = require('path'); const _lib = (m) => require(path.join(process.env.GITHUB_WORKSPACE || process.cwd(), 'programs/lfx-mentorship/automation/lib', m)); const { isExportBranch } = _lib('notify.js'); const { owner, repo } = context.repo; const branch = context.payload.pull_request.head.ref; if (!isExportBranch(branch)) { console.log(`Not an export branch, skipping delete: ${branch}`); return; } try { await github.rest.git.deleteRef({ owner, repo, ref: `heads/${branch}` }); console.log(`Deleted merged export branch: ${branch}`); } catch (e) { console.log(`Could not delete branch ${branch}: ${e.message}`); }
What changed
- Run on Latchkey managed runners with one line (
runs-on), which apply the fixes below automatically and self-heal transient failures. This example useslatchkey-small; pick the runner size that fits the job. - Cancel superseded runs when a branch or PR gets a newer push.
- Add a job timeout so a hung step cannot burn hours of runner time.
This workflow runs 1 job per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.