maragudk / maragudk/workflows

Let docs-only pull requests pass required checks without running CI

Open
#1 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
No language data
Stars
0
Forks
0
Avg merge
45m
Merged PRs (30d)
6

Description

Problem

Pull requests that only touch documentation (docs/**, **.md) run the whole CI pipeline: build matrix, tests, lint. For a typo fix that is minutes of runner time, in every repository that adopts a shared CI workflow from here.

The two obvious escapes do not work:

  • [skip ci] is only read from the HEAD commit message, so it depends on how the branch happened to be written, and a ruleset cannot enforce it.
  • Filtering the workflow out with paths-ignore means it never runs, and a required status check that never reports stays pending forever. Under a branch ruleset that requires it, the pull request can never merge.

So the required checks have to report success without doing the work. Two shapes for that, both of which belong here rather than copy-pasted into every repository.

Option A: a second, docs-only workflow

A separate workflow with the mirror paths filter, whose jobs carry the same names as the required checks and do nothing but succeed, plus paths-ignore for the same set on the real workflow.

  • Simplest to write, and the real jobs are untouched.
  • A mixed pull request (docs and code) matches both filters, so the same check name appears twice in the list. Every instance must pass, so this is safe, but the check list is confusing.
  • The job names must stay in sync across two workflows and the ruleset. Drift fails loudly rather than silently: the required check never reports and the pull request hangs.
  • Edge case: a pull request with an empty diff matches neither filter, so nothing runs and the checks hang.

Option B: a gate job at the front of CI

One job at the start of the workflow decides whether the change set is docs-only and exposes that as an output. Every real job gains needs: on the gate and an if: on its output, so on a docs-only pull request they are skipped, which reports success without running anything.

  • One workflow and one set of job names, so there is nothing to keep in sync beyond the ruleset that already exists.
  • No duplicate check rows on mixed pull requests.
  • No empty-diff hole: the gate always runs and decides.
  • The required check names stay exactly what they are today, so adopting it changes no ruleset.
  • Costs one extra runner start per pull request, and the gate needs the changed file list: a git diff against the base after a checkout with enough history, or a changed-files action.

As a shared workflow this fits the job-sized shape already sketched for CI: a small on: workflow_call workflow that returns a boolean output, which each caller's ci.yml gates its own jobs on.

Recommendation

Option B. Option A is less code today and more maintenance forever: two files and a ruleset holding the same list of job names, duplicate rows on the common mixed pull request, and a hole that hangs the checks. The gate keeps the required check names stable, which also makes it a no-op to adopt.

Pattern notes worth writing down

  • Use **.md, not **/*.md. The second does not match Markdown at the repository root, so a README.md-only pull request quietly falls out of the docs-only set and runs the full build.
  • On pull_request, path filters are evaluated over the whole pull request diff, not just the latest push. A branch that touched code in an early commit keeps running CI even when the last push was docs only.

Open questions

  • Confirm on a live pull request that a job skipped by if: satisfies a required status check in a ruleset. A job skipped inside a workflow that did run behaves differently from a workflow that was never triggered, and only the first is any use here. If it does not hold, the jobs need a no-op step instead of a skip.
  • Should the docs path set be an input, or fixed here? Fixed keeps the input surface minimal and the behaviour identical everywhere; an input covers a repository with, say, a website/ directory.
  • Does the gate need a changed-files action, or is git diff --name-only against the merge base enough? Callers pin @main, so a third-party action added here becomes a dependency of every repository that calls it.
  • Should a push to the default branch get the same treatment, or only pull_request? The saving is on pull requests, and skipping on the default branch leaves that branch without a green build.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by inspecting the existing shared workflow and each caller's ci.yml, focusing on the workflow_call interface and current required job names. Compare the gate-job approach with the documented ruleset behavior for skipped jobs, then resolve the changed-file detection and docs path input questions. Done means docs-only pull requests report the existing required checks successfully without running CI, while mixed and code changes retain the full pipeline.

Written by the indexing model from the issue text.

Assessment

Tech stack
github-actions
Domain
ci-cd, devops
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.