Concurrent task runner, developer's routine tasks automation toolkit. Simple modern alternative to GNU Make 🧰

Overview

taskctl - developer's routine tasks automation toolkit

taskctl - concurrent task runner, developer's routine tasks automation toolkit

pkg.go.dev reference GitHub tag (latest SemVer) GitHub go.mod Go version GitHub closed issues GitHub issues Licence

Tests Requirements Status GitHub top language Go Report Card Test Coverage Maintainability PRs Welcome

Simple modern alternative to GNU Make. taskctl is concurrent task runner that allows you to design you routine tasks and development pipelines in nice and neat way in human-readable format (YAML, JSON or TOML). Given a pipeline (composed of tasks or other pipelines) it builds a graph that outlines the execution plan. Each task my run concurrently or cascade. Beside pipelines, each single task can be started manually or triggered by built-in filesystem watcher.

Features

  • human-readable configuration format (YAML, JSON or TOML)
  • concurrent tasks execution
  • highly customizable execution plan
  • cross platform
  • import local or remote configurations
  • integrated file watcher (live reload)
  • customizable execution contexts
  • different output types
  • embeddable task runner
  • interactive prompt
  • handy autocomplete
  • and many more...
tasks:
  lint:
    command:
      - golint $(go list ./... | grep -v /vendor/)
      - go vet $(go list ./... | grep -v /vendor/)
  
  test:
    allow_failure: true
    command: go test ./....
        
  build:
    command: go build -o bin/app ./...
    env: 
      GOOS: linux
      GOARCH: amd64
    before: rm -rf bin/*

pipelines:
  release:
    - task: lint
    - task: test
    - task: build
      depends_on: [lint, test]

According to this plan lint and test will run concurrently, build will start only when both lint and test finished.

asciicast

Contents

Getting started

Install

MacOS

brew tap taskctl/taskctl
brew install taskctl

Linux

sudo wget https://github.com/taskctl/taskctl/releases/latest/download/taskctl_linux_amd64 -O /usr/local/bin/taskctl
sudo chmod +x /usr/local/bin/taskctl

Ubuntu Linux

sudo snap install --classic taskctl

deb/rpm:

Download the .deb or .rpm from the releases page and install with dpkg -i and rpm -i respectively.

Windows

scoop bucket add taskctl https://github.com/taskctl/scoop-taskctl.git
scoop install taskctl

Installation script

curl -sL https://raw.githubusercontent.com/taskctl/taskctl/master/install.sh | sh

From sources

git clone https://github.com/taskctl/taskctl
cd taskctl
go build -o taskctl .

Docker images

Docker images available on Docker hub

Usage

  • taskctl - run interactive task prompt
  • taskctl pipeline1 - run single pipeline
  • taskctl task1 - run single task
  • taskctl pipeline1 task1 - run one or more pipelines and/or tasks
  • taskctl watch watcher1 watcher2 - start one or more watchers

Configuration

taskctl uses config file (tasks.yaml or taskctl.yaml) where your tasks and pipelines stored. Config file includes following sections:

  • tasks
  • pipelines
  • watchers
  • contexts
  • variables

Config file may import other config files, directories or URLs.

import:
- .tasks/database.yaml
- .tasks/lint/
- https://raw.githubusercontent.com/taskctl/taskctl/master/docs/example.yaml

Example

Config file example

Global configuration

taskctl has global configuration stored in $HOME/.taskctl/config.yaml file. It is handy to store system-wide tasks, reusable contexts, defaults etc.

Tasks

Task is a foundation of taskctl. It describes one or more commands to run, their environment, executors and attributes such as working directory, execution timeout, acceptance of failure, etc.

tasks:
    lint:
        allow_failure: true
        command:
          - golint $(go list ./... | grep -v /vendor/)
          - go vet $(go list ./... | grep -v /vendor/)
          
    build:
        command: go build ./...
        env: 
          GOOS: linux
          GOARCH: amd64
        after: rm -rf tmp/*
        variations:
          - GOARCH: amd64
          - GOARCH: arm
            GOARM: 7

Task definition takes following parameters:

  • command - one or more commands to run
  • variations - list of variations (env variables) to apply to command
  • context - execution context's name
  • env - environment variables. All existing environment variables will be passed automatically
  • dir - working directory. Current working directory by default
  • timeout - command execution timeout (default: none)
  • allow_failure - if set to true failed commands will not interrupt execution (default: false)
  • after - command that will be executed after command completes
  • before - command that will be executed before task starts
  • exportAs - env variable name to store task's output (default: TASK_NAME_OUTPUT, where TASK_NAME is actual task's name)
  • condition - condition to check before running task
  • variables - task's variables
  • interactive - if true provides STDIN to commands (default: false)

Tasks variables

Each task, stage and context has variables to be used to render task's fields - command, dir. Along with globally predefined, variables can be set in a task's definition. You can use those variables according to text/template documentation.

Predefined variables are:

  • .Root - root config file directory
  • .Dir - config file directory
  • .TempDir - system's temporary directory
  • .Args - provided arguments
  • .Task.Name - current task's name
  • .Context.Name - current task's execution context's name
  • .Stage.Name - current stage's name
  • .Output - previous command's output
  • .Tasks.Task1.Output - task1 last command output

Variables can be used inside task definition. For example:

tasks:
    task1:
        dir: "{{ .Root }}/some-dir"
        command:
          - echo "My name is {{ .Task.Name }}"
          - echo {{ .Output }} # My name is task1
          - echo "Sleep for {{ .sleep }} seconds"
          - sleep {{ .sleep | default 10 }}
          - sleep {{ .sleep }}
        variables:
          sleep: 3

Pass CLI arguments to task

Any command line arguments succeeding -- are passed to each task via .Args variable or ARGS environment variable.

Given this definition:

lint:
  command: go lint {{.Args}}

the resulting command is:

$ taskctl lint -- package.go
# go lint package.go

Storing task's output

Task output automatically stored to the variable named like this - .Tasks.TaskName.Output, where TaskName is the actual task's name. It is also stored to TASK_NAME_OUTPUT environment variable. It's name can be changed by a task's exportAs parameter. Those variables will be available to all dependent stages.

Tasks variations

Task may run in one or more variations. Variations allows to reuse task with different env variables:

tasks:
  build:
    command:
      - GOOS=${GOOS} GOARCH=amd64 go build -o bin/taskctl_${GOOS} ./cmd/taskctl
    env:
      GOFLAGS: -ldflags=-s -ldflags=-w
    variations:
      - GOOS: linux
      - GOOS: darwin
      - GOOS: windows

this config will run build 3 times with different GOOS

Task conditional execution

The following task will run only when there are any changes that are staged but not committed:

tasks:
  build:
    command:
      - ...build...
    condition: git diff --exit-code

Pipelines

Pipeline is a set of stages (tasks or other pipelines) to be executed in a certain order. Stages may be executed in parallel or one-by-one. Stage may override task's environment, variables etc.

This pipeline:

pipelines:
    pipeline1:
        - task: start task
        - task: task A
          depends_on: "start task"
        - task: task B
          depends_on: "start task"
        - task: task C
          depends_on: "start task"
        - task: task D
          depends_on: "task C"
        - task: task E
          depends_on: ["task A", "task B", "task D"]
        - task: finish
          depends_on: ["task E"]    

will result in an execution plan like this: execution plan

Stage definition takes following parameters:

  • name - stage name. If not set - referenced task or pipeline name will be used.
  • task - task to execute on this stage
  • pipeline - pipeline to execute on this stage
  • env - environment variables. All existing environment variables will be passed automatically
  • depends_on - name of stage on which this stage depends on. This stage will be started only after referenced stage is completed.
  • allow_failure - if true failing stage will not interrupt pipeline execution. false by default
  • condition - condition to check before running stage
  • variables - stage's variables

Taskctl output formats

Taskctl has several output formats:

  • raw - prints raw commands output
  • prefixed - strips ANSI escape sequences where possible, prefixes command output with task's name
  • cockpit - tasks dashboard

Filesystem watchers

Watcher watches for changes in files selected by provided patterns and triggers task anytime an event has occurred.

watchers:
  watcher1:
    watch: ["README.*", "pkg/**/*.go"] # Files to watch
    exclude: ["pkg/excluded.go", "pkg/excluded-dir/*"] # Exclude patterns
    events: [create, write, remove, rename, chmod] # Filesystem events to listen to
    task: task1 # Task to run when event occurs

Patterns

Thanks to doublestar taskctl supports the following special terms within include and exclude patterns:

Special Terms Meaning
* matches any sequence of non-path-separators
** matches any sequence of characters, including path separators
? matches any single non-path-separator character
[class] matches any single non-path-separator character against a class of characters (details)
{alt1,...} matches a sequence of characters if one of the comma-separated alternatives matches

Any character with a special meaning can be escaped with a backslash (\).

Contexts

Contexts allow you to set up execution environment, variables, binary which will run your task, up/down commands etc.

contexts:
  local:
    executable:
      bin: /bin/zsh
      args:
        - -c
    env:
      VAR_NAME: VAR_VALUE
    variables:
      sleep: 10
    quote: "'" # will quote command with provided symbol: "/bin/zsh -c 'echo 1'"
    before: echo "I'm local context!"
    after: echo "Have a nice day!"

Context has hooks which may be triggered once before first context usage or every time before task with this context will run.

context:
    docker-compose:
      executable:
        bin: docker-compose
        args: ["exec", "api"]
      up: docker-compose up -d api
      down: docker-compose down api

    local:
      after: rm -rf var/*

Docker context

  alpine:
    executable:
      bin: /usr/local/bin/docker
      args:
        - run
        - --rm
        - alpine:latest
    env:
      DOCKER_HOST: "tcp://0.0.0.0:2375"
    before: echo "SOME COMMAND TO RUN BEFORE TASK"
    after: echo "SOME COMMAND TO RUN WHEN TASK FINISHED SUCCESSFULLY"

tasks:
  mysql-task:
    context: alpine
    command: uname -a

Embeddable task runner

taskctl may be embedded into any go program. Additional information may be found on taskctl's pkg.go.dev page

Runner

t := task.FromCommands("go fmt ./...", "go build ./..")
r, err := NewTaskRunner()
if err != nil {
    return
}
err  = r.Run(t)
if err != nil {
    fmt.Println(err, t.ExitCode, t.ErrorMessage())
}
fmt.Println(t.Output())

Scheduler

format := task.FromCommands("go fmt ./...")
build := task.FromCommands("go build ./..")
r, _ := runner.NewTaskRunner()
s := NewScheduler(r)

graph, err := NewExecutionGraph(
    &Stage{Name: "format", Task: format},
    &Stage{Name: "build", Task: build, DependsOn: []string{"format"}},
)
if err != nil {
    return
}

err = s.Schedule(graph)
if err != nil {
    fmt.Println(err)
}

FAQ

How does it differ from go-task/task?

It's amazing how solving same problems lead to same solutions. taskctl and go-task have a lot of concepts in common but also have some differences.

  1. Main is pipelines. Pipelines and stages allows more precise workflow design because same tasks may have different dependencies (or no dependencies) in different scenarios.
  2. Contexts allow you to set up execution environment and binary which will run your task.

Autocomplete

Bash

Add to ~/.bashrc or ~/.profile

. <(taskctl completion bash)

ZSH

Add to ~/.zshrc

. <(taskctl completion zsh)

Similar projects

How to contribute?

Feel free to contribute in any way you want. Share ideas, submit issues, create pull requests. You can start by improving this README.md or suggesting new features Thank you!

License

This project is licensed under the GNU GPLv3 - see the LICENSE.md file for details

Authors

  • Yevhen Terentiev - trntv See also the list of contributors who participated in this project.
Comments
  • yaml parsing error

    yaml parsing error

    There is something wrong with yaml parsing, let show example:

    tasks:                                                                                                                                                                
      task1:                                                                                                                                                              
        dir: /etc                                                                                                                                                         
        command:                                                                                                                                                          
          - /bin/ls -la                                                                                                                                                   
          - /bin/pwd                                                                                                                                                      
          - /bin/printf '%s\nLine-2\n' '=========== Line #1 ==================' 
    

    Even hash symbol # is enclosed in single quotes, it treated as a comment symbol and as result: reached EOF without closing quote '

    An attempt to escape hash sign as:

    tasks:                                                                                                                                                                
      task1:                                                                                                                                                              
        dir: /etc                                                                                                                                                         
        command:                                                                                                                                                          
          - /bin/ls -la                                                                                                                                                   
          - /bin/pwd                                                                                                                                                      
          - /bin/printf '%s\nLine-2\n' '=========== Line \#1 =================='
    

    will fix the problem, but escaping is visible as: =========== Line \#1 ================== which is also wrong.

    More serious issue happened if we going to process tasks via context:

    tasks:                                                                                                                                                                
      task1:                                                                                                                                                              
        context: ctx-bin-sh                                                                                                                                               
        dir: /etc                                                                                                                                                         
        command:                                                                                                                                                          
          - /bin/ls -la                                                                                                                                                   
          - /bin/pwd                                                                                                                                                      
          - /bin/printf '%s\nLine-2\n' '=========== Line 1 =================='                                                                                           
                                                                                                                                                                          
    contexts:                                                                                                                                                             
      ctx-bin-sh:                                                                                                                                                         
        executable:                                                                                                                                                       
          bin: /bin/sh                                                                                                                                                    
          args:                                                                                                                                                           
            - -c                                                                                                                                                          
        before: echo "================================================================================"                                                                   
        after: echo "--------------------------------------------------------------------------------"
    

    First of all before & after assigned in ctx-bin-sh won't show content. Commands in task1 will pass commands to ctx-bin-sh the only first part ignoring rest of the string. (quoting commands as "/bin/ls -la" won't help either) So, /bin/ls -la will be executed simply as /bin/sh (where -la get lost). printf command will be fired without arguments at all, so result is /bin/printf: missing operand

    opened by CompuRoot 4
  • Command line arguments should be available as an array / slice

    Command line arguments should be available as an array / slice

    Provided command line arguments are available now as a string in the .Args variable.

    Handling individual arguments is somewhat inconvenient this way.

    Feature request

    Would be nice if the command line arguments would be available as an array / slice to reach individual arguments more conveniently.

    E.g. provided by this command line taskctl mytask -- arg1 arg2 We could reach the values like .Argsa[0] which would equal arg1

    Thanks for considering this request!

    opened by hetesiistvan 3
  • How to use bash functions in tasks

    How to use bash functions in tasks

    Hi!

    I want to use self-written Bash functions in tasks, but something goes wrong.

        command:
          - |
            function zookeeper_replicas() {
              kubectl --namespace ${KUBE_NAMESPACE} get statefulsets.apps --field-selector=metadata.name=zookeeper \
                --output 'jsonpath={..status.replicas}'
            }
          - |
            function zookeeper_ready_replicas() {
              kubectl --namespace ${KUBE_NAMESPACE} get statefulsets.apps --field-selector=metadata.name=zookeeper \
                --output 'jsonpath={..status.readyReplicas}'
            }
          - |
            while [[ $(zookeeper_replicas) != $(zookeeper_ready_replicas) ]]; do
              echo "Waiting ready zookeeper"
              sleep 1
            done
    

    The above example, when run, throws an error:

    "zookeeper_replicas": executable file not found in $PATH
    "zookeeper_ready_replicas": executable file not found in $PATH
    

    Is there any way to use similar functions in tasks? Thanks in advance for your answer.

    UPD: fixed in the following way:

        command:
          - |
            function zookeeper_replicas() {
              kubectl --namespace ${KUBE_NAMESPACE} get statefulsets.apps --field-selector=metadata.name=zookeeper \
                --output 'jsonpath={..status.replicas}'
            };
            function zookeeper_ready_replicas() {
              kubectl --namespace ${KUBE_NAMESPACE} get statefulsets.apps --field-selector=metadata.name=zookeeper \
                --output 'jsonpath={..status.readyReplicas}'
            };
            while [[ $(zookeeper_replicas) != $(zookeeper_ready_replicas) ]]; do
              echo "Waiting ready zookeeper"
              sleep 1
            done
    
    opened by warlock9600 2
  • Add env_file to pipelines and context

    Add env_file to pipelines and context

    Feature request

    taskctl is a great tool! However, it is not possible to easily reuse tasks for multiple environments. Especially in cases, where you maintain environment parity, but enumerating all env variables would cause tasks file to grow significantly. It might be easily solved by an ability to specify env_file for specific pipeline and context

    pipelines:
      live-pipeline1:
        - task: task1
          name: liveStage1
          env_file: .env.live
      stage-pipeline1:
        - task: task1
          name: stageStage1
          env_file: .env.stage
    
    tasks:
      test1:
        command:
          - echo $FOO
    
    opened by damian-szulc 1
  • Output property is ignored when specified in the tasks.yml file

    Output property is ignored when specified in the tasks.yml file

    Just like in the documentation [1] I specify the output property in the tasks.yml file:

    output: prefixed
    

    Unfortunately it seems to be ignored by taskctl. When I specify this option via command line (-o prefixed) then it works just as expected.

    I use taskctl on macOsx, the version is:

    $ taskctl -version
    taskctl version 1.3.0
    

    Am I doing something incorrectly?

    Thanks for checking in advance!

    [1] - https://github.com/taskctl/taskctl/blob/master/docs/example.yaml#L163

    bug 
    opened by hetesiistvan 1
  • Define environment variables using a property file

    Define environment variables using a property file

    In my case I use taskctl to deploy an application to different environments. This includes most of the steps of the lifecycle starting from building the application to K8s deployment.

    Quite some steps do require environment-specific information, like server URL, connection string, etc... In some cases those information needs to be passed as a command-line argument, in other cases they are required for templating.

    The values which are environment specific are stored in properties files, e.g. like test.properties:

    DB_URL=...
    SELECTED_REGION=...
    SMTP_SERVER=...
    

    This is really convenient to maintain but requires a workaround ATM to be used with taskctl.

    Feature proposal

    Individual environment variables can be used ATM like this:

      build:
        command: go build -o bin/app ./...
        env: 
          GOOS: linux
          GOARCH: amd64
    

    (example from the documentation)

    Using environment property files would look like the following:

      build:
        command: go build -o bin/app ./...
        env_file: 
          build.properties
    

    Where build.properties contains:

    GOOS: linux
    GOARCH: amd64
    

    This would be already a great help.

    If the name of the environment file could contain variable like ``` "{{ .ArgsList[1] }}.properties" it would be quite perfect. 🚀

    Many thanks for considering this!

    opened by hetesiistvan 1
  • Segmentation violation

    Segmentation violation

    Unpack taskctl to an empty directory that unavailable via PATH and try to run it. Program failed to start with following error message:

    panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0x875685]
    
    goroutine 1 [running]:
    main.buildTaskRunner(0xc0001a0580, 0xc0001961c8, 0x96a119, 0x412822)
    	/home/runner/work/taskctl/taskctl/cmd/taskctl/taskctl.go:254 +0x75
    main.rootAction(0xc0001a0580, 0xc00019e800, 0x0)
    	/home/runner/work/taskctl/taskctl/cmd/taskctl/taskctl.go:194 +0x43
    github.com/urfave/cli/v2.(*App).RunContext(0xc000082780, 0xa2cba0, 0xc0000b6010, 0xc0000961b0, 0x1, 0x1, 0x0, 0x0)
    	pkg/mod/github.com/urfave/cli/[email protected]/app.go:315 +0x70b
    github.com/urfave/cli/v2.(*App).Run(...)
    	pkg/mod/github.com/urfave/cli/[email protected]/app.go:215
    main.run(0xc0000c4000, 0xa23680)
    	/home/runner/work/taskctl/taskctl/cmd/taskctl/taskctl.go:67 +0xa7
    main.main()
    	/home/runner/work/taskctl/taskctl/cmd/taskctl/taskctl.go:43 +0x73
    

    The reason is absents of yaml file. After running taskctl init to create default config, everything is fine then.

    My suggestion is to throw human understandable error, something like: Can't run due to absents of config file. Run taskctl init to create default one

    bug 
    opened by CompuRoot 1
  • Does taskctl support capturing output from called apps and storing as a variable?

    Does taskctl support capturing output from called apps and storing as a variable?

    Hi,

    I'm exploring using this tool as a potential replacement for Makefiles in some of my projects (Go newbie). One of the features I'm looking for is calling external applications and capturing their output for use with various tasks. For example, capturing the current commit hash so I can pass it to go build via a -ldflags option.

    I looked over the README and the Full config example, but didn't see this mentioned. It could very well be there and I have just overlooked it.

    If this isn't supported now, is it a planned feature?

    Thank you for your time.

    enhancement 
    opened by atc0005 1
  • Respect 'output' param set in local yaml file

    Respect 'output' param set in local yaml file

    Current behavior

    Tasks file:

    output: raw
    
    tasks:
      task1:
        command: "echo 'hello, world!'"
    

    After running following command:

    taskctl task1
    

    a user will be presented with a prefixed output:

    Screenshot 2021-05-21 at 21 00 54

    Expected behavior

    User will be presented with raw output

    Screenshot 2021-05-21 at 21 01 41 bug 
    opened by damian-szulc 0
  • Interpolate variables

    Interpolate variables

    Interpolate tasks's variables to allow such configs:

    tasks:
      image:bluid:
        command:
          - docker build -t {{ .Registry }}/foo:{{ .Tag }} .
          - docker push {{ .Registry }}/foo:{{ .Tag }}
        variables:
          Tag: '{{ .Args | default "latest" }}'
          Registry: registry.example.com
    
    opened by trntv 0
  • Overwrite default

    Overwrite default "Args" variable

    tasks:
      exec:api:
        interactive: true
        command:
          - docker-compose up -d api
          - docker-compose exec api {{.Args}}
        variables:
          Args: bash
    

    if args provided by user, it should replace default one

    taskctl exec:api -- sh
    
    opened by trntv 0
  • Cannot Install Using Homebrew

    Cannot Install Using Homebrew

    The Homebrew install is not working. I've tried on 2 macs running MacOS 12.3.1 and get the following:

    ~ brew tap taskctl/taskctl Running brew update --preinstall... ==> Auto-updated Homebrew! Updated 2 taps (homebrew/core and homebrew/cask). ==> Updated Formulae Updated 111 formulae. ==> Updated Casks Updated 43 casks.

    ==> Tapping taskctl/taskctl Cloning into '/usr/local/Homebrew/Library/Taps/taskctl/homebrew-taskctl'... remote: Enumerating objects: 169, done. remote: Counting objects: 100% (169/169), done. remote: Compressing objects: 100% (164/164), done. remote: Total 169 (delta 60), reused 16 (delta 4), pack-reused 0 Receiving objects: 100% (169/169), 30.79 KiB | 7.70 MiB/s, done. Resolving deltas: 100% (60/60), done. Error: Invalid formula: /usr/local/Homebrew/Library/Taps/taskctl/homebrew-taskctl/taskctl.rb taskctl: Calling bottle :unneeded is disabled! There is no replacement. Please report this issue to the taskctl/taskctl tap (not Homebrew/brew or Homebrew/core): /usr/local/Homebrew/Library/Taps/taskctl/homebrew-taskctl/taskctl.rb:6

    Error: Cannot tap taskctl/taskctl: invalid syntax in tap!

    opened by dsmallwood-amido 2
  • Specifying imports without any items throws unfriendly error

    Specifying imports without any items throws unfriendly error

    If one includes a block like so:

    import:
    # nothing
    
    tasks:
     blabla
    

    Then an error is generated like the below:

    panic: interface conversion: interface {} is nil, not []interface {}
    
    goroutine 1 [running]:
    github.com/taskctl/taskctl/internal/config.(*Loader).load(0xc00008db30, 0xc000026460, 0x20, 0x0, 0x0, 0x0)
    	/home/runner/work/taskctl/taskctl/internal/config/loader.go:155 +0xa1f
    github.com/taskctl/taskctl/internal/config.(*Loader).Load(0xc00008db30, 0xc000026460, 0x20, 0x0, 0x0, 0xc05170)
    	/home/runner/work/taskctl/taskctl/internal/config/loader.go:74 +0x10d
    main.makeApp.func2(0xc00007e580, 0xb, 0x12)
    	/home/runner/work/taskctl/taskctl/cmd/taskctl/taskctl.go:138 +0x8a
    github.com/urfave/cli/v2.(*App).RunContext(0xc0000b0480, 0x9be810, 0xc0000a8010, 0xc0000b4000, 0x2, 0x2, 0x0, 0x0)
    	pkg/mod/github.com/urfave/cli/[email protected]/app.go:291 +0x882
    github.com/urfave/cli/v2.(*App).Run(...)
    	pkg/mod/github.com/urfave/cli/[email protected]/app.go:215
    main.run(0xc0000ba000, 0x9b6ca0)
    	/home/runner/work/taskctl/taskctl/cmd/taskctl/taskctl.go:65 +0xaf
    main.main()
    	/home/runner/work/taskctl/taskctl/cmd/taskctl/taskctl.go:42 +0x73
    ##[error]Bash exited with code '2'.
    

    Easy to figure out since that was my only change, but I wonder if there's a kinder way to surface this error?

    opened by williamayerst 0
  • Task-level variables are not available from pipeline

    Task-level variables are not available from pipeline

    Encountered issue on Windows 10 using taskctl version 1.4.2.

    When running the following taskctl.yaml an error is encountered:

    pipelines:
      pipeline1:
        - task: task1
    
    tasks:
      task1:
        description: "Example task 1"
        command: "echo hello {{ .message }}"
        variables: 
          message: "world"
    
    
    taskctl run pipeline1
    time="2022-01-12 21:16:11" level=info msg="Running task task1..."
    time="2022-01-12 21:16:11" level=info msg="task1 finished. Duration 0s"
    time="2022-01-12 21:16:11" level=fatal msg="pipeline pipeline1 failed: template: interpolate:1:14: executing \"interpolate\" at <.message>: map has no entry for key \"message\""
    

    Setting the variables at a task level within pipeline map will be correctly be passed to the task level:

    pipelines:
      pipeline1:
        - task: task1
          variables: 
            message: "world"
    
    tasks:
      task1:
        description: "Example task 1"
        command: "echo hello {{ .message }}"
    
    
    taskctl run pipeline1
    time="2022-01-12 21:21:58" level=info msg="Running task task1..."
    task1: hello
    task1:
    task1: world
    time="2022-01-12 21:21:58" level=info msg="task1 finished. Duration 527.7µs"
    
    Summary:
    - Stage task1 was completed in 1.58ms
    Total duration: 50.0753ms
    

    I suppose after clarifying the issue it technically works, but the variables must be put into the pipeline rather than the task level. I find this slightly non-intuitive, but if it is working as designed feel free to cancel this issue.

    opened by karldreher 0
  • It is possible to use a context's variables in a task?

    It is possible to use a context's variables in a task?

    I am working with taskctl to simplify some builds and to use PowerShell as my context for the task. I have sucessfully created a context that allows me to do this.

    From the docs, I had thought that I would be able to set some variables in the context and then use them in the task which uses that context, like so:

    contexts:
      powershell:
        executable:
          bin: pwsh
          args:
            - -NoProfile
            - -Command
        variables:
          test_arguments: "-v q /p:CollectCoverage=true /p:CoverletOutputFormat=opencover"
    
    tasks:
    
      test:unittest:
        context: powershell
        description: Perform unit tests
        command:
          - build/scripts/Invoke-DotNetTests.ps1 -arguments {{ .test_arguments }}
        env:
          pattern: "*UnitTests"
    

    However, when I run this i get the error message:

    time="2021-11-12 14:59:45" level=info msg="Running task test:unittest..."
    time="2021-11-12 14:59:45" level=info msg="test:unittest finished. Duration 498.7µs"
    time="2021-11-12 14:59:45" level=fatal msg="task test:unittest failed: template: interpolate:1:76: executing \"interpolate\" at <.test_arguments>: map has no entry for key \"test_arguments\""
    

    Does this mean it is not possible to interpolate variables set in the context?

    opened by russellseymour 0
  • Watcher not triggering task

    Watcher not triggering task

    Using the task file generated by taskctl init, I would have expected that when running

    taskctl watch watcher1

    task1 is getting executed, whenever READEME.md is changed. However, task1 is executed only once and changes to README.md have no effect. With --debug the output shows that the change is detected. Below I edited the file twice, both times a debug log is written, but task1 is not executed:

    # taskctl --debug watch watcher1
    DEBU[0000] starting watcher watcher1
    DEBU[0000] watcher "watcher1" is waiting for events in README.md
    DEBU[0000] Executing "echo "I'm task1""
    I'm task1
    DEBU[0005] watcher1: event "WRITE" in file "README.md"
    DEBU[0009] watcher1: event "WRITE" in file "README.md"
    [No further output]
    

    I have both tried the latest download and building from source. Linux x86_64.

    Please let me know if any further information would be helpful. Thanks!

    bug 
    opened by bschwehn 1
Releases(1.4.2)
Owner
null
Build system and task runner for Go projects

Gilbert is task runner that aims to provide declarative way to define and run tasks like in other projects like Gradle, Maven and etc.

Gilbert 104 Sep 26, 2022
Modern Make

Modern Make About Mmake is a small program which wraps make to provide additional functionality, such as user-friendly help output, remote includes, a

TJ Holowaychuk 1.6k Sep 26, 2022
🌍 Earthly is a build automation tool for the container era

?? Earthly is a build automation tool for the container era. It allows you to execute all your builds in containers. This makes them self-contained, repeatable, portable and parallel. You can use Earthly to create Docker images and artifacts (eg binaries, packages, arbitrary files).

Earthly 8k Sep 24, 2022
A small utility that aims to automate and simplify some tasks related to software release cycles.

Stork is a small utility that aims to automate and simplify some tasks related to software release cycles such as reading the current version from a f

Simone Margaritelli 42 Sep 21, 2022
run/stop goroutines/tasks securely, recursively

grunner - run/stop goroutines/tasks securely, recursively. s1 := grunner.New() s1.Defer(func() { fmt.Println("s1 stopped 2") }) s1.Defer(func() {

vogo 0 Apr 22, 2022
a Make/rake-like dev tool using Go

About Mage is a make-like build tool using Go. You write plain-old go functions, and Mage automatically uses them as Makefile-like runnable targets. I

Mage 3.2k Sep 30, 2022
EGo lets you build, debug und run Go apps on Intel SGX - as simple as conventional Go programming!

EGo is a framework for building confidential apps in Go. Confidential apps run in always-encrypted and verifiable enclaves on Intel SGX-enabled ha

Edgeless Systems GmbH 339 Sep 21, 2022
NFPM is Not FPM - a simple deb, rpm and apk packager written in Go

NFPM NFPM is Not FPM - a simple deb, rpm and apk packager written in Go. Why While fpm is great, for me, it is a bummer that it depends on ruby, tar a

GoReleaser 1.6k Sep 27, 2022
A simple tool to help WoW repack administrators manipulate the repack database(s)

WoW Repack Manipulator This tool makes it easier for an administrator of a WoW Repack (private WoW server, basically) to manipulate the database that

Michael Crilly 2 Feb 7, 2022
Telegram + Google Sheet daily routine trackerTelegram + Google Sheet daily routine tracker

Telegram + Google Sheet daily routine tracker Deploy as serverless function Fork this repository and set secrets github secrets: API_DOMAIN - your ver

Sergey Varibrus 0 Oct 13, 2021
A task runner / simpler Make alternative written in Go

Task Task is a task runner / build tool that aims to be simpler and easier to use than, for example, GNU Make. See taskfile.dev for the documentation.

Task 5.8k Oct 1, 2022
Realize is the #1 Golang Task Runner which enhance your workflow by automating the most common tasks and using the best performing Golang live reloading.

#1 Golang live reload and task runner Content - ⭐️ Top Features - ???? Get started - ?? Config sample - ?? Commands List - ?? Support and Suggestions

Oxequa 4.3k Sep 21, 2022
Realize is the #1 Golang Task Runner which enhance your workflow by automating the most common tasks and using the best performing Golang live reloading.

#1 Golang live reload and task runner Content - ⭐️ Top Features - ???? Get started - ?? Config sample - ?? Commands List - ?? Support and Suggestions

Oxequa 4.3k Sep 29, 2022
Golang (Go) bindings for GNU's gettext (http://www.gnu.org/software/gettext/)

gosexy/gettext Go bindings for GNU gettext, an internationalization and localization library for writing multilingual systems. Requeriments GNU gettex

Go toolbelt 61 Jun 6, 2022
🏠 An HTTP-based command runner for home automation.

Badges Reporting Issues If you are facing a problem with this package or found any bug, please open an issue on GitHub. License The MIT License (MIT).

Homettp 27 Apr 11, 2022
Terraform provider to help with various AWS automation tasks (mostly all that stuff we cannot accomplish with the official AWS terraform provider)

terraform-provider-awsutils Terraform provider for performing various tasks that cannot be performed with the official AWS Terraform Provider from Has

Cloud Posse 22 Aug 26, 2022
Build system and task runner for Go projects

Gilbert is task runner that aims to provide declarative way to define and run tasks like in other projects like Gradle, Maven and etc.

Gilbert 104 Sep 26, 2022
Go based task runner

Grift Grift is a very simple library that allows you to write simple "task" scripts in Go and run them by name without having to write big main type o

Mark Bates 414 Sep 21, 2022
Act is a task runner and supervisor with some great features like act name matching, subacts, etc. We use this in nosebit workspaces.

Act Act is a task runner and supervisor tool written in Go which aims to provide the following features: process supervision in a project level allow

Nosebit 6 May 8, 2022
A cross-platform task runner for executing commands and generating files from templates

Orbit A cross-platform task runner for executing commands and generating files from templates Orbit started with the need to find a cross-platform alt

Julien Neuhart 172 Sep 27, 2022