DEV Community

Cover image for How I Automated My GitHub Profile (And You Can Too)
Nick Taylor
Nick Taylor Subscriber

Posted on • Originally published at nickyt.co

How I Automated My GitHub Profile (And You Can Too)

Keeping a GitHub profile updated is tedious. New blog post? Update the profile. New newsletter issue? Update the profile. Made a video? You guessed it... update the profile

I publish content across multiple platforms: my blog at nickyt.co, my newsletter at OneTipAWeek.com, and videos on my YouTube channel as well as work videos and videos where I'm a guest. I got fed up with manual updates so I decided to automate it.

My GitHub profile at github.com/nickytonline now stays current automatically, pulling in my latest content without me lifting a finger. Here's how I built it.

My GitHub profile page

The GitHub Special Repository

First, the basics. GitHub has this neat feature where if you create a public repository with the same name as your username (in my case, nickytonline/nickytonline), it becomes a special profile repository. The README.md file in this repo displays directly on your profile page.

You can follow GitHub's official guide to set this up, but the basic steps are:

  1. Create a new public repository named exactly like your username
  2. Make sure to check "Add a README file" when creating it
  3. Edit the README.md to include your profile content

Most people know this part and stop there with static content. What fewer people realize is how powerful it becomes when you combine it with GitHub Actions.

My Setup

My profile showcases three types of dynamic content:

All of this updates automatically. I write the content, publish it, and within a day, it appears on my GitHub profile. No manual README editing required.

GitHub Actions to the Rescue

The automation happens through GitHub Actions workflows. Scripts run, update the README, and git commits the changes directly to the main branch.

Here's what my actual workflows look like.

For RSS feeds, I use the blog-post-workflow by Gautam krishna R. This thing handles RSS feed parsing, README updating, and committing automatically.

For newsletter posts:

name: Latest Newsletter Posts
on:
  schedule:
    # 1pm UTC on Mondays
    - cron: '0 13 * * MON'
  workflow_dispatch:

jobs:
  update-readme-with-blog:
    name: Update this repo's README with latest blog posts
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: gautamkrishnar/blog-post-workflow@master
        with:
          feed_list: 'https://rss.beehiiv.com/feeds/NggVbrRMab.xml'
          comment_tag_name: 'NEWSLETTER-POST-LIST'
Enter fullscreen mode Exit fullscreen mode

For blog posts:

name: Latest content I make workflow
on:
  schedule:
    # Runs every day at midnight UTC
    - cron: '0 0 * * *'
  workflow_dispatch:

jobs:
  update-readme-with-blog:
    name: Update this repo's README with latest blog posts
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: gautamkrishnar/blog-post-workflow@master
        with:
          feed_list: 'https://www.nickyt.co/feed'
Enter fullscreen mode Exit fullscreen mode

For YouTube videos:

name: Update readme videos
on:
  schedule:
    # Runs every Monday at 1pm UTC
    - cron: '0 13 * * 1'
  workflow_dispatch:

jobs:
  update_profile_data:
    name: Update readme videos
    runs-on: ubuntu-latest
    environment: all
    steps:
      - uses: actions/checkout@v2
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '22'
      - name: Update README
        env:
          YOUTUBE_API_KEY: ${{ vars.YOUTUBE_API_KEY }}
        run: |
          cd scripts
          npm install
          node --experimental-transform-types update-readme.ts
      - name: Commit changes
        id: commit
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          git config user.name "GitHub Actions Bot"
          git config user.email "<>"
          git pull origin main
          git add .
          if [[ -n "$(git status --porcelain)" ]]; then
            git commit -m "Update README"
            git push origin main
          fi
Enter fullscreen mode Exit fullscreen mode

Each workflow runs on a different schedule. Newsletter runs weekly on Mondays at 1pm UTC, blog posts check daily at midnight UTC, YouTube videos update weekly on Mondays.

The first two workflows use the blog-post-workflow action with different RSS feeds. The YouTube workflow uses a custom TypeScript script since I need the YouTube API for more control over formatting.

Leveraging the GitHub Actions Ecosystem

There's a huge ecosystem of GitHub Actions available. The blog-post-workflow action is just one example of how you can leverage existing solutions instead of writing everything from scratch.

You can find actions for almost anything: RSS feed processing, social media integration, calendar and scheduling, data visualization, file processing, and more.

Before you write a custom script, check the GitHub Actions Marketplace to see if someone has already solved your problem.

You can always go bespoke when you need specific functionality. TLDR; Use existing actions when they fit, and write custom scripts when you need something unique.

Scripts, Scripts, Scripts

Scripts do most of the heavy lifting. Typically they"

  1. Fetch RSS feeds using libraries like feedparser or rss-parser
  2. Extract relevant data (title, URL, date)
  3. Format as markdown
  4. Replace placeholder sections in the README

The key is using HTML comments as markers in your README:

## Latest Blog Posts

<!-- BLOG-POST-LIST:START -->
<!-- BLOG-POST-LIST:END -->
Enter fullscreen mode Exit fullscreen mode

Your script finds these markers and replaces everything between them with fresh content.

README as a Template

We pair our automations with our README.md which acts as a template with specific placeholder sections. Here's how my README is structured:

# Hi! I'm Nick Taylor. 👋🏻

[Static bio content here...]

## Latest Newsletter Posts

<!-- NEWSLETTER-POST-LIST:START -->
<!-- NEWSLETTER-POST-LIST:END -->

## Latest Blog Posts and Talks

<!-- BLOG-POST-LIST:START -->
<!-- BLOG-POST-LIST:END -->

## Upcoming Live Streams

<!-- STREAM-SCHEDULE:START -->
<!-- STREAM-SCHEDULE:END -->

## Latest Videos

<!-- VIDEO-LIST:START -->
<!-- VIDEO-LIST:END -->
Enter fullscreen mode Exit fullscreen mode

Each section between the HTML comments gets automatically replaced by the GitHub Actions. The blog-post-workflow action looks for the default <!-- BLOG-POST-LIST:START --> and <!-- BLOG-POST-LIST:END --> comments, but you can customize this with the comment_tag_name parameter like I do for my newsletter section (NEWSLETTER-POST-LIST).

The static content (your bio, contact info, etc.) stays untouched, while the dynamic sections get updated automatically.

As a content creator, I publish a newsletter issue, video or blog post and boom! My GitHub profile is updated. I'm not tied to manually maintaining content multiple places. I focus on creating good content, and the automation handles distribution.

Getting Started

If you want to build something similar:

  1. Create your special profile repository - create a public repository named exactly like your username (like yourusername/yourusername)
  2. Add placeholder sections to your README where dynamic content will go
  3. Start with one content type (blog posts are usually easiest)
  4. Build a simple script to fetch and format data
  5. Set up a GitHub Action to run it on a schedule

You don't need to automate everything at once. Start with one type of content and expand from there.

For RSS feeds (blogs, newsletters), you can use the blog-post-workflow action instead of writing your own scripts. It's a time-saver that handles the heavy lifting.

Or, if you want to skip the setup work entirely, feel free to clone my repository and steal my whole setup. Just update the RSS feeds and content sources to point to your own stuff. That's exactly what I'd do if I found a setup I liked.

Wrapping Up

The automation is nice, but the real benefit is consistency. Your profile stays current automatically instead of being a snapshot from whenever you last remembered to update it.

It's been a couple years now and my GitHub profile is always up to date. I never think about it.

If you're publishing content regularly, this kind of automation is worth setting up. Check out my special repository if you want to steal the whole setup.

If you want to stay in touch, all my socials are on nickyt.online.

Until the next one!

Photo by Homa Appliances on Unsplash

Top comments (0)