Using Workspaces
Workspaces #
Workspaces allow jobs within a build to share files. They are useful when you want to use build artifacts from a previous job; for example, you create a cache that can be used in multiple jobs later.
So you can clearly see when a workspace is created and used, we recommend using workspaces with build stages, as shown in the following examples.
Note that it is best to create a workspace in one stage and then use it in subsequent stages.
Configuration #
A minimal workspace configuration looks like this:
jobs:
include:
- stage: warm_cache
script:
- echo "foo" > foo.txt
workspaces:
create:
name: ws1
paths:
- foo.txt
- stage: use_cache
workspaces:
use: ws1
script:
- cat foo.txt || true
Each workspace has a unique name within a build.
It is specified by the name
key when it is created with
workspaces.create
, and by the value when it is used with
workspaces.use
.
In the example above, the workspace named ws1
is created by the only
job in the warm_cache
stage.
The workspace is subsequently consumed in the use_cache
stage.
Workspace examples #
Multiple workspaces example #
You can use multiple workspaces in a build.
script:
- ./build $TRAVIS_OS_NAME
jobs:
include:
- stage: Build binaries
os: linux
workspaces:
create:
name: linux-binaries
- os: osx
workspaces:
create:
name: osx-binaries
- stage: Deploy
language: minimal
workspaces:
use:
- linux-binaries
- osx-binaries
git:
clone: false
script:
- ./create_archive.sh
deploy:
provider: script
script: ./upload.sh
In this example:
- we run two jobs in the “Build binaries” stage, each producing uploading binaries.
- in the subsequent “Deploy” stage, we fetch the workspaces produced by the jobs in the previous stage, and deploy it using a custom script.
A more explicit example below:
jobs:
include:
- stage: Build and Test
name: "Job A"
script:
- echo "Building Job A"
- echo "Running tests for Job A"
- mkdir -p workspace-a
- echo "This is data from Job A" > workspace-a/data-A.txt
workspaces:
create:
name: workspace-a
paths:
- workspace-a
- name: "Job B"
script:
- echo "Building Job B"
- echo "Running tests for Job B"
- mkdir -p workspace-b
- echo "This is data from Job B" > workspace-b/data-B.txt
workspaces:
create:
name: workspace-b
paths:
- workspace-b
- name: "Job C"
script:
- echo "Building Job C"
- echo "Running tests for Job C"
- mkdir -p workspace-c
- echo "This is data from Job C" > workspace-c/data-C.txt
workspaces:
create:
name: workspace-c
paths:
- workspace-c
- stage: Deploy
name: "Deploy"
script:
- echo "Deploying using artifacts from Job A Job B and Job C"
- cat workspace-a/data-A.txt
- cat workspace-b/data-B.txt
- cat workspace-c/data-C.txt
workspaces:
use:
- workspace-a
- workspace-b
- workspace-c
In above example:
- Build stage “Build and Test” consists of 3 jobs, each of them producing output to a separate workspace
- Build stage “Deploy” consists of one job, which
- Marks usage of all 3 previosuly created workspaces
- pulls data out of each previously created workspace and echoes it to standard output to demonstrate ability to access workspace
Workspaces and concurrency #
Note that workspaces work best if there is no race condition set while uploading them. Since there is no guarantee in the execution order of jobs within a build stage, it is a good idea to assign different workspace names to jobs within a build stage.
Workspace names must be pre-determined #
Due to technical reasons, workspace names will be escaped for shell. In other words, given:
workspaces:
create:
name: $TRAVIS_OS_NAME
paths: …
it will have to be consumed by
workspaces:
use: $TRAVIS_OS_NAME
and not by
workspaces:
use: linux
even if the consumer is running on a Linux VM.
How workspaces differ from caches #
It is worth reiterating that the workspaces are meant for sharing files within the same build. For files you want to share across builds, use caches.
Workspaces and caches are considered independently #
It is possible to include a single file in the cache and workspaces.
If you restart some builds within a job, and your workspace isn’t working like you expect it to, try restarting the the entire build.