How to Create a Dynamic GitHub Profile README
Since July 2020, GitHub has enabled developers to create profile-level repositories, using a README file to add a personal touch to their pages. I've been aware of this feature for some time, but only recently delved into it, and perhaps I got a little carried away.
Getting Started: The Profile Repository
To get started, navigate to GitHub and create a new repository with the exact same name as your GitHub username. For instance, if your username is mvndr
, the repository should also be named mvndr
. Once the repository is created, I clone it to my local machine and open it in my preferred code editor.
Setting Up the Script
We will utilize a third-party module called isomorphic-fetch
, which intelligently switches between unfetch
for the client and node-fetch
for the server. I imported the necessary dependencies into an index.js
file.
To begin, I declared an async
function called main
. Inside this function, I first read a template file and stored its contents in a variable named readmeTemplate
.
The next step involves making an API request. I made a request to 'The Office API' and assigned the resulting quote to a variable called officeQuote
. Then, I replaced a specific placeholder pattern within the template file with the dynamic content received from the API.
Finally, the script overwrites the actual README.md
file with the updated content from the readmeTemplate
variable.
Here is a simplified example of what the script looks like:
import fetch from 'isomorphic-fetch';
import fs from 'fs';
const main = async () => {
// 1. Read the template file
const readmeTemplate = fs.readFileSync('./README.template.md', 'utf-8');
// 2. Make the API request
const officeQuoteResponse = await fetch('https://officeapi.dev/api/quotes/random');
const { quote, character } = await officeQuoteResponse.json();
const officeQuote = `> ${quote.content}\n> \n> — ${quote.character.firstname} ${quote.character.lastname}`;
// 3. Replace the placeholder
const newReadme = readmeTemplate.replace('%', officeQuote);
// 4. Write to the actual README file
fs.writeFileSync('./README.md', newReadme);
};
main();
Enhancing the Profile's Visuals
I manually added a file to greet visitors with an attractive banner image that links to my portfolio. To create various badges, I used shields.io
, where I could customize the badge labels, colors, and destination URLs. For a bit of fun, I decided to track profile visits, so I created a visitor counter badge and placed it alongside my social media badges.
In addition to the introduction, I included sections for my latest blog posts, repositories, and Git statistics. To provide a unique and personal touch, I added a placeholder for a quote from 'The Office' in its own dedicated section. The assets
directory contains two files: one for my banner and another spare image that could be used as a profile picture.
Automating with GitHub Actions
Next, I opened a dynamic-inject-workflow.yml
file. I named the workflow and specified the triggers for when it should run. I scheduled a cron job to execute this workflow hourly. This ensures that new blog posts are fetched frequently and visitors are greeted with a fresh quote from 'The Office' on a regular basis.
With the basic workflow structure in place, I needed to define the jobs. The order of execution is important, so I created the first job specifically to fetch the quote. The dynamic-inject-workflow.yml
file was then complete.
Here is an example of the workflow configuration:
name: Dynamic Inject Workflow
on:
schedule:
- cron: '0 * * * *' # Runs every hour
workflow_dispatch:
jobs:
inject:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Run injection script
run: node ./index.js
- name: Commit and push changes
uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: "Automated: Update README with latest data"
branch: main
file_pattern: README.md
Deployment and Verification
I committed my changes and pushed them to my GitHub profile repository. GitHub automatically recognized the new workflow file, and it appeared under the 'Actions' tab of the repository. To test it, I manually triggered the workflow by clicking the 'Run workflow' button and observed its execution on the main branch.
After the workflow successfully completed both of its jobs, I returned to my profile page to see the dynamic results in action.
Join the 10xdev Community
Subscribe and get 8+ free PDFs that contain detailed roadmaps with recommended learning periods for each programming language or field, along with links to free resources such as books, YouTube tutorials, and courses with certificates.