DEV Community

Jimmy Dahlqvist
Jimmy Dahlqvist

Posted on

The Chuck Norris GitHub Action

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

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.

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
Enter fullscreen mode Exit fullscreen mode

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.

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"]
Enter fullscreen mode Exit fullscreen mode

Action:

# 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 }}
Enter fullscreen mode Exit fullscreen mode

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.

#!/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"
Enter fullscreen mode Exit fullscreen mode

This is the python file where all the magic happens.

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")
Enter fullscreen mode Exit fullscreen mode

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!

Top comments (1)

Collapse
 
andre profile image
André König

hahaha ... great one! Thanks for building it.

Keeps the team spirit up. Especially when a deadline is near 😀