Skip to content

feat(check-commits): report WIP commits as a separate check - #7

Open
javier-godoy wants to merge 2 commits into
mainfrom
feature/wip-action-required
Open

javier-godoy wants to merge 2 commits into
mainfrom
feature/wip-action-required

Conversation

@javier-godoy

@javier-godoy javier-godoy commented Sep 9, 2026

Copy link
Copy Markdown
Member

Refs FlowingCode/AddonsInternal#99
Depends on FlowingCode/action-conventional-commits#3 — merged.

A Pull Request with WIP commits must not be merged, but that is an expected state of an
unfinished branch rather than an error. Reporting it with the same failure as an invalid
commit message made the two indistinguishable.

WIP commits no longer fail the conventional commits step. They are reported as a separate
wip-commits check run with the action_required conclusion, which keeps the merge blocked
without marking the Pull Request as failing.

As a side effect, the version and Semantic Versioning checks now run for Pull Requests that
contain WIP commits, where previously the WIP failure skipped them.

Validated on javier-godoy/test-repo

Every open pull request there was re-run on 2026-09-15 against dd72611, the head of this
branch, and FlowingCode/action-conventional-commits at master, where #3 is now merged — so
the table below is what this workflow reports in its merged configuration, with no branch
pinning left anywhere.

check-commits / check-commits is the job's own check run, and it fails whenever the analysis
found anything to report, WIP commits included, because the script calls core.setFailed so the
pull request is marked as failing. What this branch changes is not that the job stays green: it
is that wip-commits says which problem it was, and concludes action_required rather than
failure when the branch can be squashed at merge time. semver-alignment and wip-commits
are created by this workflow and carry the verdict; the titles below are theirs.

Pull request Scenario check-commits semver-alignment wip-commits mergeable_state
javier-godoy/test-repo#13 valid commit message ✅ success Consistent: PATCH change No Work-in-Progress (WIP) commits clean
javier-godoy/test-repo#12 one invalid commit message ❌ failure The semantic versioning level is unknown No Work-in-Progress (WIP) commits unstable
javier-godoy/test-repo#17 every commit message invalid ❌ failure The semantic versioning level is unknown No Work-in-Progress (WIP) commits unstable
javier-godoy/test-repo#11 one non-WIP commit, then one WIP ❌ failure Consistent: NONE change 🚧 Must squash WIP commit unstable
javier-godoy/test-repo#25 one non-WIP commit, then two WIP ❌ failure Consistent: NONE change 🚧 Must squash WIP commits unstable
javier-godoy/test-repo#24 every commit is a WIP commit ❌ failure Consistent: NONE change 🚧 Must consolidate WIP commit unstable
javier-godoy/test-repo#28 breaking change, no version bump ❌ failure 🚫 MAJOR version required No Work-in-Progress (WIP) commits unstable
javier-godoy/test-repo#29 new feature, no version bump ❌ failure 🚫 MINOR version required No Work-in-Progress (WIP) commits unstable
javier-godoy/test-repo#30 breaking change with a matching version bump ✅ success Consistent: MAJOR change No Work-in-Progress (WIP) commits clean
javier-godoy/test-repo#14 breaking change + WIP commit, no version bump ❌ failure 🚫 MAJOR version required 🚧 Must consolidate WIP commit unstable
javier-godoy/test-repo#19 fork — invalid commit message ❌ failure unstable
javier-godoy/test-repo#20 fork — non-WIP commit, then two WIP ❌ failure unstable
javier-godoy/test-repo#21 fork — valid commit messages ✅ success clean

A WIP commit does not affect the semantic versioning level: it neither raises it nor renders
it unknown, because it is going to be squashed into a commit whose own type settles the
level. javier-godoy/test-repo#11, #24 and #25 therefore report the level of their non-WIP
commits. A commit message that could not be parsed is different — the level it would have
settled is unknown, so the level as a whole becomes a lower bound. A lower bound cannot
confirm that a version is consistent, but it can still contradict one, which is why
javier-godoy/test-repo#14 keeps its MAJOR failure and javier-godoy/test-repo#12 reports the
level as unknown rather than as the NONE its one readable commit describes.

master in that repository is not protected, so no check is required and every failing pull
request reads unstable rather than blocked. An earlier manual run with wip-commits added
to the required checks did report blocked; that is recorded here as an observation, not as a
row the table above reproduces.

javier-godoy/test-repo#26 and javier-godoy/test-repo#27 also exist but call the action directly
rather than through this workflow, so they exercise the action's own reporting and say nothing
about this branch.

The suite covers both caller configurations, on a repository whose default workflow permission
is read-only. The ten same-repository pull requests declare contents: read + checks: write
on the calling job and get the two check runs. The three fork pull requests declare nothing at
all and still run, because this workflow asks for no permissions of its own: there is nothing
for a read-only caller to refuse. Their check runs are missing for an unrelated reason — the
workflow skips creating them on a fork, whatever the caller granted — so the verdict travels
through the annotations and the job's own conclusion.

It also confirms that the version and Semantic Versioning steps now run on pull requests that
contain WIP commits: javier-godoy/test-repo#14 reports a semver failure and a WIP failure
together, where previously the WIP failure skipped the version check.

The caveat still holds: mergeable_state is unstable, not clean, so GitHub counts
action_required as a non-successful check and the pull request reads "Some checks were not
successful"
rather than being green.

🤖 Generated with Claude Code

@javier-godoy
javier-godoy force-pushed the feature/wip-action-required branch 2 times, most recently from 7c3957f to 404cdb9 Compare September 15, 2026 16:59
The check run that GitHub creates for this job cannot carry a message: its
conclusion is derived from the job outcome and its output is empty, so a
pull request showed a failing check without saying why, and a WIP commit was
reported exactly like an invalid commit message.

The action is now asked not to report anything, and this workflow renders the
outcome instead. The offending commits become annotations, the presence of
WIP commits is reported as a check of its own, and the job fails if either
check failed, so that the pull request is marked as failing while the checks
themselves say which one it was.

Nothing here is specific to pull requests: check runs attach to any commit,
so the checks are also reported for the commits of other events.

A pull request from a fork is the exception: it runs with a read-only token
whatever the permissions block asks for, so no check run can be created for
it. Rather than answering 403, the checks are skipped there. The annotations
are workflow commands and still work, and the job still fails, so the outcome
is reported either way; only the checks that carry it separately are missing,
which is why they must not be required on a repository that takes
contributions from forks.
The consistency between the version in the POM and the level of semantic
versioning change described by the commit messages was enforced by failing
this job, which made it indistinguishable from an invalid commit message.
It is now reported as a check of its own, with the version and the level in
its title, and it joins the other checks in failing the job.

Both of its inputs are reported as unknown rather than assumed. The version
is read with if: always(), because reading it does not depend on the commit
check. The level is read from the SEMVER_LEVEL environment variable that the
action exports, and it counts as unknown in two cases: when the action could
not analyse the commit messages at all, which it signals by failing, and
when no commit message could be parsed, because only a valid commit raises
the level and NONE is also what an unparseable pull request leaves behind.
The WIP check is reported as unknown on the first of those paths too,
because an empty result is not evidence of consolidated commits.
@javier-godoy
javier-godoy force-pushed the feature/wip-action-required branch 2 times, most recently from d4dcf35 to dd72611 Compare September 15, 2026 17:51
@javier-godoy
javier-godoy marked this pull request as ready for review September 15, 2026 18:07
@javier-godoy
javier-godoy requested a review from paodb September 21, 2026 12:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: To Do

Development

Successfully merging this pull request may close these issues.

1 participant