[go: up one dir, main page]
More Web Proxy on the site http://driver.im/ Skip to main content
Alex Hyett

Scheduling Posts with a Static Site

I finally got around to publishing my new website design this week. It is not 100% done, but it is a good basis that I can build from.

My previous site was built on Gatsby with all my posts stored in Strapi. This made scheduling posts relatively simple with a script that published the post on Strapi and then call to GitHub trigger my website build.

I am now using eleventy (11ty) for my new website, so I needed a new way of scheduling my posts.

If you Google how to do this, you will get a lot of people mention the GitHub Action gr2m/merge-schedule-action which allows you to merge a PR automatically if it has /schedule 2024-05-12T12:00:00Z in the comment.

This sounded like a great solution, unfortunately the GitHub Action no longer seems to work. I am guessing GitHub changed something with their permissions and I ended up with the same error shown in one of the open issues.

Luckily GitHub has a pretty extensive API so writing a quick script to do this was the easiest option.

This script needed to do the following:

  1. Get a list of open pull requests for my blog repo.
  2. Loop through each PR looking for a string that matches /schedule <date_string> of the form /schedule 2024-05-12T12:00:00Z somewhere in the comment.
  3. Check to see if the date is either now or in the past.
  4. If it is, then comment on the PR and merge it into main.

I then a have a GitHub Action when something is merged into main that builds and deploys my website.

This is the script that I came up with:

#!/bin/bash

# This script checks for open pull requests and merges them based on
# a "/schedule 2024-05-02T08:00:00Z" comment in your PR.
#
# Script requires the package jq
# GITHUB_TOKEN can be supplied using .env file
#
# Token should be a fine grained token with Read and write access to
# Contents - needed to merge
# Pull Requests - needed to post a comment
#
# Read access is also required to Metadata which is given by default.

# Runs script in local directory to pick up .env file
parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
cd "$parent_path"

# Import variables
set -a
source .env
set +a

OWNER=alexhyett # Your GitHub Username
REPO=alexhyett-website # The repo for your website.

# Get list of open PRs for repo
response=$(curl -L -s -w "\n%{http_code}" \
  -H "Accept: application/vnd.github+json" \
  -H "Authorization: Bearer $GITHUB_TOKEN" \
  -H "X-GitHub-Api-Version: 2022-11-28" \
  https://api.github.com/repos/$OWNER/$REPO/pulls)

response=(${response[@]})
status_code=${response[*]: -1}
pull_requests=${response[@]::${#response[@]}-1}

if [ $status_code -ne 200 ];
then
    echo "Unable to get pull requests. Status Code: $status_code"
    exit 1
fi

# Should match /schedule 2024-05-02T08:00:00Z or /schedule 2024-05-02T08:00:00
regex='\/schedule ([0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z?)'

echo $pull_requests | jq -c '.[]' | while read pr; do
    body=$(echo $pr | jq -c '.body')
    pull_number=$(echo $pr | jq -c '.number')
    title=$(echo $pr | jq -c '.title')

    if [[ $body =~ $regex ]]
    then
        date="${BASH_REMATCH[1]}"
        now=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

        # Alphabetical string match
        if [[ $date < $now || $date = $now ]];
        then
            # Add a merge comment
            status_code=$(curl -L -w '%{http_code}' -s -o /dev/null \
                -X POST \
                -H "Accept: application/vnd.github+json" \
                -H "Authorization: Bearer $GITHUB_TOKEN" \
                -H "X-GitHub-Api-Version: 2022-11-28" \
                https://api.github.com/repos/$OWNER/$REPO/issues/$pull_number/comments \
                -d '{"body":"Automatically merging PR on schedule"}')

            if [ $status_code -eq 201 ];
            then
                # Merge Pull Request
                status_code=$(curl -L -w '%{http_code}' -s -o /dev/null \
                    -X PUT \
                    -H "Accept: application/vnd.github+json" \
                    -H "Authorization: Bearer $GITHUB_TOKEN" \
                    -H "X-GitHub-Api-Version: 2022-11-28" \
                    https://api.github.com/repos/$OWNER/$REPO/pulls/$pull_number/merge \
                    -d '{"commit_title":'"$title"',"commit_message":"Automatically merged"}')

                if [ $status_code -ne 200 ];
                then
                    echo "Failed to merge pull request. Status code: $status_code"
                fi
            else
                echo "Failed to post comment. Status code: $status_code"
            fi
        fi
    fi
done

To use this script you will need to create a fine-grained GitHub personal access token with the following read & write permissions to your repository:

This token should be saved to a .env file in the same directory using the variable GITHUB_TOKEN e.g.

GITHUB_TOKEN=github_pat_11Ajdi9s9383h7sdsFGGDs839290jds_s73w9s9w9dshSSDDg

I then run this script on my home server every 15 minutes using cron. If you don't have a home server you could run this on a free Oracle VM instead.

The hardest part of this script was just working out how to get curl to output the response as well as the status code, which you can see in the first curl command.

I wrote this script using bash, so it could mostly run anywhere, but it does have a few dependencies. In addition to curl which you mostly likely already have installed you will also need jq installed for parsing the json response from the APIs.


❤️ Picks of the Week #

📝 Article - Should you self-host Google Fonts? - I am using the Atkinson Hyperlegible font on my new site. I did wonder whether it is worth self-hosting but after reading this it turns out Google are doing a lot of optimisations that it is just not worth the effort.

📝 Article - Programming mantras are proverbs - It is easy to take things like SOLID and YAGNI as rules that need to be obeyed. Really they are more like intelligent suggestions and they aren't always the right choice.

📝 Article - Wait the Piña Colada song is about what?! - This made me laugh. I think the last time I heard this song is in the film "Guardians of the Galaxy" and it was likely only the chorus. I never realised what the song was actually about.

📝 Article - Why you need TDD - I always use TDD when I am fixing a bug, but I have never got into it for normal coding. I probably should and this post gives quite a compelling argument too.

📝 Article - Rebuilding my website with Eleventy - It looks like I am not the only one who has been rebuilding my website with Eleventy. I might introduce a like button and a link to Mastodon in future as well. Search is another topic I need to tackle as well.

🎬 Video - Apple's message falls flat - I am not sure what Apple were thinking when they made the new iPad advert. They are usually very good with their adverts but destroying all the things that creatives love in order to promote the iPad is not a great way to go.

📝 Article - Stack Overflow Upset Over Users Deleting Answers After OpenAI Partnership - Stack Overflow is going to get a lot less useful if people start deleting content. I can see why though, the same happened with Reddit.


👨‍💻 Latest from me #

As I mentioned in this week's post, my new website is live. I still have a few optimizations to do, but most pages are already under my 100 Kb target. I will probably discuss some of the design decisions and tweaks in one of my later posts.

If you didn't know you can also subscribe to my website (and this newsletter) using RSS as well. I know we all get a lot of emails already so if you use RSS check out my RSS Feed.

I also wrote a blog post this week on setting up my Windows gaming VM on my Unraid server, if that sort of thing interests you.


💬 Quote of the Week #

Don’t let comparison be the thief of your joy. Live your life the way you want to and spend time on things and activities you enjoy. That will lead you to a long-term state of happiness.

From the article Material Things Will Never Make You Happy – Here’s Why


Linked mentions (1)
♥ donating = loving

Each month, I spend many hours making my content available to everyone for free while remaining ad-free. If you have enjoyed my work, please consider supporting my independent writing with a one-time or loyal donation. Your support makes all the difference.

Subscribe to my newsletter

The Curious Engineer is my weekly newsletter when I share my thoughts on software development, careers, productivity, self-hosting, and entrepreneurship.

Or subscribe via Buttondown

Skip back to main content