:octocat: ghdag is a tiny workflow engine for GitHub issue and pull request.

Overview

ghdag

build ghdag workflow

:octocat: ghdag is a tiny workflow engine for GitHub issue and pull request.

Key features of ghdag are:

  • Simple definition of workflows to improve the lifecycle of issues and pull requests.
  • Built-in GitHub and Slack actions.
  • Optimized for running on GitHub Actions, it is easier to configure when running on GitHub Actions.

See Examples page for practical usage.

Getting Started

Generate a workflow file

Execute ghdag init for generating a workflow YAML file for ghdag ( and a workflow YAML file for GitHub Actions ).

$ ghdag init myworkflow
2021-02-23T23:29:48+09:00 [INFO] ghdag version 0.2.3
2021-02-23T23:29:48+09:00 [INFO] Creating myworkflow.yml
Do you generate a workflow YAML file for GitHub Actions? (y/n) [y]: y
2021-02-23T23:29:48+09:00 [INFO] Creating .github/workflows/ghdag_workflow.yml
$ cat myworkflow.yml
---
# generate by ghdag init
tasks:
  -
    id: set-question-label
    if: 'is_issue && len(labels) == 0 && title endsWith "?"'
    do:
      labels: [question]
    ok:
      run: echo 'Set labels'
    ng:
      run: echo 'failed'
    name: Set 'question' label
$ cat .github/workflows/ghdag_workflow.yml
---
# generate by ghdag init
name: ghdag workflow
on:
  issues:
    types: [opened]
  issue_comment:
    types: [created]
  pull_request:
    types: [opened]

jobs:
  run-workflow:
    name: Run workflow
    runs-on: ubuntu-latest
    container: ghcr.io/k1low/ghdag:latest
    steps:
      - name: Checkout
        uses: actions/[email protected]
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Run ghdag
        run: ghdag run myworkflow.yml
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

And edit myworkflow.yml.

Run workflow on your machine

$ export GITHUB_TOKEN=xxXxXXxxXXxx
$ export GITHUB_REPOGITORY=k1LoW/myrepo
$ ghdag run myworkflow.yml
2021-02-28T00:26:41+09:00 [INFO] ghdag version 0.2.3
2021-02-28T00:26:41+09:00 [INFO] Start session
2021-02-28T00:26:41+09:00 [INFO] Fetch all open issues and pull requests from k1LoW/myrepo
2021-02-28T00:26:42+09:00 [INFO] 3 issues and pull requests are fetched
2021-02-28T00:26:42+09:00 [INFO] 1 tasks are loaded
2021-02-28T00:26:42+09:00 [INFO] [#14 << set-question-label] [DO] Replace labels: question
Set labels
2021-02-28T00:26:43+09:00 [INFO] Session finished
$

Run workflow on GitHub Actions

$ git add myworkflow.yml
$ git add .github/workflows/ghdag_workflow.yml
$ git commit -m'Initial commit for ghdag workflow'
$ git push origin

And, see https://github.com/[owner]/[repo]/actions

Issues and pull requests targeted by ghdag

📝 The issues and pull requests that ghdag fetches varies depending on the environment in which it is run.

Environment or Event that trigger workflows for GitHub Actions Issues and pull requests fetched by ghdag
On your machine All opened and not draft issues and pull requests
issues A single opened issue that triggered the event
issue_comment A single opened and not draft issue or pull request that triggered the event
pull_request pull_request_* A single opened and not draft pull request that triggered the event
Other events All opened and not draft issues and pull requests

Workflow syntax

ghdag requires a YAML file to define your workflow configuration.

env:

A map of environment environment variables in global scope (available to all tasks in the workflow).

Example

env:
  SERVER: production
  GITHUB_TOKEN: ${GHDAG_GITHUB_TOKEN}

tasks:

A workflow run is made up of one or more tasks. Tasks run in sequentially.

Example

tasks:
  -
    id: first
    if: 'is_issue && len(labels) == 0 && title endsWith "?"'
    do:
      labels: [question]
    ok:
      run: echo 'Set labels'
    ng:
      run: echo 'failed'
    name: Set 'question' label
  -
    id: second
    if: len(assignees) == 0
    do:
      assignees: [k1LoW]
    name: Assign me

tasks[*].id:

Each task have an id to be called by another task.

tasks[*].name:

Name of task.

tasks[*].if:

The task will not be performed unless the condition in the if section is met.

If the if section is missing, the task will not be performed unless it is called by another task.

Expression syntax

ghdag use antonmedv/expr.

See Language Definition.

Available variables

The variables available in the if section are as follows

Variable name Type Description
number int Number of the issue (pull request)
state string State of the issue (pull request)
title string Title of the issue (pull request)
body string Body of the issue (pull request)
url string URL of the issue (pull request)
author string Author of the issue (pull request)
labels array Labels that are set for the issue
assignees array Assignees of the issue (pull request)
reviewers array Reviewers of the pull request (including code owners)
code_owners array Code owners of the pull request
reviewers_who_approved array Reviewers who approved the pull request (including code owners)
code_owners_who_approved array Code owners who approved the pull request
is_issue bool true if the target type of the workflow is "Issue"
is_pull_request bool true if the target type of the workflow is "Pull request"
is_approved bool true if the pull request has received an approving review
is_review_required bool true if a review is required before the pull request can be merged
is_change_requested bool true if changes have been requested on the pull request
mergeable bool true if the pull request can be merged.
changed_files int Number of changed files in this pull request
hours_elapsed_since_created int Hours elspsed since the issue (pull request) created
hours_elapsed_since_updated int Hours elspsed since the issue (pull request) updated
number_of_comments int Number of comments
latest_comment_author string Author of latest comment
latest_comment_body string Body of latest comment
caller_action_run_stdout string Latest caller STDOUT of the run action
caller_action_run_stderr string Latest caller STDERR of the run action
caller_action_labels_updated array Latest caller update result of the labels: action
caller_action_assignees_updated array Latest caller update result of the assgnees: action
caller_action_reviewers_updated array Latest caller update result of the reviewers: action
caller_action_comment_created string Latest caller created comment of the comment: action
caller_action_state_changed string Latest caller changed state of the state: action
caller_action_notify_sent string Latest caller sent message of the notify: action
caller_action_do_error string Latest caller error message when do: action failed
year int Year of current time (UTC)
month int Month of current time (UTC)
day int Day of current time (UTC)
hour int Hour of current time (UTC)
weekday int Weekday of current time (UTC) (Sunday = 0, ...)
github_event_name string Event name of GitHub Actions ( ex. issues, pull_request )
github_event_action string Action name of event ( ex. opened closed )

tasks[*].env:

A map of environment environment variables in the scope of each task.

tasks[*].do:, tasks[*].ok:, tasks[*].ng:

A task has 3 actions ( called do, ok and ng ) with predetermined steps to be performed.

  1. Perform do: action.
  2. If the do: action succeeds, perform the ok: action.
  3. If the do: action fails, perform the ng: action.
Available builtin environment variables
Environment variable Description
GHDAG_TASK_ID Task ID
GHDAG_CALLER_TASK_ID Task ID of the caller via the next: action
GHDAG_ACTION_RUN_STDOUT STDOUT of the run action
GHDAG_ACTION_RUN_STDERR STDERR of the run action
GHDAG_ACTION_LABELS_UPDATED Update result of the labels: action
GHDAG_ACTION_ASSIGNEES_UPDATED Update result of the assgnees: action
GHDAG_ACTION_REVIEWERS_UPDATED Update result of the reviewers: action
GHDAG_ACTION_COMMENT_CREATED Created comment of the comment: action
GHDAG_ACTION_STATE_CHANGED Changed state of the state: action
GHDAG_ACTION_NOTIFY_SENT Sent message of the notify: action
GHDAG_ACTION_DO_ERROR Error message when do: action failed
GHDAG_TASK_* Variables available in the if: section. ( ex. number -> GHDAG_TASK_NUMBER )

tasks[*].<action_type>.run:

Execute command using sh -c.

Example

do:
  run: echo 'execute command'

tasks[*].<action_type>.labels:

Update the labels of the target issue or pull request.

Example

do:
  labels: [question, bug]

tasks[*].<action_type>.assignees:

Update the assignees of the target issue or pull request.

Example

do:
  assignees: [alice, bob, charlie]
env:
  GITHUB_ASSIGNEES_SAMPLE: 1

tasks[*].<action_type>.reviewers:

Update the reviewers for the target pull request.

However, Code owners has already been registered as a reviewer, so it is excluded.

Example

do:
  reviewers: [alice, bob, charlie]
env:
  GITHUB_REVIEWERS_SAMPLE: 2

tasks[*].<action_type>.comment:

Create new comment to the target issue or pull request.

Example

do:
  labels: [question]
ok:
  comment: Thank you for your question :+1:

tasks[*].<action_type>.state:

Change state the the target issue or pull request.

Example

if: hours_elapsed_since_updated > (24 * 30)
do:
  state: close
Changeable states
Target Changeable states
Issue close
Pull request close merge

tasks[*].<action_type>.notify:

Send notify message to Slack channel.

Example

ng:
  notify: error ${GHDAG_ACTION_OK_ERROR}
env:
  SLACK_CHANNEL: workflow-alerts
  SLACK_MENTIONS: [bob]
Required environment variables
  • ( SLACK_API_TOKEN and SLACK_CHANNEL ) or SLACK_WEBHOOK_URL

tasks[*].<action_type>.next:

Call next tasks in the same session.

Example

tasks:
  -
    id: set-question-label
    if: 'is_issue && len(labels) == 0 && title endsWith "?"'
    do:
      labels: [question]
    ok:
      next [notify-slack, add-comment]
  -
    id: notify-slack
    do:
      notify: A question has been posted.
  -
    id: add-comment
    do:
      comment: Thank you your comment !!!

Environment variables for configuration

Environment variable Description Default on GitHub Actions
GITHUB_TOKEN A GitHub access token. -
GITHUB_REPOSITORY The owner and repository name owner/repo of the repository where GitHub Actions are running
GITHUB_API_URL The GitHub API URL https://api.github.com
GITHUB_GRAPHQL_URL The GitHub GraphQL API URL https://api.github.com/graphql
SLACK_API_TOKEN A Slack OAuth access token -
SLACK_WEBHOOK_URL A Slack incoming webhook URL -
SLACK_CHANNEL A Slack channel to be notified -
GITHUB_ASSIGNEES_SAMPLE Number of users to randomly select from those listed in the assignees: action. -
GITHUB_REVIEWERS_SAMPLE Number of users to randomly select from those listed in the reviewers: action. -
GITHUB_COMMENT_MENTIONS Mentions to be given to comment -
GITHUB_COMMENT_MENTIONS_SAMPLE Number of users to randomly select from those listed in GITHUB_COMMENT_MENTIONS. -
SLACK_MENTIONS Mentions to be given to Slack message -
SLACK_MENTIONS_SAMPLE Number of users to randomly select from those listed in SLACK_MENTIONS. -
GHDAG_SAMPLE_WITH_SAME_SEED Sample using the same random seed as the previous action/task or not. -
SLACK_USERNAME Custom username of slack message. Require chat:write.customize scope.
SLACK_ICON_EMOJI Custom icon_emoji of slack message. Require chat:write.customize scope.
SLACK_ICON_URL Custom icon_url of slack message. Require chat:write.customize scope.
GITHUB_ASSIGNEES Additional Assignees to the list in the assignees: action -
GITHUB_REVIEWERS Additional Reviewers to the list in the reviewers: action -
GHDAG_ACTION_LABELS_BEHAVIOR Behavior of the labels: action ( replace (=default), add, remove ) -
GHDAG_ACTION_COMMENT_MAX Maximum number of consecutive comments by the same login ( default: 5 ) -

Required scope of SLACK_API_TOKEN

  • channel:read
  • chat:write
  • chat:write.public
  • users:read
  • usergroups:read
  • chat:write.customize ( optional )

Use ghdag as the one-shot command on GitHub Actions

ghdag can be used not only as a workflow engine, but also as a utility command in jobs on GitHub Actions.

$ ghdag do --help
do action.

Usage:
  ghdag do [command]

Available Commands:
  assignees   update the assignees of the target issue or pull request
  comment     create the comment of the target issue or pull request
  labels      update the labels of the target issue or pull request
  notify      send notify message to slack channel
  reviewers   update the reviewers of the target issue or pull request
  run         execute command using `sh -c`
  state       change state of the target issue or pull request

Flags:
  -h, --help   help for do

Use "ghdag do [command] --help" for more information about a command.
$ ghdag if --help
check condition.

Usage:
  ghdag if [CONDITION] [flags]

Flags:
  -h, --help         help for if
  -n, --number int   issue or pull request number

Example

name: labels

on:
  issues:
    types: [created]

jobs:
  set-labels:
    name: Set labels
    runs-on: ubuntu-latest
    container: ghcr.io/k1low/ghdag:latest
    steps:
      - name: Set labels
        run: ghdag do labels question
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
name: build

jobs:
  job-tests:

# snip

      - name: Send notification to channel
        if: failure()
        run: ghdag do notify 'Test faild'
        env:
          SLACK_API_TOKEN: ${{ secrets.SLACK_API_TOKEN }}
          SLACK_CHANNEL: operations
          SLACK_MENTIONS: bob

Install

deb:

Use dpkg-i-from-url

$ export GHDAG_VERSION=X.X.X
$ curl -L https://git.io/dpkg-i-from-url | bash -s -- https://github.com/k1LoW/ghdag/releases/download/v$GHDAG_VERSION/ghdag_$GHDAG_VERSION-1_amd64.deb

RPM:

$ export GHDAG_VERSION=X.X.X
$ yum install https://github.com/k1LoW/ghdag/releases/download/v$GHDAG_VERSION/ghdag_$GHDAG_VERSION-1_amd64.rpm

apk:

Use apk-add-from-url

$ export GHDAG_VERSION=X.X.X
$ curl -L https://git.io/apk-add-from-url | sh -s -- https://github.com/k1LoW/ghdag/releases/download/v$GHDAG_VERSION/ghdag_$GHDAG_VERSION-1_amd64.apk

homebrew tap:

$ brew install k1LoW/tap/ghdag

manually:

Download binary from releases page

go get:

$ go get github.com/k1LoW/ghdag

docker:

$ docker pull ghcr.io/k1low/ghdag:latest
Releases(v0.16.0)
Owner
Ken’ichiro Oyama
Ken’ichiro Oyama
End-to-end HTTP and REST API testing for Go.

httpexpect Concise, declarative, and easy to use end-to-end HTTP and REST API testing for Go (golang). Basically, httpexpect is a set of chainable bui

Victor Gaydov 1.7k Jul 24, 2021
End to end functional test and automation framework

Declarative end to end functional testing (endly) This library is compatible with Go 1.12+ Please refer to CHANGELOG.md if you encounter breaking chan

Viant, Inc 188 Jul 4, 2021
Randomized testing for Go

go-fuzz: randomized testing for Go Go-fuzz is a coverage-guided fuzzing solution for testing of Go packages. Fuzzing is mainly applicable to packages

Dmitry Vyukov 4.1k Jul 23, 2021
HTTP mock for Golang: record and replay HTTP/HTTPS interactions for offline testing

govcr A Word Of Warning I'm in the process of partly rewriting govcr to offer better support for cassette mutations. This is necessary because when I

Seb C 98 May 16, 2021
Fortio load testing library, command line tool, advanced echo server and web UI in go (golang). Allows to specify a set query-per-second load and record latency histograms and other useful stats.

Fortio Fortio (Φορτίο) started as, and is, Istio's load testing tool and now graduated to be its own project. Fortio is also used by, among others, Me

Fortio (Φορτίο) 2k Jul 18, 2021
A bytecode-based virtual machine to implement scripting/filtering support in your golang project.

eval-filter Implementation Scripting Facilities Types Built-In Functions Conditionals Loops Functions Case/Switch Use Cases Security Denial of service

Steve Kemp 63 Jul 23, 2021
A generic fuzzing and delta-debugging framework

Tavor Tavor (Sindarin for woodpecker) is a framework for easily implementing and using fuzzing and delta-debugging. Its EBNF-like notation allows you

Markus Zimmermann 232 Apr 27, 2021
HTTP load testing tool and library. It's over 9000!

Vegeta Vegeta is a versatile HTTP load testing tool built out of a need to drill HTTP services with a constant request rate. It can be used both as a

Tomás Senart 17.8k Jul 22, 2021
Clean database for testing, inspired by database_cleaner for Ruby

DbCleaner Clean database for testing, inspired by database_cleaner for Ruby. It uses flock syscall under the hood to make sure the test can runs in pa

Scott Le 131 Jul 21, 2021
Datastore Testibility

Datastore Testibility (dsunit) This library is compatible with Go 1.10+ Please refer to CHANGELOG.md if you encounter breaking changes. Introduction M

Viant, Inc 38 Feb 14, 2021
Markdown based document-driven RESTful API testing.

silk Markdown based document-driven web API testing. Write nice looking Markdown documentation (like this), and then run it using the silk command Sim

Mat Ryer 923 Jul 14, 2021
HTTP mocking to test API services for chaos scenarios

GAOS HTTP mocking to test API services for chaos scenarios Gaos, can create and provide custom mock restful services via using your fully-customizable

Trendyol Open Source 202 Jul 1, 2021
Sql mock driver for golang to test database interactions

Sql driver mock for Golang sqlmock is a mock library implementing sql/driver. Which has one and only purpose - to simulate any sql driver behavior in

DATA-DOG 3.7k Jul 23, 2021
HTTP mocking for Golang

httpmock Easy mocking of http responses from external resources. Install Currently supports Go 1.7 - 1.15. v1 branch has to be used instead of master.

Jared Morse 1.1k Jul 24, 2021