How to Update a Custom GitHub Profile with GitHub Actions

Markgriffith
WW Tech Blog
Published in
5 min readNov 20, 2020

You’ve probably heard of GitHub.

Marc Adreesen, inventor of Mosaic, founder of Netscape, angel investor, and Internet legend, once quipped that “software is eating the world.” He’s still right. In the ever-growing world of software, change has come rapidly, and the innovation has been breathtaking. Few companies have helped with this revolution as much as GitHub.

At WW (formerly Weight Watchers®) Engineering, we are constantly updating our platform and tools so that our organization can thrive and our engineers can not only innovate but also share their innovations. For example, we use the new GitHub Actions to streamline our deploys and accelerate releases so that WW engineers can deploy with “one click.”

GitHub recently made another fresh change: a secret developer profile that you can customize!

Instead of giving visitors a list of your repos and commits (yawn), you can show them something like this:

Check mine out! https://github.com/ww-tech/github-profile

Your GitHub profile is no longer just a place to showcase your code but also to tell your digital story. Wouldn’t you like to tell your own story?

From a time capsule re-creation of your first blog… to a regularly updated log of exploits, your profile can be personalized the way you want it! I will help you get your profile page set up and pass along some tips and tricks on how to make it your own.

First, you need to know this one little trick: Head over to your GitHub account and create a repo named after your username:

Mine is mgriffith-ww:

GitHub will prompt you to initialize this secret and special repo with a README.md file. This README.md file will contain all the components composing your profile page. From there, you can easily style it. (GitHub even provides a basic template to work with.)

Natively, GitHub recognizes HTML tags, like <h2> or <img>, so you can use them to augment a profile with photos and to structure. With just these simple tools, you can create an exciting profile to show off your skills. That’s cool. But sprinkle in a few GitHub Actions and you can create an even more dynamic profile with real-time updates and more:

name: README build
on:
push:
branches:
- master
schedule:
- cron: ‘0 1–23 * * *
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout current repository to Master branch
uses: actions/checkout@v1
- name: Setup NodeJs 13.x
uses: actions/setup-node@v1
with:
node-version: ‘13.x’
- name: Cache dependencies and build outputs to improve workflow execution time.
uses: actions/cache@v1
with:
path: node_modules
key: ${{ runner.os }}-js-${{ hashFiles(‘package-lock.json’) }}
- name: Install dependencies
run: npm install
- name: Generate README file
run: node index.js
- name: Commit and Push new README.md to the repository
uses: mikeal/publish-to-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

With the above GitHub Actions, you can automate updates to your profile on a schedule — a cron job that works to promote your work and interests. The example I show below is a simple script that changes the date and time of your profile on just such a schedule:

// index.jsconst Mustache = require(‘mustache’);
const fs = require(‘fs’);
const MUSTACHE_MAIN_DIR = ‘./main.mustache’;
/**
* DATA is the object that contains all
* the data to be provided to Mustache
* Notice the “name” and “date” property.
*/
let DATA = {
name: ‘Mark Griffith’,
date: new Date().toLocaleDateString(‘en-US’, {
weekday: ‘long’,
month: ‘long’,
day: ‘numeric’,
hour: ‘numeric’,
minute: ‘numeric’,
timeZoneName: ‘short’,
timeZone: ‘America/New_York’}),
};
/**
* A — We open ‘main.mustache’
* B — We ask Mustache to render our file with the data
* C — We create a README.md file with the generated output
*/
function generateReadMe() {
fs.readFile(MUSTACHE_MAIN_DIR, (err, data) => {
if (err) throw err;
const output = Mustache.render(data.toString(), DATA);
fs.writeFileSync(‘README.md’, output);
});
}
generateReadMe();

Notice that this script uses the templating language Mustache, a great way to create a profile page that displays dynamic information.

And ship! A simple self-updating profile and a scaffold to use for building your own digital profile.

But you can do even more.

Let’s say you want to introduce a bit of randomness to your profile and display some nice photos to comfort you in the current climate. We can do that with an API from the people at Unsplash, using a quick fetch and a slight update to our script:

// index.js
// module to allow node to fetch from the api
const fetch = require(‘cross-fetch’);
const Mustache = require(‘mustache’);
const fs = require(‘fs’);
const MUSTACHE_MAIN_DIR = ‘./main.mustache’;
//Getting an image and returning the urlasync function imageFetch() {
let image = await fetch(“https://source.unsplash.com/random/200x400")
return image.url
}
/**
* DATA is the object that contains all
* the data to be provided to Mustache
* Notice the “name” and “date” property.
* Data is now returned in a function with the image added to the object
*/
async function buildData(){
let image = await imageFetch()
return DATA = {
name: ‘Mark Griffith’,
date: new Date().toLocaleDateString(‘en-US’, {
weekday: ‘long’,
month: ‘long’,
day: ‘numeric’,
hour: ‘numeric’,
minute: ‘numeric’,
timeZoneName: ‘short’,
timeZone: ‘America/New_York’}),
picture: image
};
}
/**
* A — We open ‘main.mustache’
* B — We ask Mustache to render our file with the data
* C — We create a README.md file with the generated output
*/
async function generateReadMe() {
const DATA = await buildData()
fs.readFile(MUSTACHE_MAIN_DIR, (err, data) => {
if (err) throw err;
const output = Mustache.render(data.toString(), DATA);
fs.writeFileSync(‘README.md’, output);
});
}
await generateReadMe();

And in the Mustache template:

<h2> Hi, I’m {{name}} and it is currently {{date}}.<img src=”https://toggl.com/blog/wp-content/uploads/2018/08/programming-comic-blog-header.png" width=”50"></h2><img align=’right’ src=”https://media.giphy.com/media/LcfBYS8BKhCvK/giphy.gif" width=”230"><p><em>Software Engineer at <a href=”https://www.weightwatchers.com/us/about-WW">WW International</a><img src=”https://media.giphy.com/media/JrXc72Pz2Ib1dBK13T/giphy.gif" width=”30"</em></p>### Image of the hour<img src=”{{{picture}}}”>### More on me below… <img src=”https://media.giphy.com/media/VgCDAzcKvsR6OM0uWg/giphy.gif" width=”50">const Mark = {
code: [Javascript, Typescript, HTML, CSS, Python, C++],
tools: [React, Redux, Node, Storybook, Styled-Components, Jest, Docker],
architecture: [“microservices”, “event-driven”, “design system pattern”],
techCommunities: {
engineer:”WW International”,
volunteer:”CodeNation”,
mentor:“MarcyLab”
},
challenge: “Currently prototyping a small level demo in Unreal end to end!”
}
<img src=”https://media.giphy.com/media/LnQjpWaON8nhr21vNW/giphy.gif" width=”60"> <em><b>Let me know a skill you’ve learned this week</b>

Now whenever a new image arrives, a GitHub Action triggers a Mustache template render that outputs a brand-spanking-new profile!

Maybe try adding your recent Instagram photos or your personal Spotify playlist…

— Mark Griffith, software engineer at WW (formerly Weight Watchers®)

Special thanks to Thomas Guibert for inspiring this article.

Interested in joining the WW team? Check out the Careers page to view technology job listings, as well as open positions on other teams.

--

--