Skip to content

Commit

Permalink
Add feed.updated_deterministic setting
Browse files Browse the repository at this point in the history
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
   jekyll/jekyll#7187, by offering a choice
   that simply eliminates use of current time entirely, not even
   having to mock it.
  • Loading branch information
Krinkle committed Mar 27, 2022
1 parent 423ca21 commit 7383c47
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 1 deletion.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<updated>` 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:
Expand Down
8 changes: 7 additions & 1 deletion lib/jekyll-feed/feed.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
<generator uri="https://jekyllrb.com/" version="{{ jekyll.version }}">Jekyll</generator>
<link href="{{ page.url | absolute_url }}" rel="self" type="application/atom+xml" />
<link href="{{ '/' | absolute_url }}" rel="alternate" type="text/html" {% if site.lang %}hreflang="{{ site.lang }}" {% endif %}/>
<updated>{{ site.time | date_to_xmlschema }}</updated>
<id>{{ page.url | absolute_url | xml_escape }}</id>

{% assign title = site.title | default: site.name %}
Expand Down Expand Up @@ -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 %}
<updated>{{ last_updated | date_to_xmlschema }}</updated>
{% assign posts_limit = site.feed.posts_limit | default: 10 %}
{% for post in posts limit: posts_limit %}
<entry{% if post.lang %}{{" "}}xml:lang="{{ post.lang }}"{% endif %}>
Expand Down
19 changes: 19 additions & 0 deletions spec/jekyll-feed_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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
Expand Down

0 comments on commit 7383c47

Please sign in to comment.