From 7383c475d87d1d794835d901d79d6c4c80157638 Mon Sep 17 00:00:00 2001 From: Timo Tijhof Date: Sun, 27 Mar 2022 18:43:18 +0100 Subject: [PATCH] Add `feed.updated_deterministic` setting Two main uses cases: 1. Reduce deployment churn in repositories that hold a docsite in addition to source code. These currently regenerate and find something new commit on every change, even when nothing in the site has been changed. The only file changing each time is feed.xml. For example: https://github.com/qunitjs/qunit/commits/gh-pages 2. Improve reproducibility of the build, as highlighted via https://github.com/jekyll/jekyll/pull/7187, by offering a choice that simply eliminates use of current time entirely, not even having to mock it. --- README.md | 11 +++++++++++ lib/jekyll-feed/feed.xml | 8 +++++++- spec/jekyll-feed_spec.rb | 19 +++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 62694793..81163fba 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,17 @@ feed: To note, you shouldn't have to do this unless you already have a feed you're using, and you can't or wish not to redirect existing subscribers. +### Deterministic timestamp + +By default, the feed will set `` to the current time (as provided by Jekyll via `site.time`). + +Enable the `updated_deterministic` setting to set this instead to a deterministic value based on when the last post was published or updated. + +```yml +feed: + updated_deterministic: true +``` + ### Optional front matter The plugin will use the following post metadata, automatically generated by Jekyll, which you can override via a post's YAML front matter: diff --git a/lib/jekyll-feed/feed.xml b/lib/jekyll-feed/feed.xml index 9068836f..cd018036 100644 --- a/lib/jekyll-feed/feed.xml +++ b/lib/jekyll-feed/feed.xml @@ -6,7 +6,6 @@ Jekyll - {{ site.time | date_to_xmlschema }} {{ page.url | absolute_url | xml_escape }} {% assign title = site.title | default: site.name %} @@ -51,6 +50,13 @@ {% assign posts = posts | where_exp: "post", "post.draft != true" %} {% endunless %} {% assign posts = posts | sort: "date" | reverse %} + {% if site.feed.updated_deterministic %} + {% assign last_post = posts | first %} + {% assign last_updated = last_post.last_modified_at | default: last_post.date | default: site.time %} + {% else %} + {% assign last_updated = site.time %} + {% endif %} + {{ last_updated | date_to_xmlschema }} {% assign posts_limit = site.feed.posts_limit | default: 10 %} {% for post in posts limit: posts_limit %} diff --git a/spec/jekyll-feed_spec.rb b/spec/jekyll-feed_spec.rb index f739a2e2..a763aeb3 100644 --- a/spec/jekyll-feed_spec.rb +++ b/spec/jekyll-feed_spec.rb @@ -116,6 +116,7 @@ context "parsing" do let(:feed) { RSS::Parser.parse(contents) } + let(:overrides) { { "time" => Time.parse("2018-12-31") } } it "outputs an RSS feed" do expect(feed.feed_type).to eql("atom") @@ -134,6 +135,24 @@ expect(feed.generator.version).to eql(Jekyll::VERSION) end + context "with site.feed.updated_deterministic set" do + let(:overrides) do + { + "feed" => { + "updated_deterministic" => true, + }, + } + end + + it "outputs the last post time" do + expect(feed.updated.content).to eql(Time.parse("2016-04-25")) + end + end + + it "outputs the current time" do + expect(feed.updated.content).to eql(Time.parse("2018-12-31")) + end + it "includes the items" do expect(feed.items.count).to eql(10) end