Skip to content
Latchkey

Update README workflow (rancher/rke)

The Update README workflow from rancher/rke, 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: rancher/rke.github/workflows/update-readme.ymlLicense Apache-2.0View source

What it does

This is the Update README workflow from the rancher/rke 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: Update README
on:
  workflow_dispatch:
  release:
    types: [published]

permissions:
  contents: write
  pull-requests: write
  id-token: write

jobs:
  update-readme:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
    - name: Update README file
      run: |
       tagstmpfile=$(mktemp)
       readmetmpfile=$(mktemp)
       gh api graphql -F owner='rancher' -F name='rke' -f query='query($name: String!, $owner: String!) {repository(owner: $owner, name: $name) {releases(first: 100) {nodes { tagName }}}}' |jq -r .data.repository.releases[] > $tagstmpfile
       for rke_major_minor in 1.8 1.7 1.6; do
         latest=$(jq -r 'first(.[] | select(.tagName | startswith("v'"${rke_major_minor}"'")) | select(.tagName | contains("rc") | not) | .tagName)' $tagstmpfile)
         if [ -n "${latest}" ]; then
           echo "* v${rke_major_minor}" >> $readmetmpfile
           echo "  * ${latest} - Read the full release [notes](https://github.com/rancher/rke/releases/tag/${latest})." >> $readmetmpfile
         fi
       done
       sed -e '/## Latest Release/r '"$readmetmpfile"'' -e 's/CURRENTYEAR/'"$(date +%Y)"'/g' README-template.md > README.md
      env:
        GH_TOKEN: ${{ github.token }}
    - name: Check for repository changes
      run: |
        if git diff --name-only --exit-code; then
          echo "No changes found in repository after updating README"
          echo "changes_exist=false" >> $GITHUB_ENV
        else
          echo "Changes found in repository after updating README:"
          git diff --name-only
          echo "changes_exist=true" >> $GITHUB_ENV
        fi
    - name: Create branch, commit and push
      if: ${{ env.changes_exist == 'true' }}
      id: branch
      run: |
        BRANCH="githubaction-update-readme-$(date +%Y-%m-%d-%H-%M-%S)"
        echo "branch=${BRANCH}" >> $GITHUB_OUTPUT
        git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
        git config --global user.name "github-actions[bot]"
        git checkout -b "$BRANCH"
        git commit -a -m "update README with latest"
        git push origin "$BRANCH"

    # GitHub does not trigger workflows for pull requests made by a GitHub Actions token (GITHUB_TOKEN) by default.
    # Therefore, we need to retrieve a Personal Access Token (PAT)
    - name: Retrieve token from vault
      uses: rancher-eio/read-vault-secrets@0da85151ad1f19ed7986c41587e45aac1ace74b6 # v3
      with:
        secrets: |
          secret/data/github/repo/${{ github.repository }}/github-token/credentials token | PAT_TOKEN ;

    - name: Create Pull Request
      if: ${{ env.changes_exist == 'true' }}
      id: cpr
      env:
        SOURCE_BRANCH: ${{ steps.branch.outputs.branch }}
        GH_TOKEN: ${{ env.PAT_TOKEN }}
      run: |
        PR_TITLE="[${GITHUB_REF_NAME}] update README with latest"
        PR_BODY="Auto-generated by GitHub Actions"
        EXISTING_PR=$(gh pr list --limit 500 --json title,url | jq --arg title "${PR_TITLE}" -r '.[] | select(.title==$title) | .url')
        CREATED_PR=$(gh pr create --title "${PR_TITLE}" --body "${PR_BODY}" --label "status/auto-created" --base "${GITHUB_REF_NAME}" --head "${SOURCE_BRANCH}")
        echo "Created pull request: ${CREATED_PR}" >> $GITHUB_STEP_SUMMARY
        if [ -n "${EXISTING_PR}" ]; then
            gh pr close --comment "Superseded by ${CREATED_PR}" --delete-branch "${EXISTING_PR}"
            echo "Closed previous pull request: ${EXISTING_PR}" >> $GITHUB_STEP_SUMMARY
        fi

The same workflow, on Latchkey

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

name: Update README
on:
  workflow_dispatch:
  release:
    types: [published]
 
permissions:
  contents: write
  pull-requests: write
  id-token: write
 
jobs:
  update-readme:
    timeout-minutes: 30
    runs-on: latchkey-small
    steps:
    - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
    - name: Update README file
      run: |
       tagstmpfile=$(mktemp)
       readmetmpfile=$(mktemp)
       gh api graphql -F owner='rancher' -F name='rke' -f query='query($name: String!, $owner: String!) {repository(owner: $owner, name: $name) {releases(first: 100) {nodes { tagName }}}}' |jq -r .data.repository.releases[] > $tagstmpfile
       for rke_major_minor in 1.8 1.7 1.6; do
         latest=$(jq -r 'first(.[] | select(.tagName | startswith("v'"${rke_major_minor}"'")) | select(.tagName | contains("rc") | not) | .tagName)' $tagstmpfile)
         if [ -n "${latest}" ]; then
           echo "* v${rke_major_minor}" >> $readmetmpfile
           echo "  * ${latest} - Read the full release [notes](https://github.com/rancher/rke/releases/tag/${latest})." >> $readmetmpfile
         fi
       done
       sed -e '/## Latest Release/r '"$readmetmpfile"'' -e 's/CURRENTYEAR/'"$(date +%Y)"'/g' README-template.md > README.md
      env:
        GH_TOKEN: ${{ github.token }}
    - name: Check for repository changes
      run: |
        if git diff --name-only --exit-code; then
          echo "No changes found in repository after updating README"
          echo "changes_exist=false" >> $GITHUB_ENV
        else
          echo "Changes found in repository after updating README:"
          git diff --name-only
          echo "changes_exist=true" >> $GITHUB_ENV
        fi
    - name: Create branch, commit and push
      if: ${{ env.changes_exist == 'true' }}
      id: branch
      run: |
        BRANCH="githubaction-update-readme-$(date +%Y-%m-%d-%H-%M-%S)"
        echo "branch=${BRANCH}" >> $GITHUB_OUTPUT
        git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
        git config --global user.name "github-actions[bot]"
        git checkout -b "$BRANCH"
        git commit -a -m "update README with latest"
        git push origin "$BRANCH"
 
    # GitHub does not trigger workflows for pull requests made by a GitHub Actions token (GITHUB_TOKEN) by default.
    # Therefore, we need to retrieve a Personal Access Token (PAT)
    - name: Retrieve token from vault
      uses: rancher-eio/read-vault-secrets@0da85151ad1f19ed7986c41587e45aac1ace74b6 # v3
      with:
        secrets: |
          secret/data/github/repo/${{ github.repository }}/github-token/credentials token | PAT_TOKEN ;
 
    - name: Create Pull Request
      if: ${{ env.changes_exist == 'true' }}
      id: cpr
      env:
        SOURCE_BRANCH: ${{ steps.branch.outputs.branch }}
        GH_TOKEN: ${{ env.PAT_TOKEN }}
      run: |
        PR_TITLE="[${GITHUB_REF_NAME}] update README with latest"
        PR_BODY="Auto-generated by GitHub Actions"
        EXISTING_PR=$(gh pr list --limit 500 --json title,url | jq --arg title "${PR_TITLE}" -r '.[] | select(.title==$title) | .url')
        CREATED_PR=$(gh pr create --title "${PR_TITLE}" --body "${PR_BODY}" --label "status/auto-created" --base "${GITHUB_REF_NAME}" --head "${SOURCE_BRANCH}")
        echo "Created pull request: ${CREATED_PR}" >> $GITHUB_STEP_SUMMARY
        if [ -n "${EXISTING_PR}" ]; then
            gh pr close --comment "Superseded by ${CREATED_PR}" --delete-branch "${EXISTING_PR}"
            echo "Closed previous pull request: ${EXISTING_PR}" >> $GITHUB_STEP_SUMMARY
        fi
 

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