Skip to content

Bump puma from 6.6.1 to 7.2.1 - #41

Closed
dependabot[bot] wants to merge 15 commits into
mainfrom
dependabot/bundler/puma-7.2.1
Closed

Bump puma from 6.6.1 to 7.2.1#41
dependabot[bot] wants to merge 15 commits into
mainfrom
dependabot/bundler/puma-7.2.1

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Aug 29, 2026

Copy link
Copy Markdown
Contributor

Bumps puma from 6.6.1 to 7.2.1.

Release notes

Sourced from puma's releases.

v7.2.1

  • Bugfixes
    • Limit and anchor PROXY protocol v1 parsing to prevent abuse via crafted inputs (#3947)
    • Parse PROXY protocol only once per connection to prevent injection on keep-alive requests (#3947)

Security advisories

v7.2.0 - On The Corner

  • Features

    • Add workers :auto (#3827)
    • Make it possible to restrict control server commands to stats (#3787)
  • Bugfixes

    • Don't break if WEB_CONCURRENCY is set to a blank string (#3837)
    • Don't share server between worker 0 and descendants on refork (#3602)
    • Fix phase check race condition in Puma::Cluster#check_workers (#3690)
    • Fix advertising of CLI config before config files are loaded (#3823)
  • Performance

    • 17% faster HTTP parsing through pre-interning env keys (#3825)
    • Implement dsize and dcompact functions for Puma::HttpParser, which makes Puma's C-extension GC-compactible (#3828)
  • Refactor

    • Remove NoMethodError rescue in Reactor#select_loop (#3831)
    • Various cleanups in the C extension (#3814)
    • Monomorphize handle_request return (#3802)
  • Docs

    • Change link to docs/deployment.md in README.md (#3848)
    • Fix formatting for each signal description in signals.md (#3813)
    • Update deployment and Kubernetes docs with Puma configuration tips (#3807)
    • Rename master to main (#3809, #3808, #3800)
    • Fix some minor typos in the docs (#3804)
    • Add GOVERNANCE.md, MAINTAINERS (#3826)
    • Remove Code Climate badge (#3820)
    • Add @​joshuay03 to the maintainer list
  • CI

v7.1.0

7.1.0 / 2025-10-16 - Neon Witch

neon_witch

  • Features

... (truncated)

Changelog

Sourced from puma's changelog.

7.2.1 / 2026-05-27

  • Bugfixes
    • Limit and anchor PROXY protocol v1 parsing to prevent abuse via crafted inputs (#3947)
    • Parse PROXY protocol only once per connection to prevent injection on keep-alive requests (#3947)

7.2.0 / 2026-01-20

  • Features

    • Add workers :auto (#3827)
    • Make it possible to restrict control server commands to stats (#3787)
  • Bugfixes

    • Don't break if WEB_CONCURRENCY is set to a blank string (#3837)
    • Don't share server between worker 0 and descendants on refork (#3602)
    • Fix phase check race condition in Puma::Cluster#check_workers (#3690)
    • Fix advertising of CLI config before config files are loaded (#3823)
  • Performance

    • 17% faster HTTP parsing through pre-interning env keys (#3825)
    • Implement dsize and dcompact functions for Puma::HttpParser, which makes Puma's C-extension GC-compactible (#3828)
  • Refactor

    • Remove NoMethodError rescue in Reactor#select_loop (#3831)
    • Various cleanups in the C extension (#3814)
    • Monomorphize handle_request return (#3802)
  • Docs

    • Change link to docs/deployment.md in README.md (#3848)
    • Fix formatting for each signal description in signals.md (#3813)
    • Update deployment and Kubernetes docs with Puma configuration tips (#3807)
    • Rename master to main (#3809, #3808, #3800)
    • Fix some minor typos in the docs (#3804)
    • Add GOVERNANCE.md, MAINTAINERS (#3826)
    • Remove Code Climate badge (#3820)
    • Add @​joshuay03 to the maintainer list
  • CI

7.1.0 / 2025-10-16

  • Features

    • Introduce after_worker_shutdown hook (#3707)
    • Reintroduce keepalive "fast inline" behavior. Provides faster (8x on JRuby & 1.4x on Ruby) pipeline processing (#3794)
  • Bugfixes

    • Skip reading zero bytes when request body is buffered (#3795)
    • Fix PUMA_LOG_CONFIG=1 logging twice with prune_bundler enabled (#3778)

... (truncated)

Commits

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    You can disable automated security fix PRs for this repo from the Security Alerts page.

samsonjs and others added 15 commits August 28, 2026 14:14
The dashboard's link form had its own OpenGraph scraper alongside Pressa's,
one for prefilling title/description and one for the Image front matter.
Fold the text fields into Pressa::OpenGraph so there's a single scraper for
the web app to call.
The HTML and Gemini writers could only render a post by writing it to disk
as part of a full site build, and PostRepo could only build a Post from a
file. Pull out the seams a preview needs: build a Post from a string,
render one post's HTML page, render one post's gemtext. All three are the
code paths the build itself uses, so a preview shows the real output rather
than an approximation of it.

Also collapses the two identical copies of the kramdown call onto
MarkdownRenderer.render_html.
Pressa::Web::Preview turns one post's source into both outputs at once,
through the same writers the build uses. Catching capsule formatting
problems currently means publishing and then reading the built capsule;
this makes it something you can see before you publish.
Publishing is pull, write, commit, push, build twice, rsync twice. Far too
slow to block a request on, and it mutates a git checkout that bin/post-link
also writes to over SSH. Model it as a job instead: JobRegistry holds the
single work slot and a short history, Job carries the log and lets browsers
subscribe to it, and JobRunner runs the existing scripts and streams their
progress.

A second publish while one is running is refused with the running job
rather than queued. Silently queueing a publish is worse than being told to
wait, and two at once against the same checkout would corrupt something.
The three scripts that write to this checkout shared a copy-pasted rv
preamble and repo/remote resolution; that moves to bin/lib/common.sh, which
also carries a flock. Publishing pulls, commits, pushes, builds, and rsyncs,
and now has two callers — the phone Shortcut over SSH and the web app — so
two of them at once against one git repo is a real possibility rather than a
theoretical one. Exit 75 says "try again shortly" rather than "that failed".

bin/publish-draft is the draft counterpart to bin/post-link. It commits
pending draft edits before pulling, since the web app writes drafts straight
into the checkout and `git pull --ff-only` is entitled to refuse otherwise.
Posting a link, drafts, and preview, served on the tailnet from mudge. It
drives bin/post-link and bin/publish-draft rather than reimplementing the
flow, and renders previews through the build's own writers, so there's one
copy of each behaviour rather than one per front end.

Publishing runs as a job and the browser watches its log over SSE, copying
the dashboard's streaming pattern. A second publish while one is running is
refused with a link to the running job.

Sinatra and puma share the existing Gemfile on purpose. bin/post-link runs
`bundle exec bake`, and a second Gemfile for the web app would leave
BUNDLE_GEMFILE pointing at the wrong one in the child -- the bug the
dashboard worked around with Bundler.with_unbundled_env.

Writes are guarded against cross-site requests. There are no cookies here,
so what a malicious page would ride isn't a login, it's this machine's
position on the tailnet: without this, any page open in a browser on the
tailnet could publish a post or delete a draft. super_good-csrf_protection
allows Sec-Fetch-Site of same-origin or none, falls back to Origin-vs-Host
for older browsers, and allows requests carrying neither header, since those
didn't come from a browser and can't be the confused deputy a CSRF needs --
which is what keeps curl and the phone Shortcut working. /link/metadata gets
the same treatment despite being a GET, because it makes this server fetch a
URL the caller chose and could otherwise be used to probe the tailnet blind.
…able

bin/publish-draft was recovering the published path by piping bake's prose
through `tail -n 1 | awk '{print $NF}'`. The task now follows the same
convention as new_link and preview_link -- stdout is the answer, stderr is
the progress -- so the script just captures stdout.

Moving the mechanics into Drafts::Publisher put them under test for the
first time, which turned up two bugs. The date rewrite ignored whether the
sub! matched, so a draft missing its Date or Timestamp line published a post
that only failed later, at build time, after bin/publish-draft had already
committed and pushed; it now validates the result with the same PostMetadata
the build uses and refuses before anything is moved. And unlike new_link
there was no check for an existing post, so a slug clash silently overwrote
one.
Publishing one draft committed every other edited draft too, under a vague
"Update drafts", because the pull needs a clean tree and that was the blunt
way to get one. It now stages just the draft being published.

That also fixes a worse bug behind it. The check was `git diff --quiet`,
which reports untracked files as clean -- and a draft created in the web app
is untracked. So it was never committed here, and then the `git add` after
publish_draft moved it away died with "pathspec did not match any files",
aborting the script under set -e with the post already written. Publishing a
newly created draft failed every time. `git status --porcelain` sees
untracked files, so one change covers both.
The app needs two Site objects -- one configured for HTML, one for Gemini --
so the preview can render a post through the same writers the build uses.
They were being built lazily on first request and stuffed back into a
Sinatra setting, which worked only because `set` happens to return the
class, defined singleton methods at request time, and raced between threads.

Building both costs about six milliseconds, once, so web/config.ru does it
at boot via configure_sites! and the helpers are plain readers that raise a
clear error naming config.ru if nobody set them. Every entry point already
goes through config.ru: the systemd unit via web/bin/start, `bake web`, and
the documented smoke test. The one test that relied on the lazy path now
calls configure_sites!, so it exercises the real boot path instead.

The tag-chip cache moves off Sinatra settings to a plain hash, keyed by repo
root as well as post count and mtime. It's a mutable cache, not
configuration, and `set` was the wrong mechanism for it.
Saving a draft overwrote whatever was there. Two tabs, or a phone and a
laptop, and the second save silently destroyed the first -- and now that
publishing pulls from GitHub, a pull can rewrite a draft underneath an open
editor too.

The editor carries a SHA-256 of what it loaded and sends it back with the
save. A mismatch is refused with 409, the submitted text still in the
textarea and what's on disk shown below it, so neither version is lost and
the reconciling is a copy-paste rather than a merge UI. A digest rather than
mtime because re-saving identical content shouldn't be a conflict and
same-second writes shouldn't compare equal.

A save carrying no token at all -- a tab left open across a deploy -- is
refused too, rather than falling back to last-write-wins.
The job model was built on a number I never measured. Publishing was
supposed to take 30-60 seconds, a figure inherited from the dashboard's own
"usually ~30s" and never checked. Measured against beta: HTML build 0.72s,
Gemini build 0.48s, build and rsync to mudge 1.0s, a GitHub round trip
1.25s, an og:image fetch 0.12-0.85s against real sites. A whole publish is
about five seconds.

At five seconds a request can just do the work. POST /link and the draft
publish run the script inline and render the result and its log on the page.
Job, JobRegistry, the three /jobs routes, the SSE stream and its two views
are gone -- about 580 lines including their tests.

Serialisation is unaffected: the flock in bin/lib/common.sh was always the
real guard, since it's the only one the phone Shortcut's SSH path respects
too. A publish that can't take it exits 75 and the app turns that into a 409
saying to try again, rather than the in-process mutex saying the same thing
less reliably.
Timeouts were per-hop: five seconds to connect plus five to read, across up
to six redirects, so a hanging server could hold a fetch open for the better
part of a minute. That was survivable when it ran in a background job. Now
that publishing blocks, it's a minute the browser spends waiting.

The whole fetch shares a five second budget, redirects included, and each
hop gets only what's left of it. Real sites measure 0.11s to 0.85s, so
there's plenty of headroom. Covered by a test against a socket that accepts
and never answers.
Publishing rendered straight from the POST, so the browser sat on
/link with a form result and a reload would publish the post a second time.
Success now redirects with the published path in the query string; a failure
still renders inline, since that's the case where the form contents and the
log are worth keeping.

The draft editor was headed by the slug rather than the draft's own title.
The link form's URL field autofocuses, which is what you want on a form whose
whole job is pasting a link. "Quote the description" was stretching to full
width in the flex column and reading as a primary action. And the preview
breaks out of the reading column on wide screens, so the web pane gets enough
room to show something other than the mobile layout.

None of these were visible from the test suite, because none of the tests
run a browser.
bin/post-link and bin/publish-draft are 49 lines of shell that the phone
Shortcut runs over SSH and the web app spawns, and they're where this repo's
git bugs hide: a `git diff --quiet` that reported untracked files as clean
meant publishing a newly created draft failed every time, and nothing in 300
Ruby tests could see it.

These run the actual scripts against a temporary git repo with a real bare
remote, stubbing only bake, whose tasks are unit tested separately. They
cover the untracked draft, leaving other drafts alone, filename and slug
arguments, the missing draft and usage errors, and that post-link puts its
payload on bake's stdin and pushes what it commits. Reintroducing the old
`git diff --quiet` makes the untracked-draft test fail, which is the point.

The repo and its remote cost more to build than the scripts cost to run, so
they're built once and copied per test: 3.4s rather than 4.7s, out of a
suite that now takes 6.3s.
Bumps [puma](https://github.com/puma/puma) from 6.6.1 to 7.2.1.
- [Release notes](https://github.com/puma/puma/releases)
- [Changelog](https://github.com/puma/puma/blob/main/History.md)
- [Commits](puma/puma@v6.6.1...v7.2.1)

---
updated-dependencies:
- dependency-name: puma
  dependency-version: 7.2.1
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file ruby Pull requests that update Ruby code labels Aug 29, 2026
@dependabot @github

dependabot Bot commented on behalf of github Aug 29, 2026

Copy link
Copy Markdown
Contributor Author

Looks like puma is up-to-date now, so this is no longer needed.

@dependabot dependabot Bot closed this Aug 29, 2026
@dependabot
dependabot Bot deleted the dependabot/bundler/puma-7.2.1 branch August 29, 2026 19:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file ruby Pull requests that update Ruby code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant