Commiticons | Hashes are boring, Identify commits with Avatars via Actions
It's a fine morning, the birds are chirping outside your window. You just had a hearty breakfast and are ready to get down to business, push some improvements to the next revolutionary project that you have been working on for the past month. You let out a small burp, chuckle to yourself and fire off git log
to remind yourself what you did yesterday.
Immediately, a bunch of commits pop up on your screen lead by lifeless strings of chars. What a mood killer to the perfectly fine morning! Only if you had some better way to uniquely identify your commits.
My Workflow
"Why should users have all the fun?", the concept of identicons
has been around for long and many websites use it to generate a default avatar for users. They take a unique property attached to the user, such as email or username. Next, they run a hashing algorithm on it which generates a long incredibly unique string, called as a hash, from your smaller unique string. This hash is then passed to an algorithm which generates images as programmed by its dev.
This is where my idea comes in. Since all git commits already have unique hashes, why not generate identicons for them? I configured a small (but interesting) workflow to automatically generate unique avatars for your commits. I call these avatars Commiticons
, identicons but for commits! 😬🎉
Commiticons are avatars for your commits directly saved to your GitHub Commits as a Commit Comment.
Here's what the workflow does:
- First, I check-out my repo with actions/checkout since I want to save the Commiticons to my repo.
- name: Checkoutuses: actions/checkout@v2
Next, I want my Commiticons to be accompanied by a joke to make them even more fun. So, I use the infamous icanhazdadjoke API to grab one for me via cURL. I also must perform a few clean-up steps on them to make it simple for me to push them to the GitHub as a commit comment later.
I clean up any new lines,
\n
or\r\n
, in the joke to prevent problems when I later push it to GitHub withcURL
. The sed command replaces\n
with the<br>
tag. Next, the tr command deletes\r
which is present in case of Windows Line Endings. Read more about \r, \n and the problem of CRLF.
- name: Get a dad-jokerun: |echo "::set-env name=TEMP::$(curl -H "Accept: text/plain" https://icanhazdadjoke.com/ | sed -r ':a;N;$!ba;s/\n/<br>/g' | tr -d '\r')"
- Next, I replace all " in the text with ', via tr, in order to avoid clashes with the " with the commands in the cURL command. The $TEMP is the env variable that saves output of previous command.
- name: Escape double-quotesrun: |echo "::set-env name=DAD_JOKE::$(echo "$TEMP" | tr \" \')"
These commands are enclosed within echo and set-env to save them as Environment variables for future steps.
- Now, I use the GitHub REST API v3 to push them as a commit comment. Here are some more details about how to Create a commit comment. The request is also authenticated by using GITHUB_TOKEN.
- name: Create commit commentrun: |curl \-X POST \-H "Accept: application/vnd.github.v3+json" \-H 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/commits/$GITHUB_SHA/comments \-d "{\"body\":\"| ![Commiticon](https://avatars.dicebear.com/api/human/$GITHUB_SHA.svg?h=250) | $DAD_JOKE |\n|:-:|:-:|\"}"
The process of generating the Commiticons is handled by Dicebear Avatars, a hidden gem that I was glad I came across! They are the ❤ and soul of Commiticons.
Finally, I save the svg image to my repo which is already present here courtesy of actions/checkout in first step!
I also need to push it to my repo via git. You might be going "Wait what? Isn't this already GitHub?". It's a Gotcha that had me surprised when I was new to Actions too! In simple terms, actions are their own computers which run automatically by following a script which we provide them (our workflow files).
- name: Write Commiticonrun: |curl https://avatars.dicebear.com/api/human/$(echo $GITHUB_SHA).svg?h=250 --output .commiticons/$(echo $GITHUB_SHA).svg- name: Push Changesrun: |git config user.name Amorpheuzgit config user.email connect@amorpheuz.devgit add .commiticons/git commit -m "Generated Commiticon for: $GITHUB_SHA"git push
Yaml File or Link to Code
The repository for Commiticons can be found at https://github.com/Amorpheuz/Commiticons!
Workflow file:
name: Generate Commiticon# Controls when the action will run. Triggers the workflow on push# events but only for the main branchon:push:branches: [ main ]# A workflow run is made up of one or more jobs that can run sequentially or in paralleljobs:# This workflow contains a single job called "build"build:# The type of runner that the job will run onruns-on: ubuntu-latest# Steps represent a sequence of tasks that will be executed as part of the jobsteps:# Checkout latest commit- name: Checkoutuses: actions/checkout@v2# Fetch a dad joke from icanhazdadjoke and replace newlines with <br> tag- name: Get a dad-jokerun: |echo "::set-env name=TEMP::$(curl -H "Accept: text/plain" https://icanhazdadjoke.com/ | sed -r ':a;N;$!ba;s/\n/<br>/g' | tr -d '\r')"# Replace double quotes with single quotes to avoid clashes in further text- name: Escape double-quotesrun: |echo "::set-env name=DAD_JOKE::$(echo "$TEMP" | tr \" \')"# Add Commiticon as Commit Comment- name: Create commit commentrun: |curl \-X POST \-H "Accept: application/vnd.github.v3+json" \-H 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/commits/$GITHUB_SHA/comments \-d "{\"body\":\"| ![Commiticon](https://avatars.dicebear.com/api/human/$GITHUB_SHA.svg?h=250) | $DAD_JOKE |\n|:-:|:-:|\"}"# Write file to .commiticons folder- name: Write Commiticonrun: |curl https://avatars.dicebear.com/api/human/$(echo $GITHUB_SHA).svg?h=250 --output .commiticons/$(echo $GITHUB_SHA).svg# Push changes- name: Push Changesrun: |git config user.name Amorpheuzgit config user.email connect@amorpheuz.devgit add .commiticons/git commit -m "Generated Commiticon for: $GITHUB_SHA"git push
Additional Resources / Info
Here are all the projects that make this workflow possible, A huge shout out to all of them:
- Dicebear Avatars for the lovely avatars. 🖼
- Icanhazdadjoke for the jokes! 🤣
- actions/checkout for making repo interactions a breeze. 🏄🏽♂️
- The
sed
,cURL
andtr
commands. 👨🏽💻 - GitHub Docs for all the knowledge! 🧠
With Commiticons, I aimed to improve my grasp over not only Actions but also shell commands. Commiticons can be used for a variety of useful things too, like identifying releases with their unique avatars, jailing an avatar for mischief (if it introduced a bug) or even celebrating its birthday every year with a cake! The possibilities are endless. 🤯
I hope you found this concept fun and look forward to seeing how you take it ahead! If you are confused about something, have some ideas, or just want to chat; reach out to me via my Twitter @Amorpheuz or DEV!