Check for broken links workflow (marcelscruz/public-apis)
The Check for broken links workflow from marcelscruz/public-apis, explained and optimized by Latchkey.
CI health: B - good
Point runs-on at Latchkey and get job timeouts, SHA-pinned actions, self-healing for flaky steps, and up to 58% lower cost, applied automatically.
What it does
This is the Check for broken links workflow from the marcelscruz/public-apis 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
# This workflow uses the lychee-action to check the links
# in your markdown files for validity.
# You can exclude links via a .lycheeignore file in your repository root.
# You find further information about lychee-action in the documentation at:
# https://github.com/lycheeverse/lychee-action
name: Check for broken links
on:
workflow_dispatch:
schedule: # Run every weekday at 12:30 UTC
- cron: '30 12 * * 1-5'
jobs:
Check-for-broken-links:
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
env:
issue-lookup-label: automated-link-issue
issue-content: ./lychee-out.md
steps:
- uses: actions/checkout@v4
- name: Restore lychee cache
uses: actions/cache@v4
with:
path: .lycheecache
key: cache-lychee-${{ github.sha }}
restore-keys: cache-lychee-
- name: Link Checker
id: lychee
uses: lycheeverse/lychee-action@v1.10.0
with:
fail: false
args: --verbose --no-progress --exclude-file .lycheeignore '**/*.md'
output: ${{ env.issue-content }}
# Permissions (issues: read)
- name: 'Look for an existing issue'
if: ${{ failure() }}
id: last-issue
uses: micalevisk/last-issue-action@v2
# Find the last updated open issue with a `automated-issue` label:
with:
state: open
labels: ${{ env.issue-lookup-label }}
# Permissions (issues: write)
- name: 'Create a new issue, or update an existing one'
if: ${{ failure() }}
uses: peter-evans/create-issue-from-file@v4
with:
title: 'docs: Broken links found'
content-filepath: ${{ env.issue-content }}
# Update an existing issue if one was found (issue_number),
# otherwise an empty value creates a new issue:
issue-number: ${{ steps['last-issue']['outputs']['issue-number'] }}
# Add a label(s) that `last-issue` can use to find this issue,
# and any other relevant labels for the issue itself:
labels: |
${{ env.issue-lookup-label }}
broken-link, docs
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
# This workflow uses the lychee-action to check the links # in your markdown files for validity. # You can exclude links via a .lycheeignore file in your repository root. # You find further information about lychee-action in the documentation at: # https://github.com/lycheeverse/lychee-action name: Check for broken links on: workflow_dispatch: schedule: # Run every weekday at 12:30 UTC - cron: '30 12 * * 1-5' jobs: Check-for-broken-links: timeout-minutes: 30 runs-on: latchkey-small permissions: contents: read issues: write env: issue-lookup-label: automated-link-issue issue-content: ./lychee-out.md steps: - uses: actions/checkout@v4 - name: Restore lychee cache uses: actions/cache@v4 with: path: .lycheecache key: cache-lychee-${{ github.sha }} restore-keys: cache-lychee- - name: Link Checker id: lychee uses: lycheeverse/lychee-action@v1.10.0 with: fail: false args: --verbose --no-progress --exclude-file .lycheeignore '**/*.md' output: ${{ env.issue-content }} # Permissions (issues: read) - name: 'Look for an existing issue' if: ${{ failure() }} id: last-issue uses: micalevisk/last-issue-action@v2 # Find the last updated open issue with a `automated-issue` label: with: state: open labels: ${{ env.issue-lookup-label }} # Permissions (issues: write) - name: 'Create a new issue, or update an existing one' if: ${{ failure() }} uses: peter-evans/create-issue-from-file@v4 with: title: 'docs: Broken links found' content-filepath: ${{ env.issue-content }} # Update an existing issue if one was found (issue_number), # otherwise an empty value creates a new issue: issue-number: ${{ steps['last-issue']['outputs']['issue-number'] }} # Add a label(s) that `last-issue` can use to find this issue, # and any other relevant labels for the issue itself: labels: | ${{ env.issue-lookup-label }} broken-link, docs
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.
3 third-party actions are referenced by a movable tag. Pin them to the commit SHA (Latchkey resolves and applies this automatically) so a repointed tag cannot change what runs.
This workflow runs 1 job per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.