
Keeping your GitHub profile up-to-date with your latest blog posts is a great way to showcase your work and maintain an active online presence. In this post, I’ll walk through how I automated the process of updating my GitHub profile README whenever a new blog is published on my Jekyll-powered website. This approach leverages GitHub Actions, custom scripting, and repository integration for a seamless workflow.
First, I created a dedicated GitHub profile repository. Make sure the repository name matches your github username. See here for more information on profile repositories. The README file in this repo includes a section for my latest blogs:
readme.md
### My Latest Blogs
<!--blog-start-->
<!--blog-ends-->
This section acts as a placeholder, allowing automated scripts to update the content between the comment tags.
On my Jekyll website, I added a custom HTML file that outputs the latest blog posts in Markdown format. This file uses Liquid templating to generate a list of recent posts, wrapped in the same comment tags for easy parsing:
/blog/machine/index.html
---
layout: none
permalink: /blog/machine/
---
<!--blog-start-->
{% assign posts = site.posts | sort: "date" | reverse %}
{% for post in posts limit:6 %}
- [{{ post.title }} - {{ post.date | date: "%Y-%m-%d" }}]({{ site.url }}{{ post.url }})
{% endfor %}
<!--blog-ends-->
This ensures the output is machine-parseable. The content on this page will be what is placed into our readme file in the profile repository.
To automate the update process, I created a custom GitHub Actions workflow in my Pages repository. This workflow is triggered whenever the site is published and performs the following steps:
NOTE: If you are not using custom github actions for your github pages project, you’ll need to change that in Settings -> Pages -> then change the Source from “Deploy from a branch” to “GitHub Actions” and use the jekyll template. Mine looks like this
Since the workflow needs to push changes to a separate repository (the profile repo), I generated a GitHub Personal Access Token (PAT) with repo scope. This token is stored as a secret in the Pages repository and used for authentication during the push step.
The workflow YAML includes steps for cloning the profile repo, downloading the latest blog markdown, running the update script, and committing the changes. Here’s a simplified version of the relevant steps. See the full pipeline here:
update-profile:
runs-on: ubuntu-latest
needs: deploy
steps:
- name: Checkout Pages Repo
uses: actions/checkout@v3
- name: Fetch Latest Blogs
run: |
curl -s https://autumnevans.dev/blog/machine/ -o latest_blogs.md
- name: Clone Profile Repo
env:
PROFILE_REPO_TOKEN: ${{ secrets.PROFILE_REPO_TOKEN }}
run: |
git clone https://x-access-token:${PROFILE_REPO_TOKEN}@github.com/AutumnEvans418/autumnevans418.git
cp latest_blogs.md autumnevans418/latest_blogs.md
cp update_readme.py autumnevans418/update_readme.py
- name: Update README in Profile Repo
run: |
cd autumnevans418
python3 update_readme.py
cat README.md
- name: Commit and Push Changes
env:
PROFILE_REPO_TOKEN: ${{ secrets.PROFILE_REPO_TOKEN }}
run: |
cd autumnevans418
git config user.name "README-bot"
git config user.email "readme-bot@example.com"
git add README.md
git commit -m "Update latest blogs" || true
git remote set-url origin https://x-access-token:${PROFILE_REPO_TOKEN}@github.com/AutumnEvans418/autumnevans418.git
git push
The update script (update_readme.py) is a simple Python script that replaces the blog section in the README with the latest markdown:
import re
with open('latest_blogs.md', 'r') as f:
latest = f.read()
with open('README.md', 'r') as f:
readme = f.read()
new_readme = re.sub(
r'(<!--blog-start-->)(.*?)(<!--blog-ends-->)',
r'\\1\\n' + latest.split('<!--blog-start-->')[1].split('<!--blog-ends-->')[0].strip() + r'\\n\\3',
readme,
flags=re.DOTALL
)
with open('README.md', 'w') as f:
f.write(new_readme)
Now when we update our Jekyll website, our github profile will be updated!

By combining Jekyll’s templating, GitHub Actions, and a simple Python script, I’ve created a robust and automated workflow for keeping my GitHub profile up-to-date with my latest blog posts. This approach can be adapted for other types of content and is a great way to integrate your personal site with your developer profile.
If you have questions or want to implement something similar, feel free to reach out or check out the source files in my repositories!