mirror of
https://github.com/tiennm99/penny-pincher-provider.git
synced 2026-10-11 03:13:43 +00:00
feat(deploy): publish to GitHub Pages and Cloudflare Pages
Build the site from one source and deploy it to both hosts from GitHub Actions, so neither depends on a host's default Jekyll toolchain. - Gemfile/Gemfile.lock pin Jekyll 4.4.1 on Ruby 3.4; both workflows use them, which keeps the two sites on an identical toolchain - _config.yml carries the GitHub Pages url and baseurl, fixing asset paths that previously resolved off-site; _config.cloudflare.yml layers over it for the pages.dev root - wrangler.jsonc declares the Pages project name and output directory - 404.html gives both hosts a page for unmatched routes - exclude README.md from the output and stop shipping CSS sourcemaps
This commit is contained in:
1 parent
8d52ed0dd0
commit
64987877a9
11 files changed
+532
No files matched your search
@@ -0,0 +1,38 @@
|
|||||||
|
name: Deploy to Cloudflare Pages
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: cloudflare-pages
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: ruby/setup-ruby@v1
|
||||||
|
with:
|
||||||
|
ruby-version: '3.4'
|
||||||
|
bundler-cache: true
|
||||||
|
|
||||||
|
# Layers _config.cloudflare.yml on top, swapping the GitHub Pages subpath
|
||||||
|
# for the pages.dev root.
|
||||||
|
- name: Build site
|
||||||
|
run: bundle exec jekyll build --config _config.yml,_config.cloudflare.yml
|
||||||
|
env:
|
||||||
|
JEKYLL_ENV: production
|
||||||
|
|
||||||
|
# Project name and output directory come from wrangler.jsonc.
|
||||||
|
- uses: cloudflare/wrangler-action@v4
|
||||||
|
with:
|
||||||
|
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||||
|
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||||
|
command: pages deploy
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
name: Deploy to GitHub Pages
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pages: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
# Let a running deploy finish rather than cancelling it mid-publish.
|
||||||
|
concurrency:
|
||||||
|
group: github-pages
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: ruby/setup-ruby@v1
|
||||||
|
with:
|
||||||
|
ruby-version: '3.4'
|
||||||
|
bundler-cache: true
|
||||||
|
|
||||||
|
# Uses _config.yml only, which carries the tiennm99.github.io/penny-pincher-provider
|
||||||
|
# url and baseurl. actions/configure-pages is deliberately not used — it would
|
||||||
|
# overwrite that baseurl with its own guess.
|
||||||
|
- name: Build site
|
||||||
|
run: bundle exec jekyll build
|
||||||
|
env:
|
||||||
|
JEKYLL_ENV: production
|
||||||
|
|
||||||
|
- uses: actions/upload-pages-artifact@v3
|
||||||
|
with:
|
||||||
|
path: _site
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
needs: build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
environment:
|
||||||
|
name: github-pages
|
||||||
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
|
steps:
|
||||||
|
- id: deployment
|
||||||
|
uses: actions/deploy-pages@v4
|
||||||
+11
@@ -1,2 +1,13 @@
|
|||||||
session-state
|
session-state
|
||||||
settings.local.json
|
settings.local.json
|
||||||
|
|
||||||
|
# Jekyll build output
|
||||||
|
_site/
|
||||||
|
.jekyll-cache/
|
||||||
|
.jekyll-metadata
|
||||||
|
|
||||||
|
# Project-local gems (bundler path config + installed gems)
|
||||||
|
.bundle/
|
||||||
|
|
||||||
|
# Wrangler local state
|
||||||
|
.wrangler/
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
layout: default
|
||||||
|
title: Page not found
|
||||||
|
permalink: /404.html
|
||||||
|
---
|
||||||
|
|
||||||
|
<h1>Page not found</h1>
|
||||||
|
|
||||||
|
<p>That page does not exist. The provider list lives on the
|
||||||
|
<a href="/">home page</a>.</p>
|
||||||
|
|
||||||
|
<p>If a link here is broken,
|
||||||
|
<a href="https://github.com/tiennm99/penny-pincher-provider/issues/new">open an issue</a>.</p>
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
source "https://rubygems.org"
|
||||||
|
|
||||||
|
gem "jekyll", "~> 4.3"
|
||||||
|
gem "minima", "~> 2.5"
|
||||||
|
|
||||||
|
# Ruby 3.x no longer bundles these as default gems.
|
||||||
|
gem "webrick", "~> 1.8"
|
||||||
|
gem "csv", "~> 3.3"
|
||||||
|
gem "base64", "~> 0.2"
|
||||||
|
gem "bigdecimal", "~> 3.1"
|
||||||
+176
@@ -0,0 +1,176 @@
|
|||||||
|
GEM
|
||||||
|
remote: https://rubygems.org/
|
||||||
|
specs:
|
||||||
|
addressable (2.9.0)
|
||||||
|
public_suffix (>= 2.0.2, < 8.0)
|
||||||
|
base64 (0.3.0)
|
||||||
|
bigdecimal (3.3.1)
|
||||||
|
colorator (1.1.0)
|
||||||
|
concurrent-ruby (1.3.8)
|
||||||
|
csv (3.3.6)
|
||||||
|
em-websocket (0.5.3)
|
||||||
|
eventmachine (>= 0.12.9)
|
||||||
|
http_parser.rb (~> 0)
|
||||||
|
eventmachine (1.2.7)
|
||||||
|
ffi (1.17.4)
|
||||||
|
ffi (1.17.4-aarch64-linux-gnu)
|
||||||
|
ffi (1.17.4-aarch64-linux-musl)
|
||||||
|
ffi (1.17.4-arm-linux-gnu)
|
||||||
|
ffi (1.17.4-arm-linux-musl)
|
||||||
|
ffi (1.17.4-arm64-darwin)
|
||||||
|
ffi (1.17.4-x86-linux-gnu)
|
||||||
|
ffi (1.17.4-x86-linux-musl)
|
||||||
|
ffi (1.17.4-x86_64-darwin)
|
||||||
|
ffi (1.17.4-x86_64-linux-gnu)
|
||||||
|
ffi (1.17.4-x86_64-linux-musl)
|
||||||
|
forwardable-extended (2.6.0)
|
||||||
|
google-protobuf (4.36.0)
|
||||||
|
bigdecimal
|
||||||
|
rake (~> 13.3)
|
||||||
|
google-protobuf (4.36.0-aarch64-linux-gnu)
|
||||||
|
bigdecimal
|
||||||
|
rake (~> 13.3)
|
||||||
|
google-protobuf (4.36.0-aarch64-linux-musl)
|
||||||
|
bigdecimal
|
||||||
|
rake (~> 13.3)
|
||||||
|
google-protobuf (4.36.0-arm64-darwin)
|
||||||
|
bigdecimal
|
||||||
|
rake (~> 13.3)
|
||||||
|
google-protobuf (4.36.0-x86-linux-gnu)
|
||||||
|
bigdecimal
|
||||||
|
rake (~> 13.3)
|
||||||
|
google-protobuf (4.36.0-x86-linux-musl)
|
||||||
|
bigdecimal
|
||||||
|
rake (~> 13.3)
|
||||||
|
google-protobuf (4.36.0-x86_64-darwin)
|
||||||
|
bigdecimal
|
||||||
|
rake (~> 13.3)
|
||||||
|
google-protobuf (4.36.0-x86_64-linux-gnu)
|
||||||
|
bigdecimal
|
||||||
|
rake (~> 13.3)
|
||||||
|
google-protobuf (4.36.0-x86_64-linux-musl)
|
||||||
|
bigdecimal
|
||||||
|
rake (~> 13.3)
|
||||||
|
http_parser.rb (0.8.1)
|
||||||
|
i18n (1.15.2)
|
||||||
|
concurrent-ruby (~> 1.0)
|
||||||
|
jekyll (4.4.1)
|
||||||
|
addressable (~> 2.4)
|
||||||
|
base64 (~> 0.2)
|
||||||
|
colorator (~> 1.0)
|
||||||
|
csv (~> 3.0)
|
||||||
|
em-websocket (~> 0.5)
|
||||||
|
i18n (~> 1.0)
|
||||||
|
jekyll-sass-converter (>= 2.0, < 4.0)
|
||||||
|
jekyll-watch (~> 2.0)
|
||||||
|
json (~> 2.6)
|
||||||
|
kramdown (~> 2.3, >= 2.3.1)
|
||||||
|
kramdown-parser-gfm (~> 1.0)
|
||||||
|
liquid (~> 4.0)
|
||||||
|
mercenary (~> 0.3, >= 0.3.6)
|
||||||
|
pathutil (~> 0.9)
|
||||||
|
rouge (>= 3.0, < 5.0)
|
||||||
|
safe_yaml (~> 1.0)
|
||||||
|
terminal-table (>= 1.8, < 4.0)
|
||||||
|
webrick (~> 1.7)
|
||||||
|
jekyll-feed (0.17.0)
|
||||||
|
jekyll (>= 3.7, < 5.0)
|
||||||
|
jekyll-sass-converter (3.1.0)
|
||||||
|
sass-embedded (~> 1.75)
|
||||||
|
jekyll-seo-tag (2.9.0)
|
||||||
|
jekyll (>= 3.8, < 5.0)
|
||||||
|
jekyll-watch (2.2.1)
|
||||||
|
listen (~> 3.0)
|
||||||
|
json (2.21.2)
|
||||||
|
kramdown (2.5.2)
|
||||||
|
rexml (>= 3.4.4)
|
||||||
|
kramdown-parser-gfm (1.1.0)
|
||||||
|
kramdown (~> 2.0)
|
||||||
|
liquid (4.0.4)
|
||||||
|
listen (3.10.0)
|
||||||
|
logger
|
||||||
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||||
|
rb-inotify (~> 0.9, >= 0.9.10)
|
||||||
|
logger (1.7.0)
|
||||||
|
mercenary (0.4.0)
|
||||||
|
minima (2.5.2)
|
||||||
|
jekyll (>= 3.5, < 5.0)
|
||||||
|
jekyll-feed (~> 0.9)
|
||||||
|
jekyll-seo-tag (~> 2.1)
|
||||||
|
pathutil (0.16.2)
|
||||||
|
forwardable-extended (~> 2.6)
|
||||||
|
public_suffix (7.0.5)
|
||||||
|
rake (13.4.2)
|
||||||
|
rb-fsevent (0.11.2)
|
||||||
|
rb-inotify (0.11.1)
|
||||||
|
ffi (~> 1.0)
|
||||||
|
rexml (3.4.4)
|
||||||
|
rouge (4.7.0)
|
||||||
|
safe_yaml (1.0.5)
|
||||||
|
sass-embedded (1.103.1)
|
||||||
|
google-protobuf (~> 4.31)
|
||||||
|
rake (>= 13)
|
||||||
|
sass-embedded (1.103.1-aarch64-linux-android)
|
||||||
|
google-protobuf (~> 4.31)
|
||||||
|
sass-embedded (1.103.1-aarch64-linux-gnu)
|
||||||
|
google-protobuf (~> 4.31)
|
||||||
|
sass-embedded (1.103.1-aarch64-linux-musl)
|
||||||
|
google-protobuf (~> 4.31)
|
||||||
|
sass-embedded (1.103.1-arm-linux-androideabi)
|
||||||
|
google-protobuf (~> 4.31)
|
||||||
|
sass-embedded (1.103.1-arm-linux-gnueabihf)
|
||||||
|
google-protobuf (~> 4.31)
|
||||||
|
sass-embedded (1.103.1-arm-linux-musleabihf)
|
||||||
|
google-protobuf (~> 4.31)
|
||||||
|
sass-embedded (1.103.1-arm64-darwin)
|
||||||
|
google-protobuf (~> 4.31)
|
||||||
|
sass-embedded (1.103.1-riscv64-linux-android)
|
||||||
|
google-protobuf (~> 4.31)
|
||||||
|
sass-embedded (1.103.1-riscv64-linux-gnu)
|
||||||
|
google-protobuf (~> 4.31)
|
||||||
|
sass-embedded (1.103.1-riscv64-linux-musl)
|
||||||
|
google-protobuf (~> 4.31)
|
||||||
|
sass-embedded (1.103.1-x86_64-darwin)
|
||||||
|
google-protobuf (~> 4.31)
|
||||||
|
sass-embedded (1.103.1-x86_64-linux-android)
|
||||||
|
google-protobuf (~> 4.31)
|
||||||
|
sass-embedded (1.103.1-x86_64-linux-gnu)
|
||||||
|
google-protobuf (~> 4.31)
|
||||||
|
sass-embedded (1.103.1-x86_64-linux-musl)
|
||||||
|
google-protobuf (~> 4.31)
|
||||||
|
terminal-table (3.0.2)
|
||||||
|
unicode-display_width (>= 1.1.1, < 3)
|
||||||
|
unicode-display_width (2.6.0)
|
||||||
|
webrick (1.9.2)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
aarch64-linux-android
|
||||||
|
aarch64-linux-gnu
|
||||||
|
aarch64-linux-musl
|
||||||
|
arm-linux-androideabi
|
||||||
|
arm-linux-gnu
|
||||||
|
arm-linux-gnueabihf
|
||||||
|
arm-linux-musl
|
||||||
|
arm-linux-musleabihf
|
||||||
|
arm64-darwin
|
||||||
|
riscv64-linux-android
|
||||||
|
riscv64-linux-gnu
|
||||||
|
riscv64-linux-musl
|
||||||
|
ruby
|
||||||
|
x86-linux-gnu
|
||||||
|
x86-linux-musl
|
||||||
|
x86_64-darwin
|
||||||
|
x86_64-linux-android
|
||||||
|
x86_64-linux-gnu
|
||||||
|
x86_64-linux-musl
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
base64 (~> 0.2)
|
||||||
|
bigdecimal (~> 3.1)
|
||||||
|
csv (~> 3.3)
|
||||||
|
jekyll (~> 4.3)
|
||||||
|
minima (~> 2.5)
|
||||||
|
webrick (~> 1.8)
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
2.6.9
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# Cloudflare Pages overrides, layered on top of _config.yml:
|
||||||
|
# bundle exec jekyll build --config _config.yml,_config.cloudflare.yml
|
||||||
|
#
|
||||||
|
# The site sits at the domain root here, unlike the GitHub Pages subpath.
|
||||||
|
url: https://penny-pincher-provider.pages.dev
|
||||||
|
baseurl: ""
|
||||||
+22
@@ -2,3 +2,25 @@ title: Penny-Pincher Provider
|
|||||||
description: A curated list of affordable (or almost free) LLM providers
|
description: A curated list of affordable (or almost free) LLM providers
|
||||||
theme: minima
|
theme: minima
|
||||||
show_downloads: false
|
show_downloads: false
|
||||||
|
|
||||||
|
# GitHub Pages target. It only ever reads this file, so its values live here and
|
||||||
|
# Cloudflare overrides them via _config.cloudflare.yml.
|
||||||
|
url: https://tiennm99.github.io
|
||||||
|
baseurl: /penny-pincher-provider
|
||||||
|
|
||||||
|
# README.md is the site content, pulled into index.md via include_relative.
|
||||||
|
# Excluding it stops the raw markdown shipping as a duplicate page.
|
||||||
|
exclude:
|
||||||
|
- CLAUDE.md
|
||||||
|
- LICENSE
|
||||||
|
- README.md
|
||||||
|
- Gemfile
|
||||||
|
- Gemfile.lock
|
||||||
|
- wrangler.jsonc
|
||||||
|
- _config.cloudflare.yml
|
||||||
|
- .claude/
|
||||||
|
- docs/
|
||||||
|
- plans/
|
||||||
|
|
||||||
|
sass:
|
||||||
|
sourcemap: never
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
# Deployment
|
||||||
|
|
||||||
|
The site is a Jekyll build of `README.md` (via `index.md`), published to two hosts
|
||||||
|
from the same source. Both deploy from GitHub Actions on every push to `main`.
|
||||||
|
|
||||||
|
| Target | URL | Workflow |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| GitHub Pages | <https://tiennm99.github.io/penny-pincher-provider> | `.github/workflows/github-pages.yml` |
|
||||||
|
| Cloudflare Pages | <https://penny-pincher-provider.pages.dev> | `.github/workflows/cloudflare-pages.yml` |
|
||||||
|
|
||||||
|
Both workflows build with this repo's `Gemfile` (Jekyll 4.4.1 on Ruby 3.4), so the
|
||||||
|
two sites cannot drift apart on toolchain.
|
||||||
|
|
||||||
|
## Config layering
|
||||||
|
|
||||||
|
The only difference between the targets is where the site sits on its domain.
|
||||||
|
|
||||||
|
| File | Role |
|
||||||
|
| --- | --- |
|
||||||
|
| `_config.yml` | Base config **plus GitHub Pages values** — `url: https://tiennm99.github.io`, `baseurl: /penny-pincher-provider`. |
|
||||||
|
| `_config.cloudflare.yml` | Overrides for the pages.dev root — `baseurl: ""`. Layered on top, never used alone. |
|
||||||
|
|
||||||
|
```sh
|
||||||
|
bundle exec jekyll build # GitHub Pages
|
||||||
|
bundle exec jekyll build --config _config.yml,_config.cloudflare.yml # Cloudflare
|
||||||
|
```
|
||||||
|
|
||||||
|
Order matters: later files win. `_config.cloudflare.yml` is excluded from the site
|
||||||
|
output.
|
||||||
|
|
||||||
|
## GitHub Pages setup
|
||||||
|
|
||||||
|
One repo setting, once: **Settings → Pages → Source → GitHub Actions**. Without it
|
||||||
|
the workflow's deploy step fails.
|
||||||
|
|
||||||
|
The workflow deliberately does not use `actions/configure-pages` — that action
|
||||||
|
rewrites `baseurl` with its own guess, which would fight the explicit value in
|
||||||
|
`_config.yml`.
|
||||||
|
|
||||||
|
## Cloudflare Pages setup
|
||||||
|
|
||||||
|
The project must be **Direct Upload**, not Git-connected. A Git-connected project
|
||||||
|
would build on every push as well, deploying twice and racing the workflow.
|
||||||
|
|
||||||
|
1. Create the project once, either in the dashboard (**Workers & Pages → Create →
|
||||||
|
Pages → Upload assets**, named `penny-pincher-provider`) or locally:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npx wrangler pages project create penny-pincher-provider --production-branch main
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Add two repository secrets under **Settings → Secrets and variables → Actions**:
|
||||||
|
|
||||||
|
| Secret | Where to get it |
|
||||||
|
| --- | --- |
|
||||||
|
| `CLOUDFLARE_API_TOKEN` | My Profile → API Tokens → Create Token, with the **Cloudflare Pages: Edit** permission. |
|
||||||
|
| `CLOUDFLARE_ACCOUNT_ID` | Workers & Pages overview sidebar, or `npx wrangler whoami`. |
|
||||||
|
|
||||||
|
`wrangler.jsonc` supplies the project name and `pages_build_output_dir`, so the
|
||||||
|
workflow's `pages deploy` command needs no arguments.
|
||||||
|
|
||||||
|
## Building locally
|
||||||
|
|
||||||
|
Requires Ruby 3.4.x with Bundler (3.4.8 is what this project was developed
|
||||||
|
against). Jekyll does not yet support Ruby 4.0 — do not upgrade past the 3.4 branch.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
bundle config set --local path .bundle/gems # first time only
|
||||||
|
bundle install
|
||||||
|
JEKYLL_ENV=production bundle exec jekyll build
|
||||||
|
```
|
||||||
|
|
||||||
|
Gems install into the gitignored `.bundle/` inside the repo rather than the shared
|
||||||
|
rbenv gem home, keeping the project self-contained. To deploy to Cloudflare by hand,
|
||||||
|
build with the Cloudflare config and run `npx wrangler pages deploy` after
|
||||||
|
`npx wrangler login`.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- `Gemfile.lock` is committed. It was generated on aarch64 but its `PLATFORMS` list
|
||||||
|
includes `x86_64-linux-gnu`, which is what GitHub runners use — without that entry
|
||||||
|
CI installs would fail. Re-check it after any `bundle update`.
|
||||||
|
- `_config.yml` excludes `README.md` from the output. It is still the site's
|
||||||
|
content, pulled into `index.md` by `include_relative`, which reads excluded files
|
||||||
|
fine — the exclusion only stops the raw markdown shipping as a duplicate page.
|
||||||
|
- `404.html` is served automatically by both hosts for unmatched routes.
|
||||||
|
- Ruby is pinned to the `3.4` series in both workflows rather than an exact patch.
|
||||||
|
Cloudflare's own build image is irrelevant here, since Actions does the building.
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
# Research Report: Stable Ruby Version for 1–2 Year Horizon
|
||||||
|
|
||||||
|
Conducted 2026-08-28. Context: local rbenv install + Cloudflare Workers build for this Jekyll site.
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
|
||||||
|
**Install Ruby 3.4.4.** Not 4.0, not 3.3, and not the 3.2.2 recommended earlier in this session
|
||||||
|
(3.2 hit EOL 2026-04-01).
|
||||||
|
|
||||||
|
Two constraints decide it, both external:
|
||||||
|
|
||||||
|
1. **Jekyll has no Ruby 4.0 support.** Jekyll 4.4.1 (Jan 2025, still latest) declares `>= 2.7.0`
|
||||||
|
and recommends 3.2+. Theme gems constrained to `~> 3.1` fail version solving under 4.0.
|
||||||
|
2. **Cloudflare's build image defaults to Ruby 3.4.4.** Pinning anything else risks a build
|
||||||
|
image that cannot supply it — and there is conflicting evidence that recent 3.4.x patches
|
||||||
|
are unavailable (see Conflict below).
|
||||||
|
|
||||||
|
3.4 is the only branch in normal (non-security-only) maintenance that Jekyll actually supports.
|
||||||
|
Picking the exact patch Cloudflare defaults to gives local/CI parity for free.
|
||||||
|
|
||||||
|
## Methodology
|
||||||
|
|
||||||
|
- Sources: 5 (ruby-lang.org branches page, Cloudflare Workers build-image docs, 3 web searches)
|
||||||
|
- Date range: 2024-12 (Ruby 3.4.0) → 2026-07 (Ruby 4.0.6)
|
||||||
|
- Terms: ruby maintenance branches EOL, ruby 3.5/4.0 stable, jekyll ruby 4.0 compatibility,
|
||||||
|
cloudflare workers build image RUBY_VERSION
|
||||||
|
|
||||||
|
## Key Findings
|
||||||
|
|
||||||
|
### 1. Ruby 3.5 does not exist — it shipped as 4.0
|
||||||
|
|
||||||
|
The version after 3.4 was renumbered. Ruby 4.0.0 released 2025-12-25; latest patch 4.0.6
|
||||||
|
(2026-07-14). Anyone searching for "Ruby 3.5 stable" finds only the April 2025 preview.
|
||||||
|
|
||||||
|
### 2. Branch status as of 2026-08-28
|
||||||
|
|
||||||
|
| Branch | Status | Released | EOL | Verdict |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| 4.0 | Normal maintenance | 2025-12-25 | TBD (~2029-03) | Too early — Jekyll unsupported |
|
||||||
|
| 3.4 | Normal maintenance | 2024-12-25 | TBD (~2028-03) | **Pick this** |
|
||||||
|
| 3.3 | Security maintenance only | 2023-12-25 | 2027-03-31 | <1 yr left, no bug fixes |
|
||||||
|
| 3.2 | **EOL** | 2022-12-25 | 2026-04-01 | Dead — no security patches |
|
||||||
|
|
||||||
|
EOL dates for 3.4/4.0 are unpublished. Ruby's historical cadence is ~2 yrs normal + ~1 yr
|
||||||
|
security, so 3.4 EOL lands ~March 2028 — comfortably past a 2-year horizon. Treat as
|
||||||
|
convention, not commitment.
|
||||||
|
|
||||||
|
### 3. Jekyll compatibility
|
||||||
|
|
||||||
|
Jekyll 4.4.0 (Jan 2025) added Ruby 3.4 support; 4.4.1 is current. No Jekyll release has
|
||||||
|
declared Ruby 4.0 support. Community reports (chirpy theme issue #2640, Jan 2026) show
|
||||||
|
dependency resolution failing on 4.0. Ruby 3.4 moved `csv`, `base64`, `bigdecimal` to bundled
|
||||||
|
gems — this repo's `Gemfile` already declares them explicitly, so it is 3.4-ready as written.
|
||||||
|
|
||||||
|
### 4. Cloudflare build image
|
||||||
|
|
||||||
|
- Default Ruby **3.4.4**; OS Ubuntu 24.04; x86_64; Node 24.18.0.
|
||||||
|
- Override via `RUBY_VERSION` env var or `.ruby-version` file.
|
||||||
|
- Policy: minor versions may auto-update without notice; pin to avoid drift.
|
||||||
|
|
||||||
|
**Conflict:** the docs claim "all versions are available for override," but open issue
|
||||||
|
cloudflare-docs#27779 ("Recent Ruby versions aren't yet supported") reports 3.4.5–3.4.8
|
||||||
|
unavailable. Unresolved. Pinning 3.4.4 sidesteps it entirely — it is the default, so it is
|
||||||
|
guaranteed present.
|
||||||
|
|
||||||
|
### 5. Security
|
||||||
|
|
||||||
|
3.2 is EOL: no further CVE patches. Anything still on it should move. 3.3 gets security fixes
|
||||||
|
only until 2027-03-31 — inside the requested horizon, so it fails the 1–2 year test. 3.4 is the
|
||||||
|
oldest branch still receiving ordinary bug fixes.
|
||||||
|
|
||||||
|
## Recommendation
|
||||||
|
|
||||||
|
```sh
|
||||||
|
rbenv install 3.4.4
|
||||||
|
cd /config/workspace/tiennm99/penny-pincher-provider
|
||||||
|
rbenv local 3.4.4 # writes .ruby-version; Cloudflare reads the same file
|
||||||
|
```
|
||||||
|
|
||||||
|
Requires `libyaml-dev` present first (psych failure seen earlier this session).
|
||||||
|
|
||||||
|
Horizon: safe to ~March 2028 on 3.4. Revisit when Jekyll declares Ruby 4.0 support, or by
|
||||||
|
early 2028, whichever is first.
|
||||||
|
|
||||||
|
### Correction required in existing docs
|
||||||
|
|
||||||
|
`docs/cloudflare-deployment.md` (written earlier this session) states the build image ships
|
||||||
|
Ruby 3.2 and suggests `RUBY_VERSION=3.2.2`. Both wrong — default is 3.4.4. With a committed
|
||||||
|
`.ruby-version` the env-var fallback becomes unnecessary.
|
||||||
|
|
||||||
|
### Pitfalls
|
||||||
|
|
||||||
|
- Don't pin a 3.4.x newer than 3.4.4 until #27779 resolves.
|
||||||
|
- Don't rely on Cloudflare's default staying 3.4.4 — minors update without notice; the
|
||||||
|
`.ruby-version` file is the pin.
|
||||||
|
- Ruby 4.0 local + Jekyll = dependency resolution failure, not a runtime error. Looks confusing.
|
||||||
|
|
||||||
|
## Sources
|
||||||
|
|
||||||
|
- [Ruby maintenance branches](https://www.ruby-lang.org/en/downloads/branches/)
|
||||||
|
- [Cloudflare Workers build image](https://developers.cloudflare.com/workers/ci-cd/builds/build-image/)
|
||||||
|
- [cloudflare-docs#27779 — recent Ruby versions unsupported](https://github.com/cloudflare/cloudflare-docs/issues/27779)
|
||||||
|
- [Jekyll 4.4.0 release notes](https://jekyllrb.com/news/2025/01/27/jekyll-4-4-0-released/)
|
||||||
|
- [chirpy#2640 — Add Ruby 4 support](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2640)
|
||||||
|
|
||||||
|
## Unresolved
|
||||||
|
|
||||||
|
1. Exact EOL dates for 3.4 and 4.0 — unpublished; ~2028-03 / ~2029-03 inferred from cadence.
|
||||||
|
2. Whether Cloudflare actually rejects 3.4.5+ (docs vs. issue conflict). Untested.
|
||||||
|
3. Jekyll's Ruby 4.0 timeline — no roadmap statement found.
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
// Cloudflare Pages project. The site is fully static — no Pages Functions —
|
||||||
|
// so this file only declares where Jekyll writes its output.
|
||||||
|
"name": "penny-pincher-provider",
|
||||||
|
"compatibility_date": "2026-08-28",
|
||||||
|
|
||||||
|
// Produced by `bundle exec jekyll build`; see docs/cloudflare-deployment.md
|
||||||
|
"pages_build_output_dir": "./_site"
|
||||||
|
}
|
||||||
Reference in new issue
Block a user