Hi… how ya been, its been a month already, gosh times flies by really fast. Status update: I’ve been doing good, When I am in home I complete the work that I plan… far better than when I am in Chennai. The corona virus pandemic is still around the world at large, US right now is the largest affected country with over 70k dead people as of writing this. The lockdown in India has been extended another 2 weeks.
Note: I have edited this post, because of the changes I made, after publishing this post.
This post is going to be about github actions.
Why
Automate a process after commit, schedule a process to be done timely…etc the possibililties are endless. A little background… lastweek github announced unlimited private colaborations and made a ton of premium features completely free.
I am going to use this feature entirely for a different purpose, It further backs-up my saying..literally anything can be done.
Goal
I have this github repository which is XKCD viewer, which utilises api ‘https://xkcd.com/info.0.json'. The api does not provide cors.
I want to clone the api, (the clone must be updated daily).
should provide cors support.
should not contain any external dependencies like server to set it up.
Solution
github offers unlimited time constraint for github actions(public repository)
using github actions I could setup a bot that runs timely.
I can mainatain a local copy of the api, compare it to the offical every day,
if there is difference, then download the new contents and update the local state.
commit the changes directly to the repository.
Approach
Im going with python in conjunction with workflow file, since I want to brush up my python skills.
The python logic will maintain a local state, add new contents, update itself i.e. the state.
I am going to use json to maintain the state.
The api data will be stored under a folder with every entry having a unique folder.
Use github actions to commit the changes to the directory.
Use github secrets to maintain a token, (token used to commit diretly to repository)
Result.
After coding away the mentioned logics above. I am left with this workflow file.
name: fetch new content from api
on:
schedule:
- cron: '0 */8 * * *'
jobs:
fetch-content:
if: github.repository == 'aghontpi/xkcd-declutter'
name: execute python logic
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: install requests pip3
run: pip3 install requests
- name: run python logic
run: python3 ./.github/workflows/update_xkcd_official.py
- name: status of the new folder
run: git status xkcd-offline/ --porcelain
- name: add new files
run: |
git config --local user.name "xkcd-content-fetcher-bot"
git add xkcd-offline/
- name: commit new content
run: (awk '{print "added content " substr($3, match($3,"\""), match($3,"}")-1) "."}' xkcd-offline/state.json) | git commit -F -
- name: push the new content
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.TOKEN }}
See it in action, downloads new content automatically and put it under the folder xkcd-offline.
Updates/Post Edit
After I published this post, Github made changes to how an environment variable is accessed, changes contains the following.
- updates to accessing environment variable.
- decided to log while every run, that is persistent in the repository.
- run every 12 hours instead of 8 hours.
- added github actions bot as the author in commit message
- update instructions to how to use this API (supporting cors)
updates to yaml
name: Sync with Api
on:
schedule:
- cron: '0 */12 * * *'
jobs:
fetch-content:
if: github.repository == 'aghontpi/mirror-xkcd-api'
name: execute python logic
runs-on: ubuntu-latest
env:
new_content: true
steps:
- uses: actions/checkout@v1
- name: install requests pip3
run: pip3 install requests
- name: run python logic
run: python3 ./sync.py
- name: status of the new folder
run: git status api/ --porcelain
- name: add new files
run: |
git config --local user.name "sync bot"
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add *
- name: commit new content
id: newfiles
run: (awk '{print "added content " substr($3, match($3,"\""), match($3,"}")-1) "."}' syncState.json) | git commit -F -
continue-on-error: true
- name: not proceed if there is no new files
if: steps.newfiles.outcome == 'failure' && env.new_content == 'true'
run: |
echo "no new content was fetched"
echo "new_content=false" >> $GITHUB_ENV
- name: push the new content
if: env.new_content == 'true'
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.TOKEN }}
branch: main
how to use this as an api(supporting cors)
End
See you soon, untill then hope you do well. - Gopinath aka aghontpi aka bluepie