Ben Greenberg | Developer Advocate
Use GitHub Actions to Make Your GitHub Profile Dynamic
Ben Greenberg
April 9, 2023
The place do folks first uncover you on-line? Maybe your social media presence is the very first thing folks discover after they seek for you, or maybe it’s the portfolio website you created for your self. Nevertheless, when you use GitHub to share your code and take part in open supply initiatives, then your GitHub profile could be the first place folks go to in an effort to be taught extra about you.
What would you like your GitHub profile to say about you? How do you need to specific what’s essential to you and who you might be in a concise and straightforward to learn method for guests? Whether or not they’re a potential employer or a potential companion in an open supply challenge, it’s crucial you have got a profile that stands out.
Utilizing GitHub Actions, you’ll be able to flip a static markdown doc right into a dynamic expertise that stays updated on the newest details about you. How do you do this?
I’ll present you an instance of how you are able to do this shortly and with out an excessive amount of effort. On this instance, you’ll learn to scrape an internet site and use that knowledge to dynamically replace your GitHub profile. We’ll present this instance in Ruby, however you are able to do this with JavaScript, TypeScript, Python, or different languages.
How Your GitHub Profile Works
Your GitHub profile is discovered by going to github.com/[your-username]
in an online browser, here’s mine for instance. The place does the content material for that view come from?
It lives in a particular repository in your account with the title of your account username. In the event you shouldn’t have this repository but, you’ll not see any particular content material while you go to github.com/[your-username]
, so step one is to make sure you have that repository created, and if you don’t, go forward and create it.
Exploring the recordsdata within the profile repository
The one required file within the repository is a README.md
file that’s the supply of your profile web page.
./
├── README.md
Go forward and add some content material in that file, reserve it, and refresh your username homepage, and you will note that content material mirrored there.
Including the fitting folders for dynamic content material
Earlier than we create the code to make our profile dynamic, let’s add the folder construction.
Contained in the top-level add a brand new folder referred to as .github
and inside .github
add two new sub-folders: scripts/
and workflows/
.
Your file construction ought to now appear to be this:
./
├── .github/
│ ├── scripts/
│ └── workflows/
└── README.md
Making a Dynamic Profile
We have to do three issues for this instance:
- Outline a spot within the
README
the place the dynamic content material can be - Add a script inside
scripts/
that can do the scraping work - Add a workflow for GitHub Actions inside
workflows/
that can run the script on a schedule
Let’s do every of these steps now.
Updating the README
We have to add a bit to the README that may be grabbed utilizing Regex by the script to switch. It may be no matter you want it to be in your particular use case. For this instance, we’ll add a bit for latest weblog posts within the README.
Open up the README.md
file in a code editor and add the next:
### Current weblog posts
Now we have now an space for the script to search out.
Creating the script
The instance script we’re constructing is written in Ruby and makes use of the GitHub gem octokit
to work together along with your repository, the nokogiri
gem to scrape the web site, and the httparty
gem to make the HTTP request.
On this instance beneath, the component to be scraped has already been recognized. In your individual use case, you’ll want to find the trail to the component on the positioning you want to scrape, and it’ll undoubtedly be completely different than what’s proven beneath as outlined within the posts
variable and for every title
and hyperlink
of every put up
.
Right here is the instance code, which works within the scripts/
folder:
require 'httparty'
require 'nokogiri'
require 'octokit'
# Scrape weblog posts from the web site
url = "https://www.bengreenberg.dev/weblog/"
response = HTTParty.get(url)
parsed_page = Nokogiri::HTML(response.physique)
posts = parsed_page.css('.flex.flex-col.rounded-lg.shadow-lg.overflow-hidden')
# Generate the up to date weblog posts checklist (prime 5)
posts_list = ["n### Recent Blog Postsnn"]
posts.first(5).every do |put up|
title = put up.css('p.text-xl.font-semibold.text-gray-900').textual content.strip
hyperlink = "https://www.bengreenberg.dev#{put up.at_css('a')[:href]}"
posts_list << "* [#{title}](#{hyperlink})"
finish
# Replace the README.md file
consumer = Octokit::Shopper.new(access_token: ENV['GITHUB_TOKEN'])
repo = ENV['GITHUB_REPOSITORY']
readme = consumer.readme(repo)
readme_content = Base64.decode64(readme[:content]).force_encoding('UTF-8')
# Exchange the present weblog posts part
posts_regex = /### Current Weblog Postsnn[sS]*?(?=</td>)/m
updated_content = readme_content.sub(posts_regex, "#{posts_list.be part of("n")}n")
consumer.update_contents(repo, 'README.md', 'Replace latest weblog posts', readme[:sha], updated_content)
As you’ll be able to see, first an HTTP request is made to the web site and the part with the weblog posts is gathered and the info is assigned to a posts
variable. Then, the script iterates by way of the weblog posts contained in the posts
variable and gathers the primary 5 of them. It’s possible you’ll need to change that quantity in your personal wants. Every loop by way of the weblog posts, a put up is added to an array of posts_list
with the title and the URL to the weblog put up.
Lastly, the README file is up to date by first discovering it utilizing the octokit
gem, after which finding the spot within the README to replace with some regex: posts_regex = /### Current Weblog Postsnn[sS]*?(?=</td>)/m
.
This script will do the job, however nothing is definitely invoking this script. How does it get run? That is the place GitHub Actions involves the rescue!
Creating the Motion workflow
Now that we have now the script in place, we want a solution to routinely run it on a schedule. GitHub Actions gives a strong solution to automate all kinds of duties, together with operating scripts. On this case, we’ll create a GitHub Actions workflow that runs the script as soon as per week at midnight on Sunday.
The workflow file ought to be positioned within the .github/workflows/ listing and might be named one thing like update_blog_posts.yml. Right here’s the content material of the workflow file:
title: Replace Current Weblog Posts
on:
schedule:
- cron: '0 0 * * 0' # Run as soon as per week at 00:00 (midnight) on Sunday
workflow_dispatch:
jobs:
update_posts:
runs-on: ubuntu-latest
steps:
- title: Try repository
makes use of: actions/checkout@v2
- title: Arrange Ruby
makes use of: ruby/setup-ruby@v1
with:
ruby-version: 3.1
- title: Set up dependencies
run: gem set up httparty nokogiri octokit
- title: Scrape posts and replace README
run: ruby ./.github/scripts/update_posts.rb
env:
GITHUB_TOKEN: $
GITHUB_REPOSITORY: $
This workflow is triggered on a schedule outlined by the cron
syntax, which specifies that it ought to run at 00:00 (midnight) each Sunday. Moreover, the workflow might be manually triggered utilizing the workflow_dispatch
occasion.
The update_posts
job consists of a number of steps:
- Testing the repository utilizing the
actions/checkout@v2
motion. - Organising Ruby utilizing the
ruby/setup-ruby@v1
motion, with the required Ruby model of three.1. - Putting in the required Ruby gems (
httparty
,nokogiri
, andoctokit
) utilizing thegem set up
command. - Operating the script
update_posts.rb
situated within the.github/scripts/
listing. TheGITHUB_TOKEN
andGITHUB_REPOSITORY
setting variables are supplied to the script, permitting it to work together with the repository.
With this workflow in place, your script will routinely run each week to scrape the weblog posts and replace the README file. GitHub Actions takes care of all of the scheduling and execution, making the method seamless and environment friendly.
Placing all of it Collectively
These days, your on-line presence is commonly the primary level of contact for folks seeking to join with you—whether or not they’re potential employers, collaborators, or contributors to open supply initiatives. Your GitHub profile, specifically, is a invaluable platform for showcasing your expertise, initiatives, and pursuits. So, how can you make sure that your GitHub profile stays updated, related, and actually reflective of who you might be?
By harnessing the ability of GitHub Actions, we’ve demonstrated how one can remodel your GitHub profile from a static Markdown doc right into a dynamic, ever-changing instance of who you might be. By the instance supplied on this information, you’ve realized the right way to scrape knowledge from an internet site and use it to dynamically replace your GitHub profile. And whereas our instance was carried out in Ruby, the identical rules might be utilized utilizing JavaScript, TypeScript, Python, or some other language of your selection.
To recap, we walked by way of the method of making a Ruby script that scrapes weblog posts from an internet site, extracts related info, and updates the “Current Weblog Posts” part of your README.md
file. Then, we used GitHub Actions to arrange a workflow that runs the script on an everyday schedule, guaranteeing that your profile stays present along with your newest content material.
However our journey doesn’t finish right here! The strategies and approaches shared on this information can function a basis for additional exploration and creativity. Whether or not it’s pulling in knowledge from different sources, integrating with APIs, or experimenting with completely different content material codecs, the probabilities are infinite.
So go forward and make your GitHub profile a vibrant and dynamic extension of your self. Let it inform your story, spotlight your achievements, and invite collaboration with others.
⭐ Was this weblog put up useful? Take into account sponsoring my work on GitHub to assist me create extra content material like this! ❤️