DEV Community

Banjo Obayomi
Banjo Obayomi

Posted on

Using GitHub Actions to answer questions about Pull Requests

Comment for #34

PR FAQ

How long was PR open?

The PR was open for 0 days, 0 hours, 0 minutes, 4 seconds

Who contributed to the PR?

The following users contributed to the PR
banjtheman

What files changed in the PR?

The following files changed in the PR
templates/prfaq-template.md

How many lines of code changed in the PR?

+5 -5 lines of code changed

The Pull Request FAQs (PRFAQs) is a mechanism to automatically capture relevant data points on a finished Pull Request. The PRFAQs currently answers the following questions.

  1. How long was PR open?

  2. Who contributed to the PR?

  3. What files changed in the PR?

  4. How many lines of code changed in the PR?

By leveraging existing GitHub Actions I was able to build a workflow to answer the questions.

My Workflow

The following highlights how this workflow works.

  1. When a pull request is closed, the workflow is started.
  2. The workflow downloads the repo using the GitHub Action actions/checkout@v2
  3. The workflow uses the GitHub GraphQL API using the template query to get data on the pull request using the GitHub Action helaili/github-graphql-action@2.0.1
  4. The workflow saves the output as a JSON file
  5. The workflow uses the jannekem/run-python-script-action@v1 to parse the JSON file to set answers to the questions as environment variables
  6. The workflow uses the chuhlomin/render-template@v1.2 to set the answers into the PRFAQs template
  7. The workflow uses the peter-evans/create-or-update-comment@v1 to post the answers as a comment on the Pull Request

Submission Category: Maintainer Must-Haves

While Maintainers can find this information by scrolling through each Pull Request the PRFAQ workflow consolidates the effort into a single comment and provides vital information not found directly such as how long the PR was open for.

Yaml File and Link to Code

Here is the GitHub Repo

GitHub logo banjtheman / prfaq_action

Create a PRFAQ for merged pull requests

Here is the Workflow Yaml

name: PRFAQ

# only trigger on pull request closed events
on:
  pull_request:
    types: [closed]
env:
  PR_NUMBER: ${{ github.event.pull_request.number }}

jobs:
  get_pr_stats:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2
      - name: GitHub GraphQL Action
        uses: helaili/github-graphql-action@2.0.1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          query: queries/pr_stats.yaml
          logLevel: debug
          outputFile: pr_stats.json
          pr_num: ${{ env.PR_NUMBER }}
      - name: Set env variables
        uses: jannekem/run-python-script-action@v1
        with:
          script: |
            import json
            import datetime

            with open("pr_stats.json", "r") as pr_file:
                pr_stats = json.load(pr_file)

                # Get Time Open
                created_at = pr_stats["data"]["repository"]["pullRequest"]["createdAt"]
                merged_at = pr_stats["data"]["repository"]["pullRequest"]["closedAt"]

                created_at_timesamp = datetime.datetime.strptime(created_at, "%Y-%m-%dT%H:%M:%SZ")
                merged_at_timestamp = datetime.datetime.strptime(merged_at, "%Y-%m-%dT%H:%M:%SZ")
                timestamp_diff = merged_at_timestamp - created_at_timesamp

                days, seconds = timestamp_diff.days, timestamp_diff.seconds
                hours = days * 24 + seconds // 3600
                minutes = (seconds % 3600) // 60
                seconds = seconds % 60

                timestamp_open = f" {days} days, {hours} hours, {minutes} minutes, {seconds} seconds"
                print(timestamp_open)
                set_env("PR_OPEN", timestamp_open)

                # Get participants
                participants = pr_stats["data"]["repository"]["pullRequest"]["participants"][
                    "edges"
                ]
                participants_string = ""
                for participant in participants:
                    participants_string += participant["node"]["login"] + "  "

                print(participants_string)
                set_env("PR_USERS", participants_string)

                # Lines of code changed
                additions = pr_stats["data"]["repository"]["pullRequest"]["additions"]
                deletions = pr_stats["data"]["repository"]["pullRequest"]["deletions"]
                content_changed = f"+{additions} -{deletions} lines of code"
                print(content_changed)
                set_env("PR_LOC", content_changed)

                # Files that changed
                files = pr_stats["data"]["repository"]["pullRequest"]["files"]["edges"]
                files_string = ""
                for file_path in files:
                    files_string += file_path["node"]["path"] + "  "
                print(files_string)
                set_env("PR_FILES", files_string)
      - name: Render template
        id: template
        uses: chuhlomin/render-template@v1.2
        with:
          template: templates/prfaq-template.md
          vars: |
            pr_open: ${{ env.PR_OPEN }}
            pr_users: ${{ env.PR_USERS }}
            pr_loc: ${{ env.PR_LOC }}
            pr_files: ${{ env.PR_FILES }}
      - name: Create comment
        uses: peter-evans/create-or-update-comment@v1
        with:
          issue-number: ${{ env.PR_NUMBER }}
          body: ${{ steps.template.outputs.result }}

Enter fullscreen mode Exit fullscreen mode

Additional Resources / Info

These are all the Actions I used to build the workflow

  1. actions/checkout@v2
  2. helaili/github-graphql-action@2.0.1
  3. jannekem/run-python-script-action@v1
  4. chuhlomin/render-template@v1.2
  5. peter-evans/create-or-update-comment@v1

What other questions should this workflow answer? Leave your suggestions in the comments below.

Top comments (0)