GitHub Action Life

http://www.feedspot.com/?dadi=1#feed/fof_fo_1021441__f_4894158/article/4964611131?dd=431152057211612
  • Transfer

It seemed to me, it would be fun to gash a post called “Life of the Action GitHub Action”. On introductory training at Google, you are being carried out through the Life of Request, and I had one of my favorite elements. Therefore, I use a similar approach for GitHub Action.


For those in the tank, Actions is a GitHub function, launched at Universe last year. Want to beta testers? Go here .


The general idea is GitHub with scripting support, but I won't suffer from garbage and spread in the explanations. It is better to guide you through the events that occur when the action starts.


Problem


Here is a typical workflow :


  • I create a pull-request to the repository.
  • Pull-request absorbed.
  • The branch remains until the end of time, eating to me that part of the brain that loves cleanliness and order.


The remaining branches are my pain, focus on it. Although the problem is common, so let's create an action to remove the branches after the pull request pull has been taken.


Mnogabukaf? All the code for the action is here .


Workflow file


Want - create actions through the user interface, and if you want - write the workflow file with handles. In this article, I just use the file.


This is how it looks, and I will explain what it all means in the comments to the file. It is .github/main.workflowin your repository.


workflow "on pull request merge, delete the branch" {
  ## On pull_request defines that whenever a pull request event is fired this 
  ## workflow will be run.
  on = "pull_request"
  ## What is the ending action (or set of actions) that we are running. 
  ## Since we can set what actions "need" in our definition of an action,
  ## we only care about the last actions run here.
  resolves = ["branch cleanup"]
}
## This is our action, you can have more than one but we just have this one for 
## our example.
## I named it branch cleanup, and since it is our last action run it matches 
## the name in the resolves section above.
action "branch cleanup" {
  ## Uses defines what we are running, you can point to a repository like below 
  ## OR you can define a docker image.
  uses = "jessfraz/branch-cleanup-action@master"
  ## We need a github token so that when we call the github api from our
  ## scripts in the above repository we can authenticate and have permission 
  ## to delete a branch.
  secrets = ["GITHUB_TOKEN"]
}

Event


So, since the article is called “The Life of Action”, we begin with what is going on for obscurantism. All actions are triggered via a GitHub event. The list of supported events is here .


Above, we chose an event pull_request. It is triggered by assigning a pull request, canceling an assignment, marking, unchecking, opening, editing, closing, reopening, synchronizing, requesting a pull request or deleting a pull request.


Okay, we launched this event, and ...


With the pull request “something” is wrong ...

And here GitHub is like this: “Blinsky pancake, there is something wrong with the pull-request! Fuck me from all the guns for troubles! ”


Looking at the workflow file (see above), GitHub says: “I’ll now start the workflow to absorb a pull request, and the branch will be deleted.”


What does this lead to? Oh, "branch cleaning." Let me streamline the actions needed to clear the branch (in this case there aren't any) and run them in order / parallel, in order to arrive at a “branch clearing”.


Act


Here GitHub declares: “Yo, people, I need to run the cleaning of the branch here. Let me figure it out. ”


This brings us back to usesour file section . We point to the repository: jessfraz/branch-cleanup-action@master.


In this repository is the Dockerfile. It defines the environment in which our action will be performed.


Dockerfile


Take a look at it, and I will try to explain everything in the comments.


## FROM defines what Docker image we are starting at. A docker image is a bunch 
## of files combined in a tarball.
## This image is all the files we need for an Alpine OS environment.
FROM alpine:latest
## This label defines our action name, we could have named it butts but
## I decided to be an adult.
LABEL "com.github.actions.name"="Branch Cleanup"
## This label defines the description for our action.
LABEL "com.github.actions.description"="Delete the branch after a pull request has been merged"
## We can pick from a variety of icons for our action.
## The list of icons is here: https://developer.github.com/actions/creating-github-actions/creating-a-docker-container/#supported-feather-icons
LABEL "com.github.actions.icon"="activity"
## This is the color for the action icon that shows up in the UI when it's run.
LABEL "com.github.actions.color"="red"
## These are the packages we are installing. Since I just wrote a shitty bash 
## script for our Action we don't really need all that much. We need bash, 
## CA certificates and curl so we can send a request to the GitHub API
## and jq so I can easily muck with JSON from bash.
RUN apk add --no-cache \
    bash \
    ca-certificates \
    curl \
    jq
## Now I am going to copy my shitty bash script into the image.
COPY cleanup-pr-branch /usr/bin/cleanup-pr-branch
## The cmd for the container defines what arguments should be executed when 
## it is run.
## We are just going to call back to my shitty script.
CMD ["cleanup-pr-branch"]

Scenario


The following is the content of the test script that I am running.


#!/bin/bash
set -e
set -o pipefail
# This is populated by our secret from the Workflow file.
if [[ -z "$GITHUB_TOKEN" ]]; then
    echo "Set the GITHUB_TOKEN env variable."
    exit 1
fi
# This one is populated by GitHub for free :)
if [[ -z "$GITHUB_REPOSITORY" ]]; then
    echo "Set the GITHUB_REPOSITORY env variable."
    exit 1
fi
URI=https://api.github.com
API_VERSION=v3
API_HEADER="Accept: application/vnd.github.${API_VERSION}+json"
AUTH_HEADER="Authorization: token ${GITHUB_TOKEN}"
main(){
    # In every runtime environment for an Action you have the GITHUB_EVENT_PATH 
    # populated. This file holds the JSON data for the event that was triggered.
    # From that we can get the status of the pull request and if it was merged.
    # In this case we only care if it was closed and it was merged.
    action=$(jq --raw-output .action "$GITHUB_EVENT_PATH")
    merged=$(jq --raw-output .pull_request.merged "$GITHUB_EVENT_PATH")
    echo "DEBUG -> action: $action merged: $merged"
    if [[ "$action" == "closed" ]] && [[ "$merged" == "true" ]]; then
        # We only care about the closed event and if it was merged.
        # If so, delete the branch.
        ref=$(jq --raw-output .pull_request.head.ref "$GITHUB_EVENT_PATH")
        owner=$(jq --raw-output .pull_request.head.repo.owner.login "$GITHUB_EVENT_PATH")
        repo=$(jq --raw-output .pull_request.head.repo.name "$GITHUB_EVENT_PATH")
        default_branch=$(
            curl -XGET -sSL \
                -H "${AUTH_HEADER}" \
                -H "${API_HEADER}" \
                "${URI}/repos/${owner}/${repo}" | jq .default_branch
        )
        if [[ "$ref" == "$default_branch" ]]; then
            # Never delete the default branch.
            echo "Will not delete default branch (${default_branch}) for ${owner}/${repo}, exiting."
            exit 0
        fi
        echo "Deleting branch ref $ref for owner ${owner}/${repo}..."
        curl -XDELETE -sSL \
            -H "${AUTH_HEADER}" \
            -H "${API_HEADER}" \
            "${URI}/repos/${owner}/${repo}/git/refs/heads/${ref}"
        echo "Branch delete success!"
    fi
}
main "$@"

Таким образом, на данный момент GitHub выполнил наш сценарий в нашей среде выполнения.
GitHub сообщит статус действия в пользовательский интерфейс, и Вы сможете увидеть его во вкладке «Actions».


Надеюсь, это внесло некоторую ясность о том, как осуществляются процессы в GitHub Actions. Жду не дождусь посмотреть, что выйдет у вас.


Also popular now: