The Chuck Norris GitHub Action
Tags: actionshackathon, github, chucknorris
Published: 2020-08-23 13:23:02

[Instructions]: # (To submit to the GitHub Actions x DEV Hackathon, please fill out all sections.)


### My Workflow
This is my contribution to the DEV GitHub Actions Hackathon. I decided to do something wacky. The Action is just for some great fun. It's a custom Action that will comment each Pull Request with a Chuck Norris programming joke and Gif.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/i3913nbjfwhu77f3yvhd.png)

Even though this is just to throw some fun into the repo and pull request, you don't mess with Chuck Norris, which then bring some seriousness into it. 


### Submission Category: 

Wacky Wildcards (Truly Wacky)


### Workflow Yaml

The workflow file is pretty simple and straight forward, the magic lies in the custom Action.

```yaml
name Chuck Norris Comment
on:
  pull_request:
    branches:
      - master

jobs:
  chuck_norris_comment:
    runs-on: ubuntu-latest
    name: A job to run chuck norris
    steps:
      # Checkout the code
      - name: Checkout
        uses: actions/checkout@v2
      # Chuck Norris
      - name: Chuck Norris
        id: cn
        uses: ./.github/actions/chuck-norris
        with:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GIF_URL: https://media.giphy.com/media/BIuuwHRNKs15C/giphy.gif
```

### Custom GitHub Action

As mentioned the Workflow it self is pretty easy, at the moment the custom Action repo is not released open source (will soon happen) in the mean time I share the magic here. The Action is a Docker based Action using Python and [pyGitHub][pyGithub-link].

Dockerfile:
```Dockerfile
FROM python:3.8-slim

RUN apt-get update && apt-get install -y \
    jq

RUN pip install PyGithub

COPY main.py /main.py
COPY entrypoint.sh /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]
```

Action:
```yaml
# action.yml
name: "chuck-norris-comment"
description: "Chuck Norris will comment your Pull-Request"
author: "Jimmy Dahlqvist"
inputs:
  GITHUB_TOKEN:
    description: "Repository Github token"
    required: true
runs:
  using: "docker"
  image: "Dockerfile"
  args:
    - ${{ inputs.GITHUB_TOKEN }}
```

Entrypoint.
Here we need to fetch the raw GitHub webhook event fired when the workflow and action is triggered, this so we can fetch the PR number and such. $GITHUB_EVENT_PATH is one of the standard GitHub Actions environment variables available to all Actions.

```bash
#!/bin/sh -l

# Fetch the GitHub webhook raw event
webhook_event=$(jq --raw-output . "$GITHUB_EVENT_PATH")

cd .github/actions/chuck-norris

python main.py --webhook_event "$webhook_event"
```

This is the python file where all the magic happens.
```python
from github import Github
import os
import argparse
import json
import random

parser = argparse.ArgumentParser()
parser.add_argument(
    '--webhook_event', required=True, help='The GitHub webhook event')

args = parser.parse_args()
event = json.loads(args.webhook_event)

pr_number = ""
full_name = ""
gif_url = ""

if not "pull_request" in event:
    raise Exception("Pull request not found in event!")

pr_number = event["pull_request"]["number"]
full_name = event["repository"]["full_name"]

if "INPUT_GIF_URL" in os.environ:
    gif_url = repo_token = os.environ["INPUT_GIF_URL"]

repo_token = os.environ["INPUT_GITHUB_TOKEN"]

with open('jokes.txt') as f:
    jokes = f.readlines()

random_joke_index = random.randint(0, len(jokes)-1)
joke = jokes[random_joke_index]

github = Github(repo_token)
repo = github.get_repo(full_name)
pr = repo.get_pull(int(pr_number))

message = "{}".format(joke)

if gif_url:
    message = message + "<br><br>![Chuck Gif]({})".format(gif_url)

pr.create_review(
    body=message, event="COMMENT")
```

As you can see the jokes are fetched from a file named jokes.txt, so if you implement this your self don't forget to include that file or change how jokes are fetched.


### Wrapping up.
Not much to say! Happy hacking everyone!


[pyGithub-link]: https://github.com/PyGithub/PyGithub