Skip to content
Latchkey

Publish Documentation workflow (nicholas-fedor/watchtower)

The Publish Documentation workflow from nicholas-fedor/watchtower, explained and optimized by Latchkey.

C

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.

Grade your own workflow free or run it on Latchkey →
Source: nicholas-fedor/watchtower.github/workflows/publish-docs.yamlLicense Apache-2.0View source

What it does

This is the Publish Documentation workflow from the nicholas-fedor/watchtower 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: Publish Documentation

on:
  workflow_dispatch:
  push:
    branches: [main]
    paths:
      - docs/**
      - build/mkdocs/**
  release:
    types: [published]

permissions:
  contents: read # Set default read-only permissions

jobs:
  build-docs:
    name: Publish Docs
    runs-on: ubuntu-latest
    permissions:
      contents: write
      actions: read
    steps:
      - name: Harden the runner (Audit all outbound calls)
        uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
        with:
          egress-policy: audit

      - name: Checkout Repo
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
        with:
          fetch-depth: 0
          persist-credentials: false

      - name: Configure Git Credentials
        run: |
          git config user.name github-actions[bot]
          git config user.email 41898282+github-actions[bot]@users.noreply.github.com
          git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Setup Go
        uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
        with:
          cache: false
          go-version-file: go.mod

      - name: Make Script Executable
        run: chmod +x ./scripts/build-tplprev.sh

      - name: Build tplprev
        run: |
          go mod download
          go clean -cache  # Clear build cache
          ./scripts/build-tplprev.sh

      - name: Setup Python
        uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
        with:
          python-version: "3.14.6"
          cache: "pip"
          cache-dependency-path: |
            build/mkdocs/docs-requirements.txt

      - name: Setup Cache
        uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
        with:
          key: mkdocs-material-${{ hashFiles('build/mkdocs/docs-requirements.txt') }}
          path: .cache
          restore-keys: |
            mkdocs-material-

      - name: Install mkdocs
        run: |
          pip install -r build/mkdocs/docs-requirements.txt

      - name: Determine Mike Version and Aliases
        id: mike
        env:
          TAG_NAME: ${{ github.event.release.tag_name }}
        run: |
          if [[ "${{ github.event_name }}" == "release" ]]; then
            echo "version=${TAG_NAME}" >> "$GITHUB_OUTPUT"
            echo "aliases=latest" >> "$GITHUB_OUTPUT"
          else
            echo "version=dev" >> "$GITHUB_OUTPUT"
          fi

      - name: Build and Deploy
        env:
          ALIASES: ${{ steps.mike.outputs.aliases }}
          VERSION: ${{ steps.mike.outputs.version }}
        run: |
          if [ -n "${ALIASES}" ]; then
            mike deploy \
              --config-file build/mkdocs/mkdocs.yaml \
              --push \
              --update-aliases "${VERSION}" "${ALIASES}"
          else
            mike deploy \
              --config-file build/mkdocs/mkdocs.yaml \
              --push \
              "${VERSION}"
          fi

The same workflow, on Latchkey

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

---
name: Publish Documentation
 
on:
  workflow_dispatch:
  push:
    branches: [main]
    paths:
      - docs/**
      - build/mkdocs/**
  release:
    types: [published]
 
permissions:
  contents: read # Set default read-only permissions
 
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
  build-docs:
    timeout-minutes: 30
    name: Publish Docs
    runs-on: latchkey-small
    permissions:
      contents: write
      actions: read
    steps:
      - name: Harden the runner (Audit all outbound calls)
        uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
        with:
          egress-policy: audit
 
      - name: Checkout Repo
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
        with:
          fetch-depth: 0
          persist-credentials: false
 
      - name: Configure Git Credentials
        run: |
          git config user.name github-actions[bot]
          git config user.email 41898282+github-actions[bot]@users.noreply.github.com
          git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 
      - name: Setup Go
        uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
        with:
          cache: false
          go-version-file: go.mod
 
      - name: Make Script Executable
        run: chmod +x ./scripts/build-tplprev.sh
 
      - name: Build tplprev
        run: |
          go mod download
          go clean -cache  # Clear build cache
          ./scripts/build-tplprev.sh
 
      - name: Setup Python
        uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
        with:
          python-version: "3.14.6"
          cache: "pip"
          cache-dependency-path: |
            build/mkdocs/docs-requirements.txt
 
      - name: Setup Cache
        uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
        with:
          key: mkdocs-material-${{ hashFiles('build/mkdocs/docs-requirements.txt') }}
          path: .cache
          restore-keys: |
            mkdocs-material-
 
      - name: Install mkdocs
        run: |
          pip install -r build/mkdocs/docs-requirements.txt
 
      - name: Determine Mike Version and Aliases
        id: mike
        env:
          TAG_NAME: ${{ github.event.release.tag_name }}
        run: |
          if [[ "${{ github.event_name }}" == "release" ]]; then
            echo "version=${TAG_NAME}" >> "$GITHUB_OUTPUT"
            echo "aliases=latest" >> "$GITHUB_OUTPUT"
          else
            echo "version=dev" >> "$GITHUB_OUTPUT"
          fi
 
      - name: Build and Deploy
        env:
          ALIASES: ${{ steps.mike.outputs.aliases }}
          VERSION: ${{ steps.mike.outputs.version }}
        run: |
          if [ -n "${ALIASES}" ]; then
            mike deploy \
              --config-file build/mkdocs/mkdocs.yaml \
              --push \
              --update-aliases "${VERSION}" "${ALIASES}"
          else
            mike deploy \
              --config-file build/mkdocs/mkdocs.yaml \
              --push \
              "${VERSION}"
          fi
 

What changed

What Latchkey heals here

This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:

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