Skip to content

fix(devto): heal a stale article id instead of failing every run on it - #38

Merged
gounthar merged 1 commit into
mainfrom
fix/devto-stale-article-id
Aug 18, 2026
Merged

fix(devto): heal a stale article id instead of failing every run on it#38
gounthar merged 1 commit into
mainfrom
fix/devto-stale-article-id

Conversation

@gounthar

Copy link
Copy Markdown
Owner

Summary

Merging #37 fired the dev.to workflow, and it failed. The cause was not the content: scripts/devto-ids.json pointed 2026-06-29-fastest-windows-on-xcp-ng at article 4089982, which 404s. The live article is 4091331. Something deleted and re-created it, dev.to issued a new id, and nothing told the map.

Left alone, every future push touching that post fails on the same entry, and the correction that #37 landed never reaches dev.to.

  • The id is corrected.
  • A PUT that 404s now looks the article up again by title, retries against the id it finds, and prints what it did. run_ci already persists whatever process_post returns, so the map heals itself from here on.
  • A title lookup that misses is not treated as "article gone, post a new one". From inside the script those two cases look identical, and guessing wrong leaves a duplicate on dev.to for someone to find and delete. It raises and names the title it could not match.

The second gap

Re-pushing this fix turned out to be impossible, which is its own bug. run_ci only handles posts whose .adoc changed in the push, so re-running a failed workflow re-runs the same diff and does nothing. The only workarounds were editing content purely to trigger a run, or running the script by hand with the production key.

--update <post> forces one already-published post through the update path, wired to a workflow_dispatch input. The input reaches the shell through the environment rather than by interpolation into the run: block, so a crafted dispatch value cannot execute as a command.

The two id-map persistence steps were gated on github.event_name == 'push', so a dispatch run would have healed an id and then thrown it away. They now cover both.

Test plan

Stubbed, since exercising the real path needs the production key and would edit a live article:

  • stale id + title match: heals, retries against the new id, returns it so the map is written
  • stale id + no title match: raises, and posts nothing
  • non-404 errors propagate unchanged
  • title matching ignores case and surrounding whitespace
  • --update rejects a missing file, and a post absent from the id map
  • yamllint clean on the workflow, and it parses to the expected triggers and gates
  • After merge: dispatch with post: 2026-06-29-fastest-windows-on-xcp-ng.adoc and confirm the dev.to article picks up the corrected -Sh wording

The map pointed 2026-06-29-fastest-windows-on-xcp-ng at article 4089982,
which returns 404. The live article is 4091331, so the article was
deleted and re-created at some point and nothing told the map. Every push
touching that post would have failed on the same entry forever, and the
corrected text never reached dev.to.

The id is corrected, but correcting it by hand is the part worth not
repeating. A PUT that 404s now looks the article up again by title and
retries against the id it finds, and because run_ci already writes back
whatever process_post returns, the map heals itself.

A title lookup that misses is deliberately not treated as "the article is
gone, post a new one". The two cases are indistinguishable from here, and
guessing wrong leaves a duplicate on dev.to that someone has to find and
delete. It raises instead and says which title it could not find.

Re-pushing this particular fix exposed a second gap. run_ci only handles
posts whose .adoc changed in the push, so a correction that lands in the
same commit as a failure gets no second attempt: re-running the workflow
re-runs the same diff and does nothing. --update forces one published
post through the update path, wired to a workflow_dispatch input, so a
re-push no longer requires editing content to trigger one. The input
reaches the shell through the environment rather than by interpolation,
so a crafted dispatch value cannot run as a command.

The two id-map persistence steps were gated on push alone, which would
have dropped a healed id on a dispatch run. They now cover both.
@gounthar gounthar added the bug Something isn't working label Aug 18, 2026
@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@gounthar, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 25 minutes

Limit details: You’ve used all 1 included review currently available under your plan.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b74ba379-57a2-449d-a41f-8a3a2c0dc47e

📥 Commits

Reviewing files that changed from the base of the PR and between 02c8ebd and 6a1de7e.

📒 Files selected for processing (3)
  • .github/workflows/devto-publish.yml
  • scripts/devto-crosspost.py
  • scripts/devto-ids.json

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gounthar
gounthar merged commit 6924b6b into main Aug 18, 2026
6 checks passed
@gounthar
gounthar deleted the fix/devto-stale-article-id branch August 18, 2026 14:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant