Popularity
6.3
Growing
Activity
7.9
-
504
6
29

Programming language: Go
License: GNU General Public License v3.0 or later
Tags: Build Automation    
Latest version: v1.0.0

goyek alternatives and similar packages

Based on the "Build Automation" category.
Alternatively, view goyek alternatives based on common mentions on social networks and blogs.

Do you think we are missing an alternative of goyek or a related project?

Add another 'Build Automation' Package

README

goyek

Create build pipelines in Go

Go Reference [Keep a Changelog](CHANGELOG.md) GitHub Release [go.mod](go.mod) [LICENSE](LICENSE)

Build Status Go Report Card codecov Mentioned in Awesome Go

Please ⭐ Star this repository if you find it valuable and worth maintaining.

Table of Contents:

Description

goyek (/ˈɡɔɪæk/ 🔊 listen) is used to create build pipelines in Go. As opposed to many other tools, it is just a Go library.

Here are some good parts:

  • No binary installation is needed. Simply add it to go.mod like any other Go module.
    • You can be sure that everyone uses the same version of goyek.
  • It has low learning curve, thanks to the minimal API surface, documentation, and examples.
  • The task's action look like a unit test. It is even possible to use testify or is for asserting.
  • It is easy to debug, like a regular Go application.
  • Tasks and helpers can be easily tested. See [exec_test.go](exec_test.go).
  • One can reuse code like in any Go application. It may be helpful to use packages like:

goyek API is mainly inspired by the testing, http, and flag packages.

See [docs/alternatives.md](docs/alternatives.md) if you want to compare goyek with other popular tools used for creating build pipelines.

See [docs/presentations.md](docs/presentations.md) if you want to watch some presenentations.

Quick start

Copy and paste the following code into [build/build.go](examples/basic/main.go):

package main

import (
    "github.com/goyek/goyek"
)

func main() {
    flow := &goyek.Flow{}

    flow.Register(goyek.Task{
        Name:  "hello",
        Usage: "demonstration",
        Action: func(tf *goyek.TF) {
            tf.Log("Hello world!")
        },
    })

    flow.Main()
}

Run:

go mod tidy

Sample usage:

$ go run ./build -h
Usage: [flag(s) | task(s)]...
Flags:
  -v     Default: false    Verbose: log all tasks as they are run.
  -wd    Default: .        Working directory: set the working directory.
Tasks:
  hello    demonstration
$ go run ./build hello
ok     0.000s
$ go run ./build hello -v
===== TASK  hello
Hello world!
----- PASS: hello (0.00s)
ok      0.001s

Repository template

Use goyek/template to create a new repository or when adopting goyek by copying most of its files.

Examples

  • [examples](examples)
  • [build/build.go](build/build.go) - this repository's own build pipeline
  • pellared/fluentassert - a library using goyek without polluting it's root go.mod
  • signalfx/splunk-otel-go - a multi-module repository using goyek

Wrapper scripts

Instead of executing go run ./build, you can use the wrapper scripts, which can be invoked from any location.

Simply add them to your repository's root directory:

  • [goyek.sh](goyek.sh) - make sure to add +x permission (git update-index --chmod=+x goyek.sh):
#!/bin/bash
set -euo pipefail

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
cd "$DIR/build"
go run . -wd=".." $@
  • [goyek.ps1](goyek.ps1):
Push-Location "$PSScriptRoot\build" -ErrorAction Stop
& go run . -wd=".." $args
Pop-Location
exit $global:LASTEXITCODE

Features

Task registration

The registered tasks are required to have a non-empty name, matching the regular expression TaskNamePattern. This means the following are acceptable:

  • letters (a-z and A-Z)
  • digits (0-9)
  • underscore (_)
  • hyphen (-) - except at the beginning
  • plus (+) - except at the beginning
  • colon (:) - except at the beginning

A task with a given name can be only registered once.

A task without description is not listed in CLI usage.

Task action

Task action is a function which is executed when a task is executed.

It is not required to set a action. Not having a action is very handy when registering "pipelines".

Task dependencies

During task registration it is possible to add a dependency to an already registered task. When the flow is processed, it makes sure that the dependency is executed before the current task is run. Take note that each task will be executed at most once.

Helpers for running programs

Use func (tf *TF) Cmd(name string, args ...string) *exec.Cmd to run a program inside a task's action.

You can use it create your own helpers, for example:

import (
    "fmt"
    "os/exec"

    "github.com/goyek/goyek"
    "github.com/mattn/go-shellwords"
)

func Cmd(tf *goyek.TF, cmdLine string) *exec.Cmd {
    args, err := shellwords.Parse(cmdLine)
    if err != nil {
        tf.Fatalf("parse command line: %v", err)
    }
    return tf.Cmd(args[0], args[1:]...)
}

func Exec(cmdLine string) func(tf *goyek.TF) {
    args, err := shellwords.Parse(cmdLine)
    if err != nil {
        panic(fmt.Sprintf("parse command line: %v", err))
    }
    return func(tf *goyek.TF) {
        if err := tf.Cmd(args[0], args[1:]...).Run(); err != nil {
            tf.Fatal(err)
        }
    }
}

Here is the explanation why argument splitting is not included out-of-the-box.

Verbose mode

Enable verbose output using the -v CLI flag. It works similar to go test -v. Verbose mode streams all logs to the output. If it is disabled, only logs from failed task are send to the output.

Use func (f *Flow) VerboseParam() BoolParam if you need to check if verbose mode was set within a task's action.

The default value for the verbose parameter can be overwritten with func (f *Flow) RegisterVerboseParam(p BoolParam) RegisteredBoolParam.

Default task

Default task can be assigned via the Flow.DefaultTask field.

When the default task is set, then it is run if no task is provided via CLI.

Parameters

The parameters can be set via CLI using the flag syntax.

On the CLI, flags can be set in the following ways:

  • -param simple - for simple single-word values
  • -param "value with blanks"
  • -param="value with blanks"
  • -param - setting boolean parameters implicitly to true

For example, ./goyek.sh test -v -pkg ./... would run the test task with v bool parameter (verbose mode) set to true, and pkg string parameter set to "./...".

Parameters must first be registered via func (f *Flow) RegisterValueParam(newValue func() ParamValue, info ParamInfo) ValueParam, or one of the provided methods like RegisterStringParam.

The registered parameters are required to have a non-empty name, matching the regular expression ParamNamePattern. This means the following are acceptable:

  • letters (a-z and A-Z)
  • digits (0-9)
  • underscore (_) - except at the beginning
  • hyphen (-) - except at the beginning
  • plus (+) - except at the beginning
  • colon (:) - except at the beginning

After registration, tasks need to specify which parameters they will read. Do this by assigning the RegisteredParam instance from the registration result to the Task.Params field. If a task tries to retrieve the value from an unregistered parameter, the task will fail.

When registration is done, the task's action can retrieve the parameter value using the Get(*TF) method from the registration result instance during the task's Action execution.

See [examples/parameters/main.go](examples/parameters/main.go) for a detailed example.

See [examples/validation/main.go](examples/validation/main.go) for a detailed example of cross-parameter validation.

Flow will fail execution if there are unused parameters.

Supported Go versions

Minimal supported Go version is 1.11.

Contributing

See [docs/contributing.md](docs/contributing.md) if you want to help us.

License

goyek is licensed under the terms of the MIT license.

[github.com/goyek/goyek package](go.mod) does not use any third-party dependency other than the Go standard library.


*Note that all licence references and agreements mentioned in the goyek README section above are relevant to that project's source code only.