Skip to content
Latchkey

Create release branch workflow (TryGhost/Ghost)

The Create release branch workflow from TryGhost/Ghost, 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: TryGhost/Ghost.github/workflows/create-release-branch.ymlLicense MITView source

What it does

This is the Create release branch workflow from the TryGhost/Ghost repository, a real project running GitHub Actions. It is shown here with attribution under its MIT license.

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

The workflow

workflow (.yml)
name: Create release branch
on:
  workflow_dispatch:
    inputs:
      base-ref:
        description: 'Git ref to base from (defaults to latest tag)'
        type: string
        default: 'latest'
        required: false
      bump-type:
        description: 'Version bump type (patch, minor)'
        type: string
        required: false
        default: 'patch'
env:
  FORCE_COLOR: 1
permissions:
  contents: write
jobs:
  create-branch:
    if: github.repository == 'TryGhost/Ghost'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        if: inputs.base-ref == 'latest'
        with:
          ref: main
          fetch-depth: 0
          submodules: true

      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        if: inputs.base-ref != 'latest'
        with:
          ref: ${{ inputs.base-ref }}
          fetch-depth: 0
          submodules: true

      - name: Checkout most recent tag
        run: git checkout "$(git describe --tags --abbrev=0 --match=v*)"
        if: inputs.base-ref == 'latest'

      - uses: asdf-vm/actions/install@b7bcd026f18772e44fe1026d729e1611cc435d47 # v4
        with:
          tool_versions: |
            semver 3.3.0

      - run: |
          CURRENT_TAG=$(git describe --tags --abbrev=0 --match=v*)
          NEW_VERSION=$(semver bump "$BUMP_TYPE_INPUT" "$CURRENT_TAG")
          printf 'CURRENT_SHA=%s\n' "$(git rev-parse HEAD)" >> "$GITHUB_ENV"
          printf 'NEW_VERSION=%s\n' "$NEW_VERSION" >> "$GITHUB_ENV"
        env:
          BUMP_TYPE_INPUT: ${{ inputs.bump-type }}

      - name: Create branch
        uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
        with:
          script: |
            const branchName = `v${process.env.NEW_VERSION}`;
            console.log(`Creating branch: ${branchName}`);
            await github.request('POST /repos/{owner}/{repo}/git/refs', {
              owner: context.repo.owner,
              repo: context.repo.repo,
              ref: `refs/heads/${branchName}`,
              sha: process.env.CURRENT_SHA
            });

The same workflow, on Latchkey

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

name: Create release branch
on:
  workflow_dispatch:
    inputs:
      base-ref:
        description: 'Git ref to base from (defaults to latest tag)'
        type: string
        default: 'latest'
        required: false
      bump-type:
        description: 'Version bump type (patch, minor)'
        type: string
        required: false
        default: 'patch'
env:
  FORCE_COLOR: 1
permissions:
  contents: write
jobs:
  create-branch:
    timeout-minutes: 30
    if: github.repository == 'TryGhost/Ghost'
    runs-on: latchkey-small
    steps:
      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        if: inputs.base-ref == 'latest'
        with:
          ref: main
          fetch-depth: 0
          submodules: true
 
      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        if: inputs.base-ref != 'latest'
        with:
          ref: ${{ inputs.base-ref }}
          fetch-depth: 0
          submodules: true
 
      - name: Checkout most recent tag
        run: git checkout "$(git describe --tags --abbrev=0 --match=v*)"
        if: inputs.base-ref == 'latest'
 
      - uses: asdf-vm/actions/install@b7bcd026f18772e44fe1026d729e1611cc435d47 # v4
        with:
          tool_versions: |
            semver 3.3.0
 
      - run: |
          CURRENT_TAG=$(git describe --tags --abbrev=0 --match=v*)
          NEW_VERSION=$(semver bump "$BUMP_TYPE_INPUT" "$CURRENT_TAG")
          printf 'CURRENT_SHA=%s\n' "$(git rev-parse HEAD)" >> "$GITHUB_ENV"
          printf 'NEW_VERSION=%s\n' "$NEW_VERSION" >> "$GITHUB_ENV"
        env:
          BUMP_TYPE_INPUT: ${{ inputs.bump-type }}
 
      - name: Create branch
        uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
        with:
          script: |
            const branchName = `v${process.env.NEW_VERSION}`;
            console.log(`Creating branch: ${branchName}`);
            await github.request('POST /repos/{owner}/{repo}/git/refs', {
              owner: context.repo.owner,
              repo: context.repo.repo,
              ref: `refs/heads/${branchName}`,
              sha: process.env.CURRENT_SHA
            });
 

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