Skip to content

ci: re-run the PR-title lint on every push - #129

Merged
oc-tmueller merged 2 commits into
mainfrom
ci/lint-pr-title-on-synchronize
Sep 16, 2026
Merged

oc-tmueller merged 2 commits into
mainfrom
ci/lint-pr-title-on-synchronize

Conversation

@oc-tmueller

Copy link
Copy Markdown
Contributor

Why

lint (workflow Lint PR title) has run on every PR in this repo since #97, but the
trigger list is [opened, edited, reopened]synchronize was deliberately omitted, on the
grounds that a push cannot change the title.

That reasoning holds only while the check is advisory. owncloud/admin manages this repo's
docs.owncloud.com-status-checks ruleset, and required status checks are evaluated per head
sha
: a check-run belongs to the commit it ran against and is never carried forward. Without
synchronize, every push leaves the new head with no lint check-run — which GitHub reads
as perpetually pending, blocking the merge until someone edits the title.

Three PRs here have already been in exactly that state, harmlessly only because the context is
not required yet:

PR what happened lint on the merged head?
#116 lint ran on 4c48f460 when Dependabot opened it; Dependabot then rebased to 78e0a21b no
#110 force-pushed to a0bcc073 no
#63 pushed 5bfb225e on 2026-09-14 no

#116 is the one that matters: Dependabot never edits its own title, so had lint been required
that PR could not have been merged at all — only closed and reopened.

Evidence, for anyone re-checking:

$ gh api "repos/owncloud/docs.owncloud.com/actions/workflows/lint-pr-title.yml/runs?per_page=15" \
    --jq '.workflow_runs[] | "\(.created_at) \(.event) head=\(.head_sha[0:8]) \(.conclusion)"'
2026-09-07T10:46:39Z pull_request head=4c48f460 success   # <- #116 as opened
                                                          # <- nothing for 78e0a21b, the head that merged

What

One trigger added, plus the two comments that documented the old reasoning brought up to date:

  • types: [opened, edited, reopened][opened, edited, reopened, synchronize]
  • the comment above types: now explains that the re-run exists to re-post the check-run on the
    new sha, not to re-judge the title
  • the concurrency comment now says the group is per pull request (github.ref is
    refs/pull/<n>/merge for a pull_request event), so an edit racing a push collapses to the
    newer run rather than leaving a stale red check

No change to permissions, to the pinned action
(amannn/action-semantic-pull-request@48f2562 / v6.1.1) or to the job itself.

This also aligns the repo with the rest of the org — activity, client, richdocuments,
testing and wopi all trigger on synchronize, and richdocuments is the worked example of
lint being required and the gate working.

Verification

The change is self-testing: this PR gets a second, empty commit pushed to it, and a lint
check-run must then appear on the new head sha. That result is posted as a comment below
before the PR is proposed for merge.

Follow-up

Requiring the context is a separate PR against owncloud/admin, which must merge after
this one.

Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com

A check-run belongs to the head sha it ran against and is never carried
forward, while required status checks are evaluated per sha. With `synchronize`
missing from this workflow's trigger list, every push therefore leaves the new
head with no `lint` check-run at all -- which GitHub reads as perpetually
pending.

That is harmless while `lint` is advisory, which it still is today: `build` is
the only required check on `main`. It becomes a permanent merge block the
moment `lint` joins the docs.owncloud.com-status-checks ruleset in
owncloud/admin, so this is the prerequisite for that follow-up rather than a
fix for a live outage.

Three PRs here have already been in the pending-forever state without paying
for it:

  * #116 -- lint ran when Dependabot opened it, Dependabot then rebased to
    78e0a21, and the head that merged carried no lint. Re-running the workflow
    would not have recovered that PR: a re-run replays the original event and
    reports back to the original sha. Only an event against the new head does.
  * #110 -- force-pushed to a0bcc07; no lint run on that sha.
  * #63  -- pushed 5bfb225 on 2026-09-14; no lint run on that sha.

The comment claiming `synchronize` was redundant reasoned only about the title,
which a push indeed cannot change. That holds while the check is advisory; it
does not once the check is required, because the re-run exists to re-post the
check-run on the new sha, not to re-judge the title.

Two neighbouring comments are corrected in the same breath, since both would
have misled the next person deciding whether a trigger is droppable:

  * `reopened` was justified as stopping the check from going "absent" on
    reopen. It does not go absent -- reopening does not move the head sha, so
    the existing check-run still applies. What actually makes `reopened`
    load-bearing is that a push while the PR is CLOSED emits no pull_request
    event at all, leaving it the only event that reports against the head the
    PR comes back with. It is therefore not redundant with `synchronize`.
  * the concurrency block was credited with preventing a stale red check.
    Cancellation is asynchronous, so the superseded run still lands, as
    `cancelled`; what keeps the current verdict authoritative is GitHub
    resolving duplicate check-run names to the newest. Head 3a91054 carries
    exactly that cancelled/success pair today.

This also aligns the repo with the rest of the org -- activity, client,
richdocuments, testing and wopi all trigger on `synchronize`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Thomas Müller <323649642+oc-tmueller@users.noreply.github.com>
@oc-tmueller
oc-tmueller requested a review from a team as a code owner September 16, 2026 15:51
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Verification probe for the change in this PR, not content. A `lint` check-run
must now appear on this new head sha; before the change, a push produced none
(see #116, #110, #63 in the PR description).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Thomas Müller <323649642+oc-tmueller@users.noreply.github.com>
@LukasHirt

Copy link
Copy Markdown
Contributor

Originally approved before the second commit but seems it worked now - keeping the original approval.

@oc-tmueller

Copy link
Copy Markdown
Contributor Author

Verification: synchronize fires, and the lint reports against the new head

The second commit on this branch is an empty one, pushed purely as the probe. Before the
change a push produced no lint run at all; now it does.

$ gh api "repos/owncloud/docs.owncloud.com/actions/workflows/lint-pr-title.yml/runs?per_page=4" \
    --jq '.workflow_runs[] | "\(.created_at) \(.event) head=\(.head_sha[0:8]) \(.status)/\(.conclusion)"'
2026-09-16T15:55:38Z pull_request head=c10aef45 completed/success   # <- the PUSHED head (this probe)
2026-09-16T15:51:51Z pull_request head=5a178307 completed/success   # <- the opened head

$ gh api repos/owncloud/docs.owncloud.com/commits/c10aef45.../check-runs --jq '[.check_runs[].name]'
["lint","build"]

Compare #116, whose merged head has no lint check-run at all:

$ gh api repos/owncloud/docs.owncloud.com/commits/78e0a21b.../check-runs \
    --jq '[.check_runs[] | "\(.name)=\(.conclusion)"]'
["build=success","deploy=skipped"]

Two details worth recording, both confirmed here:

  • The trigger list is read from this PR's version of the workflow, not from main, so the
    change is self-testing — no need to merge first and hope.
  • license/cla shows pending ("Contributor License Agreement is not signed yet") on this PR.
    That is the Co-Authored-By: Claude … trailer, not an unsigned human: the identical trailer
    passes on owncloud/richdocuments (#630, #633 → license/cla=success), so it is a per-repo
    cla-assistant allowlist difference, and docs(ocis): add 8.2 updates — clean-corrupt-public-shares CLI #63 hit the same thing here. It is not a required
    context on this repo today; the durable fix is to allowlist that identity for this repo the
    way richdocuments has it.

@oc-tmueller
oc-tmueller merged commit 9c5c156 into main Sep 16, 2026
3 of 4 checks passed
@oc-tmueller
oc-tmueller deleted the ci/lint-pr-title-on-synchronize branch September 16, 2026 16:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants