Preface

If you didn't know before you will know by the end, GitHub lets you customise your. public profile page for other to see, this is done using Markdown and a special reserved repository username/username.git or in my case: atownsend247/atownsend247.git.  The layout of this repository is rather simple, you just need to write out a README.md file, this is then displayed on your profile.

# Welcome All

I am an enthusiastic Infrastructure Engineer with a passion for complex web based systems and mainly AWS focused cloud architecture. I have experience from building websites using best practices to ensure optimum scalability, hybrid cloud systems and data heavy administration systems.

## Interests

I have a keen interest in nature and nature photography, this is mainly done through looking after a succulent and orchid collection and getting out and exploring the countryside.
Since getting into arduino programming a few years back this has evolved into creating and constructing a home automation system; using proprietary and open source solutions, along with off-the-shelf components mainly based around the ESP8266 chipset. This has allowed me to create lighting and power control around my home, with the addition of multiple sensors inclusive of security, climate and CCTV. My primary goal is to make my life easier and more efficient by making use of schedules and voice activated commands while learning the mechanics and principles of the code.
Example README.md for profile

This is obviously very boring and static by default, but we can make some improvements so it generates dynamic content. For example as I write some blog posts I'd like it to update my profile with the most recent articles that I've written rather than me having to copy the links in and updating the repository myself... ideal right.

Well the good news is this is perfectly achievable and here is how you could approach it.

The Approach

Before this I hadn't really played around with GitHub Workflows but this was a nice excuse to do so, GitHub allows you to run some automated actions either via repository triggers or at scheduled intervals. At the time of writing these Workflows have been renamed into Actions, these can be found as a Tab within the repository.

What these Actions end up translating to is a workflows directory within the .github directory within a specific repository.

Along with this blog there is a public RSS feed, so I knew I could easily request the blog article history to then process into Markdown.

I have used a basic node script to load in the existing Markdown file and then populate a list of articles between the two tag identifiers, this then writes the changes to disk, this can be run locally to test by doing yarn build, but in the next section you can then automate this using GitHub Actions and get it to automatically commit and push the changes.

import fs from "fs";
import fetch from "node-fetch";
import parser from "xml2json";

const FEED_URL = "https://brightbotblog.com/rss";
const TAG_OPEN = `<!-- FEED-START -->`;
const TAG_CLOSE = `<!-- FEED-END -->`;

const fetchArticles = async () => {
  const articles = await fetch(FEED_URL);
  const articlesText = await articles.text();
  const articlesJSON = parser.toJson(articlesText);
  const newC = JSON.parse(articlesJSON).rss.channel.item.slice(0, 5);

  return newC.map(({ title, link }) => `- [${title}](${link})`).join("\n");
};

async function main() {
  const readme = fs.readFileSync("./README.md", "utf8");
  const indexBefore = readme.indexOf(TAG_OPEN) + TAG_OPEN.length;
  const indexAfter = readme.indexOf(TAG_CLOSE);
  const readmeContentChunkBreakBefore = readme.substring(0, indexBefore);
  const readmeContentChunkBreakAfter = readme.substring(indexAfter);

  const posts = await fetchArticles();

  const readmeNew = `
${readmeContentChunkBreakBefore}
${posts}
${readmeContentChunkBreakAfter}
`;

  fs.writeFileSync("./README.md", readmeNew.trim());
}

try {
  main();
} catch (error) {
  console.error(error);
}
NodeJS Script to mutate Markdown

The workflow script below, defines the workflow to be executed every 4 hours given by the cron schedule and will use ubuntu-latest and node 14 to execute the steps defined. Which will simply checkout the repository and install the required node dependancies and then run yarn build to update the README.md and then finally commit it authoring as a bot.

# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions

name: Fetch blog posts from BrightBotBlog.com
on:
  schedule:
    - cron: "* */4 * * *"

jobs:
  fetch:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [14.x]

    steps:
    - name: Checkout the repository
      uses: actions/checkout@v2
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}
    - name: Install node dependencies
      run: yarn
    - name: Run node script
      run: yarn build
    - name: Git setup
      run: git config --global user.email github-bot@example.com && git config --global user.name github-bot
    - name: Git commit README.md file
      run: git diff --quiet && git diff --staged --quiet || git commit -am '[BOT] Update readme' && git push
GitHub Workflow Script

Everything you need to do this for yourself can be found in the repository below. To go from the basic markdown at the start of this article to the screenshot containing the dynamic content and even the build passing badge.

atownsend247/atownsend247
Contribute to atownsend247/atownsend247 development by creating an account on GitHub.
Workflow syntax for GitHub Actions - GitHub Docs
A workflow is a configurable automated process made up of one or more jobs. You must create a YAML file to define your workflow configuration.