In the summer of 2020, GitHub quietly released a feature that was quickly noticed by the community – profile READMEs. A profile README is a global README
file for your GitHub profile, which you can set up by creating a public repository whose name is identical to your GitHub username. For instance, as my username is osteel
, I created the osteel/osteel
repository.
A little box like this one should appear while you add your own:
Once the repository is created, add a README
file with a short description explaining how great you are, and your GitHub profile page will display its content by default:
Neat and simple.
As I was browsing examples for some inspiration, I stumbled upon Simon Willison's version, which features some dynamic content like recent work and blog publications. He explained how he used a combination of GitHub Actions and Python to achieve this in a blog post, and I decided to do something similar with PHP.
The placeholder
The first thing to do is to create a placeholder in the README
file where the dynamic content will go. Since I wanted to automatically insert the latest publications of my blog, I used the following tags:
<!-- posts --><!-- /posts -->
You might recognise this format; since Markdown files also support HTML, I used some HTML comment tags to make sure they wouldn't show up on my profile page.
The PHP script
I can't remember the last time I wrote some PHP without a framework; as a result, I had to do a quick search just to get started with a basic PHP script and some Composer dependencies.
Turn out it's quite simple! The first step is to initialise the project with the following command:
$ composer init
From there, I installed a lightweight library to parse my blog's RSS feed:
$ composer require dg/rss-php
I then added a posts.php
file at the root of the project, with the following content:
<?php
// Load Composer's autoload
require_once __DIR__ . '/vendor/autoload.php';
// Load the RSS feed
$feed = Feed::loadRss('https://tech.osteel.me/feeds/rss.xml')->toArray();
// Generate the list of blog posts
$posts = '';
foreach (array_slice($feed['item'], 0, 5) as $post) {
$date = date('d/m/Y', strtotime($post['pubDate']));
$posts .= sprintf("\n* **[%s]** [%s](%s \"%s\")", $date, $post['title'], $post['link'], $post['title']);
}
// Generate the new content
$content = preg_replace(
'#<!-- posts -->.*<!-- /posts -->#s',
sprintf('<!-- posts -->%s<!-- /posts -->', $posts),
file_get_contents('README.md')
);
// Overwrite the file
file_put_contents('README.md', $content);
Nothing too complicated here – Composer's autoload is required at the top, allowing me to load the RSS parser to generate a list of blog posts as a string, in Markdown format.
The existing content of the README
file is then loaded into the $content
variable, and the Markdown string is inserted between its <!-- posts -->
and <!-- /posts -->
tags with preg_replace
.
Finally, the file's entire content is replaced with the new one, using the file_put_contents
function.
The workflow
GitHub Actions allow developers to write workflows to automate various tasks like running test suites or deploying web services.
They must be defined using YAML format in a .github/workflows
folder at the root of the project, and contain a list of steps that they are to execute.
Here's mine, which I named posts.yml
:
name: Update blog posts
on:
push:
workflow_dispatch:
schedule:
- cron: '0 0 * * *'
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Clone repository
uses: actions/checkout@v2
- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
- name: Install Composer dependencies
run: composer install
- name: Insert blog posts
run: php posts.php
- name: Push changes
uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: Updated latest blog posts
Again, nothing too complicated. We first give the action a name, and then define a list of events that should trigger it – pushing some code to the repository, a manual trigger from the interface (workflow_dispatch
), or periodically like a cron job (here, every day at midnight).
We then indicate that the action should run on an Ubuntu image, where it will:
- clone the repository;
- instal PHP 8.1;
- instal the Composer dependencies;
- run the PHP script;
- commit and push the changes, if any.
That's it! My GitHub profile is now automatically updated every time I publish a new article.
Conclusion
This was a quick experiment aiming at exploring GitHub Actions, which I expect to use more and more in the future. It was also fun to use PHP as a simple scripting language again, in a procedural way.
I've voluntarily left out a few things in order to keep this article short and simple – please refer to the repository for implementation details.
Top comments (0)