Skip to content

Commit

Permalink
ci: legg til ny workflow for å varsla abonnentar når nytt innlegg bli…
Browse files Browse the repository at this point in the history
…r publisert
  • Loading branch information
adalinesimonian committed Feb 23, 2024
1 parent 0c78b82 commit f9563ff
Show file tree
Hide file tree
Showing 7 changed files with 212 additions and 4 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/notify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Notify subscribers of new posts

on:
push:
branches: [main]

workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: 'pages'
cancel-in-progress: false

jobs:
notify:
runs-on: ubuntu-latest
environment: subscriber-notification
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
cache-version: 0 # Increase this version to clear the cache

- name: Post-install script
run: rake postinstall

- name: Setup Pages
id: pages
uses: actions/configure-pages@v4

- name: Build with Jekyll
run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}"
env:
JEKYLL_ENV: production

- name: Notify subscribers
run: rake notify_new_post
env:
API_KEY: ${{ secrets.API_KEY }}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ _sass/bootstrap
assets/js/bootstrap
assets/js/lunr.js
search_index.json
new_post.json
secrets.yml
98 changes: 94 additions & 4 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
require 'rake'
require 'date'
require 'fileutils'
require 'open-uri'
require 'json'
require 'yaml'
require 'net/http'

task :default => [:install, :serve, :build]

Expand All @@ -12,8 +18,6 @@ desc 'Post install tasks'
task :postinstall do
# Copy bootstrap files

require 'fileutils'

bootstrap_gem_path = `bundle show bootstrap`.strip
sass_target_path = '_sass/bootstrap'
js_target_path = 'assets/js/bootstrap'
Expand All @@ -28,13 +32,99 @@ task :postinstall do
FileUtils.cp_r(Dir.glob("#{bootstrap_gem_path}/assets/javascripts/*"), js_target_path)

# Download lunr.js from https://unpkg.com/lunr/lunr.js and save it to assets/js/lunr.js
require 'open-uri'

open('assets/js/lunr.js', 'wb') do |file|
file << URI.open('https://unpkg.com/lunr/lunr.min.js').read
end
end

desc 'Notify about new posts'
task :notify_new_post do
api_key = ENV['API_KEY']

if api_key.nil?
# try reading from secrets.yml
begin
secrets = YAML.load_file('secrets.yml')
api_key = secrets['apiKey']
rescue
end
end

if api_key.nil?
puts 'API_KEY is not set, not notifying'
exit 1
end

if !File.exist?('new_post.json')
puts 'No new post was created'
exit 0
end

new_post_raw = File.read('new_post.json')

if new_post_raw.nil?
puts 'Failed to read new_post.json'
exit 1
end

new_post = JSON.parse(new_post_raw)

required_props = ['title', 'url', 'summary']

if required_props.any? { |prop| new_post[prop].nil? }
puts 'new_post.json is missing one or more required properties: ' + required_props.join(', ')
exit 1
end

# safety check so we don't send accidentally notify about old posts
# if the latest post is not from within the last 24 hours, don't notify
if DateTime.parse(new_post['date']).to_time < Time.now - 24 * 60 * 60
puts 'Latest post is older than 24 hours, not notifying'
exit 0
end

puts 'Notifying about new post'
puts new_post

# Send POST to https://blog-api.ordbokapi.org/new-post
# The API server expects a JSON body like this:
# {
# "title": "New post title",
# "url": "https://blog.ordbokapi.org/2020/01/01/new-post.html",
# "summary": "A short summary of the new post"
# }
# The API server will respond with a 202 Accepted status code if the request is successful.
# The API key is expected to be passed in the Authorization header.

# read api server url from _data/api.yml (baseUrl)

api_config = YAML.load_file('_data/api.yml')
api_url = api_config['baseUrl'] + '/new-post'
uri = URI.parse(api_url)

http = Net::HTTP.new(uri.host, uri.port)

request = Net::HTTP::Post.new(uri.request_uri)
request['Authorization'] = api_key
request['Content-Type'] = 'application/json'
request.body = JSON.generate({
title: new_post['title'],
url: new_post['url'],
summary: new_post['summary']
})

response = http.request(request)

if response.code == '202'
puts 'Notification sent successfully'
else
puts 'Failed to send notification'
puts response.code
puts response.body
exit 1
end
end

desc 'Start the Jekyll server'
task :serve do
sh 'bundle exec jekyll serve'
Expand Down
5 changes: 5 additions & 0 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ plugins:
#
exclude:
- search_index.json
- new_post.json
- secrets.yml
- renovate.json
- README.md
- Rakefile
# exclude:
# - .sass-cache/
# - .jekyll-cache/
Expand Down
2 changes: 2 additions & 0 deletions _data/footer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ links:
url: https://github.com/ordbokapi
- title: Bluesky
url: https://bsky.app/profile/ordbokapi.org
- title: Abonner på oppdateringar
url: /subscribe/
2 changes: 2 additions & 0 deletions _data/nav.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ pages:
url: /
- title: Om
url: /om/
- title: Abonner
url: /subscribe/
60 changes: 60 additions & 0 deletions _plugins/generate_new_post_json.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
require 'json'

module Jekyll
class LatestPostGenerator < Generator
safe true
priority :low

def generate(site)
puts "Jekyll New Post JSON Generator: Checking for new posts"

begin
File.delete('new_post.json')
rescue
end

# Check for new files in the last commit in the _posts directory
changed_files = `git diff-tree --no-commit-id --name-status -r HEAD`.lines
new_posts = changed_files.select { |line| line.start_with?('A') && line.include?('_posts/') }

if new_posts.empty?
puts 'No new post was created'
return
end

# map the new posts to their jekyll data
new_posts = new_posts.map do |line|
file = line.split("\t").last.strip
post = site.posts.docs.find { |p| p.relative_path == file }

if post.nil?
next
end

{
title: post.data['title'],
date: post.date,
author: site.data['authors'][post.data['author']],
url: site.config['url'] + post.url,
summary: post.data['summary']
}
end
new_posts = new_posts.compact

new_post = new_posts.max_by { |post| post[:date] }

# safety check so we don't send accidentally notify about old posts
# if the latest post is not from within the last 24 hours, don't notify
if new_post[:date] < Time.now - 24 * 60 * 60
puts 'Latest post is older than 24 hours, not notifying'
return
end

# Write to a JSON file in the repository root
write_path = File.join('new_post.json')
File.open(write_path, 'w') do |file|
file.write(JSON.pretty_generate(new_post))
end
end
end
end

0 comments on commit f9563ff

Please sign in to comment.