Il m'a semblé que ce serait amusant d'écraser un article intitulé "Life of GitHub Action". Lors de la formation d'introduction de Google, vous êtes guidé à travers la «durée de vie de la demande» et j'ai eu l'un de mes éléments préférés. Par conséquent, j'utilise une approche similaire pour GitHub Action.
Pour ceux qui sont dans le réservoir, Actions est une fonctionnalité GitHub lancée à Universe l'année dernière. Vous voulez des bêta-testeurs? Allez ici .
L'idée générale est un GitHub avec un support de script, mais je ne souffrirai pas de déchets et de débordements dans les explications. Mieux vaut vous guider à travers les événements qui se produisent lorsque l'action commence.
Le problème
Voici un workflow typique :
- Je crée une demande d'extraction vers le référentiel.
- La demande de tirage est absorbée.
- La branche est conservée jusqu'à la fin des temps, me dévorant cette partie du cerveau qui aime la propreté et l'ordre.

Les branches restantes sont ma douleur, concentre-toi dessus. Bien que le problème soit général, créons une action pour supprimer les branches après avoir absorbé la demande d'extraction.
Mnogabukaf? Tout le code de l'action est ici .
Fichier de workflow
Si vous le souhaitez - créez des actions via l'interface utilisateur, mais si vous le souhaitez - écrivez un fichier de workflow avec des plumes. Dans cet article, j'utilise simplement un fichier.
Voilà à quoi cela ressemble, et je vais expliquer ce que tout cela signifie dans les commentaires sur le dossier. Il se trouve dans .github/main.workflow
dans votre référentiel.
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"] }
Événement
Donc, puisque l'article s'intitule "La vie de l'action", nous commençons par ce qui se passe pour l'obscurantisme. Toutes les actions sont déclenchées via l'événement GitHub. La liste des événements pris en charge est ici .
Ci-dessus, nous avons sélectionné l'événement pull_request
. Il démarre lorsqu'une demande d'extraction est affectée, non affectée, marquée, non vérifiée, ouverte, modifiée, fermée, rouverte, synchronisée, demandée pour demander une demande d'extraction ou supprimer une demande d'extraction.
D'accord, nous avons commencé cet événement, et ...
Il y a un problème avec la demande de tirage ...
Et voici GitHub: «Merde crêpe, quelque chose ne va pas avec la demande de pull! Je suis hors de tous les outils pour les problèmes! "
En regardant le fichier de workflow (voir ci-dessus), GitHub dit: "Je vais maintenant démarrer le workflow pour absorber la demande de pull, et je supprimerai la branche."
À quoi cela mène-t-il? Oh, "nettoyer la branche." Permettez-moi de rationaliser les étapes nécessaires pour nettoyer la branche (dans ce cas, il n'y en a pas) et de les exécuter dans l'ordre / en parallèle pour arriver à la "branche propre".
Action
Ici GitHub déclare: «Yo les gens, je dois commencer le« nettoyage de branche »ici. Laissez-moi le découvrir. "
Cela nous ramène à la section uses
de notre fichier. jessfraz/branch-cleanup-action@master
sur le référentiel: jessfraz/branch-cleanup-action@master
.
Ce référentiel contient le Dockerfile. Il définit l'environnement dans lequel notre action sera effectuée.
Dockerfile
Jetez-y un œil et je vais essayer de tout expliquer dans les commentaires.
## 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"]
Le script
Vous trouverez ci-dessous le contenu du script d'essai que j'exécute.
#!/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 "$@"
Donc, pour l'instant, GitHub a exécuté notre script dans notre runtime.
GitHub signalera l'état de l'action à l'interface utilisateur, et vous pouvez le voir dans l'onglet "Actions".
Espérons que cela apporte une certaine clarté sur la façon dont les processus sont implémentés dans les actions GitHub. J'ai hâte de voir ce qui se passe avec vous.