Targets
A target identifies the result of a task. It is declared using the target
keyword and can be part of a task description.
There are three types of targets:
- file
- directory
- docker image
Targets live inside a repository and are usually in your .gitignore
. It's good practice to gather targets in a build
directory, but it's not rquired. Bob does not allow to define filesystem targets outside of the repository you're currently working on. Something like ../
is not allowed.
Targets are archived on your local machine at ~/.bobcache/artifacts
which is referred to as the cache.
Each time you see a task finishing with the status cached
,
โ โ โ โ
Ran 1 tasks in 0s
build cached
you can be sure your targets are up-to-date and no rebuild was necessary.
Bob decides if a target needs a rebuild by computing a hash of the tasks inputs and additionally considering the task description itself. The integrity of the target is also considered by looking at its checksum.
This enables bob to reuse targets when switching back and forth between branches. Additionally, with the upcoming remote caching options you can greatly speed up CI builds saving valuable time and computing power.
File Targets
Bellow we have a Bobfile where the build
task is running the command go build -o hello
.
This command is compiling the code of main.go
and creating an executable with the name hello
which is made available to bob declaring it using the target
keyword.
# app/bob.yaml
dependencies: [ go ]
build:
build:
input: main.go
cmd: go build -o hello
target: hello
If you specify a different name than the one of the file being created you will get a Target does not exist for task [build].
error.
If you want to run the above Bobfile you need to have main.go
and the go.mod
file in your working directory:
// app/bob.yaml
package main
import "fmt"
func main() {
fmt.Println("Hello World!")
}
// app/go.mod
module example/hello
go 1.19
After running bob build
you will notice a hello
executable in your directory:
$ ls
bob.yaml go.mod hello main.go
Try to run rm hello
and bob build
again and see that build is marked as cached:
$ rm hello
$ bob build
Building nix dependencies...
Succeeded building nix dependencies
Running task build with 0 dependencies
โ โ โ โ
Ran 1 tasks in 0s
build cached
After running those commands the hello
binary is back in the working directory. It was fetched from the cache.
Directory Targets
Here's an example with a build command that creates a new directory called hello
build:
build:
cmd: mkdir hello && touch ./hello/some-file
target: hello
The same rules apply to directory targets as the one from file targets with one caveat: empty directories, as opposed to empty files, will not be cached in the artifact store.
This means that having a build
task creating an empty directory the directory will not be recreated from the cache next time you run bob build
:
build:
build:
cmd: mkdir hello
target: hello
Mixing File and Directory Targets
If you have a task which is creating both files and directories you can define the targets in a multiline format using |-
:
build:
build:
cmd: touch hello && mkdir hello-dir && touch ./hello-dir/some-file
target: |-
hello
hello-dir/
Docker Image Targets
If you have Docker running and a Dockerfile
in your current working directory you can build a Docker image and specify it as a target
as well:
dependencies: [ docker ]
build:
build:
cmd: docker build -t my-image:latest .
target:
image: my-image:latest
To have a target image
you need to specify the full name:tag
format.
Shallow Target Validation
For local performance optimization the size of the target is used for validation. We call this "shallow target validation". Bob assures that shallow targets never reach an artifact store.