Github Actions, Docker, and the Beloved Cron
March 14, 2021
I've written before about my love for Github Actions and Docker.
A little over a week ago I tweeted that I was interested in writing a blog post about using Github Actions and Docker to schedule a job to do something interesting, but I didn't have a fun use case.
Fortunately, my internet friends delivered.
text me with a pic of your dog
β Camilo (@camdotbio) March 5, 2021
So I decided to write a quick script to do this, and that's how I spent my Friday evening as my wife and I watched Avengers. π
I've provided a link to the Github Repository with the full code but here's the short instructions if you're interested.
1. Register for a developer account on Twitter and get your API credentials
This is a pretty easy process and you just sign up and outline what you're doing (it's also free). Note that you'll need to store 4 variables in a .env
file like below:
1TWITTER_API_KEY=
2TWITTER_API_SECRET=
3TWITTER_ACCESS_TOKEN=
4TWITTER_ACCESS_TOKEN_SECRET=
2. Write a Python Script to Tweet a Dog Photo
This was pretty straightforward thanks to the Tweepy library in Python and this super random dog photo API (God bless the internet).
Here's what that Python code looks like:
1import os
2import json
3import requests
4import tweepy
5
6def get_random_dog(filename: str='temp') -> None:
7 r = requests.get('https://dog.ceo/api/breeds/image/random')
8 rd = json.loads(r.content)
9 r2 = requests.get(rd['message'])
10
11 with open(filename, 'wb') as image:
12 for chunk in r2:
13 image.write(chunk)
14
15def main(message: str, filename: str='temp') -> None:
16 auth = tweepy.OAuthHandler(
17 os.environ.get('TWITTER_API_KEY'),
18 os.environ.get('TWITTER_API_SECRET')
19 )
20 auth.set_access_token(
21 os.environ.get('TWITTER_ACCESS_TOKEN'),
22 os.environ.get("TWITTER_ACCESS_TOKEN_SECRET")
23 )
24 api = tweepy.API(auth)
25 get_random_dog(filename)
26
27 try:
28 api.verify_credentials()
29 print("Twitter Authentication Succeeded")
30
31 try:
32 api.update_with_media(filename, status=message)
33 print('Tweet successfully sent!')
34
35 except Exception as e:
36 print('Error sending tweet \n %s' % e)
37 except:
38 print("Twitter Authentication Failed")
39
40
41if __name__ == '__main__':
42 main("Hey, @camdotbio! π \n\nHere's your daily dog photo!")
3. Create a Docker Container to run the Python Script
This is a contentious area where some may argue docker is execessive for this but I use different computers with different operating systems so this works for me and I like it.
In short, I created a Dockerfile and a docker-compose file where I run the script. The benefit of this is that I don't have to worry about this script not working on my Linux machine or not working on my Mac, it works on both!
4. Use a Github Action to Schedule a Cron Job
This was also straightforward and I've copied the code below:
1name: Build and Deploy π
2
3on:
4 schedule:
5 - cron: '0 15 * * *'
6
7jobs:
8 build:
9 runs-on: ubuntu-latest
10
11 steps:
12 - uses: actions/checkout@v2
13
14 - name: Make envfile
15 uses: SpicyPizza/create-envfile@v1
16 with:
17 envkey_TWITTER_API_KEY: ${{ secrets.TWITTER_API_KEY }}
18 envkey_TWITTER_API_SECRET: ${{ secrets.TWITTER_API_SECRET }}
19 envkey_TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }}
20 envkey_TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
21 file_name: .env
22
23 - name: Build the docker container
24 run: docker build .
25
26 - name: Run the script π
27 run: docker-compose up
Note that you have to create Action Secrets in your Github Repository (available in the Settings tab) and add the credentials from Step 1.
Conclusion
And that's it! πΆ
Pushing the code to GitHub handles the rest, isn't that wonderful?
Anyways, thanks to my internet friends for the fun idea. I didn't end up sending it to Camilo's phone number because I would have to pay Twilio $0.0075.
Have some feedback? Feel free to let me know!