Auto-port to 5.0 workflow (netty/netty)
The Auto-port to 5.0 workflow from netty/netty, 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.
What it does
This is the Auto-port to 5.0 workflow from the netty/netty 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
workflow (.yml)
name: Auto-port to 5.0
on:
pull_request_target:
types:
- closed
- labeled
branches:
- '4.1'
- '4.2'
jobs:
autoport:
name: "Auto-porting to 5.0"
concurrency:
group: port-50-${{ github.event.pull_request.number }}
cancel-in-progress: true
if: github.event.pull_request.merged && contains(github.event.pull_request.labels.*.name, 'needs-cherry-pick-5.0')
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
ssh-key: ${{ secrets.SSH_PRIVATE_KEY_PEM }}
ssh-known-hosts: ${{ secrets.SSH_KNOWN_HOSTS }}
fetch-depth: '0' # Cherry-pick needs full history
- name: Setup git configuration
run: |
git config --global user.email "netty-project-bot@users.noreply.github.com"
git config --global user.name "Netty Project Bot"
- name: Create auto-port PR branch and cherry-pick
id: cherry-pick
run: |
MERGE_COMMIT="${{ github.event.pull_request.merge_commit_sha }}"
echo "Auto-porting commit: $MERGE_COMMIT"
PORT_BRANCH="auto-port-pr-${{ github.event.pull_request.number }}-to-5.0"
if [[ $(git branch --show-current) != '5.0' ]]; then
git fetch origin 5.0:5.0
fi
git checkout -b "$PORT_BRANCH" 5.0
if git cherry-pick -x "$MERGE_COMMIT"; then
echo "Cherry-pick successful"
else
echo "Cherry-pick failed - conflicts detected"
git cherry-pick --abort
exit 1
fi
echo "branch=$PORT_BRANCH" >> "$GITHUB_OUTPUT"
- name: Push auto-port branch
id: push
if: steps.cherry-pick.outcome == 'success'
run: |
if ! git push origin "${{ steps.cherry-pick.outputs.branch }}"; then
echo "Auto-port branch push failed"
exit 1
fi
- name: Create pull request
id: create-pr
if: steps.cherry-pick.outcome == 'success'
uses: actions/github-script@v8
with:
github-token: '${{ secrets.PAT_TOKEN_READ_WRITE_PR }}'
script: |
const { data: pr } = await github.rest.pulls.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `Auto-port 5.0: ${context.payload.pull_request.title}`,
head: '${{ steps.cherry-pick.outputs.branch }}',
base: '5.0',
body: `Auto-port of #${context.payload.pull_request.number} to 5.0\n` +
`Cherry-picked commit: ${context.payload.pull_request.merge_commit_sha}\n\n---\n` +
`${context.payload.pull_request.body || ''}`
});
console.log(`Created auto-port PR: ${pr.html_url}`);
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body: `Auto-port PR for 5.0: #${pr.number}`
});
# Important: This script MUST run with the default GITHUB_TOKEN to avoid triggering other actions.
- name: Remove triggering label
if: steps.create-pr.outcome == 'success'
uses: actions/github-script@v8
with:
script: |
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
name: 'needs-cherry-pick-5.0'
});
- name: Report cherry-pick conflicts
if: failure() && steps.cherry-pick.outcome == 'failure'
uses: actions/github-script@v8
with:
github-token: '${{ secrets.PAT_TOKEN_READ_WRITE_PR }}'
script: |
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body: `Could not create auto-port PR.\nGot conflicts when cherry-picking onto 5.0.`
});
- name: Report auto-port branch push failure
if: failure() && steps.push.outcome == 'failure'
uses: actions/github-script@v8
with:
github-token: '${{ secrets.PAT_TOKEN_READ_WRITE_PR }}'
script: |
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body: `Could not create auto-port PR.\n`+
`I could cherry-pick onto 5.0 just fine, but pushing the new branch failed.`
});
- name: Remove branch on PR create failure
if: failure() && steps.cherry-pick.outputs.branch
run: |
git push -d origin "${{ steps.cherry-pick.outputs.branch }}"
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
name: Auto-port to 5.0 on: pull_request_target: types: - closed - labeled branches: - '4.1' - '4.2' jobs: autoport: timeout-minutes: 30 name: "Auto-porting to 5.0" concurrency: group: port-50-${{ github.event.pull_request.number }} cancel-in-progress: true if: github.event.pull_request.merged && contains(github.event.pull_request.labels.*.name, 'needs-cherry-pick-5.0') runs-on: latchkey-small steps: - name: Checkout repository uses: actions/checkout@v6 with: ssh-key: ${{ secrets.SSH_PRIVATE_KEY_PEM }} ssh-known-hosts: ${{ secrets.SSH_KNOWN_HOSTS }} fetch-depth: '0' # Cherry-pick needs full history - name: Setup git configuration run: | git config --global user.email "netty-project-bot@users.noreply.github.com" git config --global user.name "Netty Project Bot" - name: Create auto-port PR branch and cherry-pick id: cherry-pick run: | MERGE_COMMIT="${{ github.event.pull_request.merge_commit_sha }}" echo "Auto-porting commit: $MERGE_COMMIT" PORT_BRANCH="auto-port-pr-${{ github.event.pull_request.number }}-to-5.0" if [[ $(git branch --show-current) != '5.0' ]]; then git fetch origin 5.0:5.0 fi git checkout -b "$PORT_BRANCH" 5.0 if git cherry-pick -x "$MERGE_COMMIT"; then echo "Cherry-pick successful" else echo "Cherry-pick failed - conflicts detected" git cherry-pick --abort exit 1 fi echo "branch=$PORT_BRANCH" >> "$GITHUB_OUTPUT" - name: Push auto-port branch id: push if: steps.cherry-pick.outcome == 'success' run: | if ! git push origin "${{ steps.cherry-pick.outputs.branch }}"; then echo "Auto-port branch push failed" exit 1 fi - name: Create pull request id: create-pr if: steps.cherry-pick.outcome == 'success' uses: actions/github-script@v8 with: github-token: '${{ secrets.PAT_TOKEN_READ_WRITE_PR }}' script: | const { data: pr } = await github.rest.pulls.create({ owner: context.repo.owner, repo: context.repo.repo, title: `Auto-port 5.0: ${context.payload.pull_request.title}`, head: '${{ steps.cherry-pick.outputs.branch }}', base: '5.0', body: `Auto-port of #${context.payload.pull_request.number} to 5.0\n` + `Cherry-picked commit: ${context.payload.pull_request.merge_commit_sha}\n\n---\n` + `${context.payload.pull_request.body || ''}` }); console.log(`Created auto-port PR: ${pr.html_url}`); await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.payload.pull_request.number, body: `Auto-port PR for 5.0: #${pr.number}` }); # Important: This script MUST run with the default GITHUB_TOKEN to avoid triggering other actions. - name: Remove triggering label if: steps.create-pr.outcome == 'success' uses: actions/github-script@v8 with: script: | await github.rest.issues.removeLabel({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.payload.pull_request.number, name: 'needs-cherry-pick-5.0' }); - name: Report cherry-pick conflicts if: failure() && steps.cherry-pick.outcome == 'failure' uses: actions/github-script@v8 with: github-token: '${{ secrets.PAT_TOKEN_READ_WRITE_PR }}' script: | await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.payload.pull_request.number, body: `Could not create auto-port PR.\nGot conflicts when cherry-picking onto 5.0.` }); - name: Report auto-port branch push failure if: failure() && steps.push.outcome == 'failure' uses: actions/github-script@v8 with: github-token: '${{ secrets.PAT_TOKEN_READ_WRITE_PR }}' script: | await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.payload.pull_request.number, body: `Could not create auto-port PR.\n`+ `I could cherry-pick onto 5.0 just fine, but pushing the new branch failed.` }); - name: Remove branch on PR create failure if: failure() && steps.cherry-pick.outputs.branch run: | git push -d origin "${{ steps.cherry-pick.outputs.branch }}"
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. - 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.