Bump puma from 6.6.1 to 7.2.1 - #41
Closed
dependabot[bot] wants to merge 15 commits into
Closed
Conversation
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>
Contributor
Author
|
Looks like puma is up-to-date now, so this is no longer needed. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumps puma from 6.6.1 to 7.2.1.
Release notes
Sourced from puma's releases.
... (truncated)
Changelog
Sourced from puma's changelog.
... (truncated)
Commits
92754acRelease v7.2.1 (#3948)ebe9db37.2.1 backport (#3947)96b5aa6v7.2.0 (#3864)5d7d1ddAdd workers :auto (#3827)b8c4783ci: fix ci - removeappend_as_byteslogic, misc changes (#3861)44a3ac4Fix PR label manager when maintainer comments [ci skip] (#3863)43f5d89Add GOVERNANCE.md, MAINTAINERS (#3826)21afa66Use Minitest 6 where applicable (#3859)ec7dd61ci: Update test_http11.rb for TruffleRuby - string size (#3860)fa89dbeci: addruby 4.0andrails 8.1(#3852)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 rebasewill rebase this PR@dependabot recreatewill recreate this PR, overwriting any edits that have been made to it@dependabot show <dependency name> ignore conditionswill show all of the ignore conditions of the specified dependency@dependabot ignore this major versionwill 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 versionwill 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 dependencywill 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.