Being any developer we generate a lot of code and push it to Github for backup, managing software versions, hosting projects, and other many tasks. If we talk about how many repositories are actual projects, we host and showcase in our resume/social media, it’s way too less than compared to the total number of repositories created. These include forked repositories, some practice codes uploaded or some additional content to refer to.
I have created a lot of them, and now when I have to showcase my projects, I get confused about which one should be included or what I have made! To solve this dilemma, I came up with a solution to develop a Github action to automate adding projects, hackathons attended, display some Github profile stats, and optionally, display the latest blogs written over medium and my website and to take it to next level, I dockerized the action and hosted the webpage for free! Let’s see how I made it.
What is GitHub Action?
Github action enables you to automate and customize the software development cycle of testing and deploying the application all integrated into your repository. These actions are called jobs and they can be scheduled to run according to your needs via Cron jobs, which are time-based job schedulers. If you visit the GitHub action documentation, you might get confused between two terms, actions and workflows. These are confusing things which need to be cleared before proceeding:
- The major difference between action and workflow is that one is part of others. Actions are the events that are triggered when a particular workflow is executed.
- Actions are the tasks that are executed in the code environment while workflows manage how these tasks will be performed, what will be their order, any dependencies/setup to be done before running them, inputs, arguments to pass, or defining the dependency between the different jobs.
- A workflow may have several actions running sequentially or in parallel, depending upon the configuration assigned.
Now that you have a basic understanding of Github’s action, let’s code the actual script, which will be part of this action.
Scripting Time!
For this project, I am using Python as it’s easy for me to code in it plus there are fewer actions built using Python. This project requires access to Github profile data, though Github API provides most of the data, it is still restricted to 60 requests per hour for non-authenticated users. Therefore, you need a Personal access token (Settings > Developer Settings > Personal Access Tokens) which authenticates the user to Github and allows 5000 requests per hour!
To start, install PyGithub library for all the headaches of making connections, pagination of results, and finally fetching the data. Next, we need to store the data returned by the API. I choose the dictionary format because it is easy to manage and access the attributes. This is what the initial code looks like:
from github import Github git = Github("TOKEN HERE") user_object = git.get_user() git_username = user_object.login user_data = {'username': git_username, 'git_photo_url': user_object.avatar_url, 'git_bio': user_object.bio, 'git_email': user_object.email, 'git_followers': user_object.followers, 'git_following': user_object.following, 'name': user_object.name, 'latest_updated': str(user_object.updated_at)}
Next regarding the repositories, I needed to distinguish between projects, hackathons, and other extra repositories. To do this, I have set up a condition that before setting up this action, you need to manually assign the repositories topic of “project” or “hackathon” to be considered in the portfolio. If a repository is not tagged for any of these, then it will not reflect in the output. This condition segregates the repositories into different two sections and now they are stored separately.
Webpage Building
The Python script extracts all the information, but now for the main aim of this project, a webpage was needed. Initially, I thought of using markdown files to do this, but due to Github restrictions, you cannot use CSS in markdown (to avoid phishing attacks). This was a major problem as I don’t want users to feel that bored or dejected after seeing a simple plain text portfolio. Therefore I extended the current script to use the information collected before and inject the values into an HTML template which is stored as a string and changed using f-strings. The HTML template took a lot of hit and trails to attain one simple view which needed different settings for the mobile view. All the basic information from Github was obtained, but one thing was still missing, a stats display. For the stats display, I used the open-source Vercel app made by Anurag Hazra which updates the stats dynamically. For the blog update, I used the Gautam Krishna R action which was scheduled differently, I will explain it in the upcoming paragraph. The final webpage which the action generates looks like this:
After all the mess, the action could generate an HTML file which with the help of Github pages can be deployed, and there you have your self-updating portfolio hosted for free! Now to automate this whole process of adding new entries, I came up with Github action.
Dockerizing and Creating the Action
I choose docker images for this action as when I tried out different approaches to creating an action in Python, I didn’t get any good results. Dockers helped to isolate the environment and run the code as it was supposed to run locally. The docker file for this action looks very simple:
FROM python:3 RUN pip install -Iv PyGithub==1.53 COPY ./ /gen_index ENTRYPOINT ["python", "/gen_index/generate_index.py"]
I have pulled a Python image from the docker hub, installed dependencies, and run the script.
Now it’s time to create the action. According to Github docs, you need a file called action.yml in the root directory of your public repository to make actions work. The action file comprises the following things: A unique action name, description, author name, inputs you need to take from the user, and then which file to execute. In YAML format, it is very easy to configure as it follows a hierarchical system. For the input, I took Github token, and for the file, I provided the docker file. Now your action is ready for use and you can also publish your action in the marketplace, but it’s not mandatory.
Final Workflow for Usage
Now it’s time to test this action. As I mentioned earlier, actions are just the triggered events from a workflow. The workflow defines the order of the actions, the system/environment specifications where it will run, and other activities you need to perform before or after the trigger. These files are stored in
.github/workflows folder.
The workflow designed to use this action is this:
name: Latest portfolio on: schedule: # Runs at the end of every day. - cron: '0 0 * * *' workflow_dispatch: jobs: job_1: name: update-index-with-project runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: kaustubhgupta/[email protected] with: gh_token: ${{ secrets.TOKEN }} # Create a secret for access token and modify the name as you wish - uses: test-room-7/action-update-file@v1 with: file-path: | index.html commit-msg: index file added github-token: ${{ secrets.TOKEN }}
You can customize the workflow with your requirements, but the steps mentioned in the job should not be altered. This workflow works fine and generates the index.html file which is being used by Github pages, but something is missing again. The problem is that the blog update action is not integrated yet. I have made this step optional as not everybody writes blogs. To integrate the blog action, in the same workflows folder, create a YAML file, and put the same code: (just update the feed list with your links)
name: Latest blog post workflow on: push: # Everytime index.html is pushed, this action runs and updates the blogs section! jobs: update-readme-with-blog: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: gautamkrishnar/blog-post-workflow@master with: feed_list: <Your feedlist> max_post_count: 7 readme_path: index.html template: "$newline <h2 class='h2-blog'><a class='a-lightblue' href=$url>$title</a></h2>$newline <br>" # Do not change the template as it will not render good results! gh_token: ${{ secrets.TOKEN }}
You can check out the blog post workflow action to customize other factors just make sure not to adjust the template parameter much as it may not give good results. This action runs every time you push something to the repository and as the index file will be pushed, this action will update the blogs section as soon as the index file is generated.
Conclusion
In this article, I walked you through the basic concept of Github action, workflow, differences between them, a bit of scripting the action, required files for actions and finally using them in a workflow. I also discussed the challenges I faced during this project and how you can use my action in your repositories.
This article has been published from the source link without modifications to the text. Only the headline has been changed.
Source link