Skip to content

CI: add Ruby head as an informational build - #201

Merged
julik merged 4 commits into
masterfrom
add-ruby-head
Jun 22, 2026
Merged

julik merged 4 commits into
masterfrom
add-ruby-head

Conversation

@julik

@julik julik commented Jun 9, 2026 •

Copy link
Copy Markdown
Collaborator

Adds Ruby head to CI as an informational (non-blocking) build so we get early warning of breakage on upcoming Ruby.

To make the head build actually run the suite, bumps the puma dev dependency from ~> 3.11 to ~> 5.6 — puma 3's C extension no longer compiles on Ruby head (it uses C macros removed in Ruby 4.0+). This supersedes the long-stale #193.

Changes

  • CI: ruby-version: "head" added via matrix.include with allow-failure: true; job uses continue-on-error so a head failure won't block merges. Pinned Rubies (2.4, 3.0, 3.4.1, 4.0.5) stay required.
  • puma 5: bump dev dependency; Rack::Handler::Puma.run now takes keyword options.
  • Chunked-upload specs: puma 5 decodes the hop-by-hop Transfer-Encoding header before the app sees it (RFC 7230 §3.3.1), so the old header assertion no longer works. Reworked to capture the raw request over a socket (with optional TLS) and assert Patron streams Transfer-Encoding: chunked with no Content-Length — server-agnostic and testing the real client contract.

🤖 Generated with Claude Code

julik and others added 4 commits June 9, 2026 12:16
Add `head` to the test matrix so we get early warning of breakage on
upcoming Ruby, while keeping it non-blocking via continue-on-error.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…head

puma 3.x's native extension uses the Data_Make_Struct/Data_Get_Struct
C macros, which were removed from Ruby's C API in 4.0+, so it no longer
compiles on Ruby head. puma 5 uses the TypedData_* API and builds fine.
This supersedes the long-stale #193.

Adapt the test harness to puma 5:
- Rack::Handler::Puma.run now takes keyword options, not a positional hash.
- puma de-chunks requests server-side (it deletes Transfer-Encoding and
  sets Content-Length to the decoded size), so the chunked-upload specs
  can no longer observe the header. Rework them to assert the file
  round-trips intact instead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Transfer-Encoding is a hop-by-hop header (RFC 7230 3.3.1): a conformant
server decodes the chunked framing and never hands the header to the Rack
app. webrick and puma 3 leaked it into the env, which the old assertion
relied on; puma 5 does not. The previous comment wrongly framed this as
puma buffering and setting Content-Length, which is an incidental server
detail, not the reason the header is unobservable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The round-trip rework verified the file arrives intact, but would also pass
if Patron buffered the body and sent Content-Length instead of streaming it.
The contract these specs exist to protect -- that put_file/post_file stream
with Transfer-Encoding: chunked -- is only observable on the wire, because a
conformant server decodes the hop-by-hop framing before the app sees it.

Add a small raw-socket capture helper (RawRequestCapture, with optional TLS
termination using the test certs) and point the chunked specs at it, asserting
the request carries Transfer-Encoding: chunked, no Content-Length, and delivers
the file intact. This is server-agnostic and immune to the puma de-chunking.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@julik
julik merged commit 57be48b into master Jun 22, 2026
10 checks passed
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.

1 participant