User build with customizable tasks
User build v2 is a new build framework introduced in Z Open Editor 6.7.0 that gives you full control over how your z/OS® applications are built from inside VS Code. Unlike the original user build (referred to here as user build v1), which runs a fixed workflow tied to IBM® Dependency Based Build (DBB), user build v2 lets you create a build pipeline from a set of individually configurable tasks. Each task can run built-in behavior, run a local script, or invoke a remote command on z/OS. This flexibility enhances the DBB experience and also supports other build frameworks and custom scripts. This makes user build v2 suitable for COBOL, PL/I, HLASM, C++, and any other language whose source code lives in a Git repository and must be built on z/OS.
This feature is in its first release and is expected to evolve and stabilize over time. User build v1 continues to work unchanged, and both versions can be used independently. Profiles for each can coexist in the same zapp.yaml file.
Overview
User build v2 addresses several limitations of user build v1:
- Customizable workflows: The build pipeline is no longer a single hard-coded sequence. You define the tasks that you need: upload, build, fetch logs, deploy. Omit tasks that are not required.
- Language agnostic: Because the build command is user-defined, you can build any language that your z/OS system supports, not just COBOL, PL/I, and HLASM.
- Git-based file synchronization: Through the included Git remote user build (GRUB) scripts, you can push only changed files to z/OS by using Git instead of uploading every dependency for each build.
- Post-build automation: Custom tasks let you run deployment or test steps immediately after a successful build, all from within VS Code.
User build v2 profiles use the userbuild type in zapp.yaml. User build v1 profiles use the dbb type. Both types appear in the same profile picker when you run a build, and Z Open Editor uses the correct execution engine for each.
Prerequisites
For all user build v2 profiles
The prerequisites for user build v2 are the same as for user build v1:
- Z Open Editor 6.7.0 or later is installed and configured.
- A
zapp.yamlorzapp.jsonfile exists in your VS Code workspace root folder with auserbuildtype profile. - If you are using Zowe™ commands, Zowe team configuration profiles are created using Zowe Explorer, as described in Connecting to z/OS with Zowe Explorer.
- The Zowe profile to use for user build is selected in the VS Code status bar.
- The
dbbWorkspaceuser setting is configured. See Specifying user build user settings and variables for details about all available user settings. These settings are shared between user build v1 and v2. - The directory specified for the
dbbWorkspaceuser setting must exist on z/OS UNIX System Services. - To use User Build with other languages than COBOL, PL/I, HLASM you must change the user setting
zopeneditor.userbuild.alwaysShowCommandstotrue. - EBCDIC encoding is configured in
.gitattributesfor your repository. See Character conversion using .gitattributes for details.
Additional prerequisites for GRUB with SSH mode
GRUB scripts support only RSE API Zowe Profiles or native SSH connections. z/OSMF profiles are not supported.
- Git 2.0 or later is installed on your local machine and available in
PATH. - Password-less SSH to z/OS is configured (key-based authentication, SSH agent integration or no passphrase prompt).
- Git for z/OS is installed on the z/OS system.
- The SSH server is running on z/OS.
Additional prerequisites for GRUB with RSE API mode
- RSE API server 1.2.5.2 on z/OS. Versions before this release will work, but file uploads will be significant slower when running a GRUB build.
- Git 2.0 or later is installed on your local machine and available in
PATH. - Zowe CLI is installed with the RSE API plug-in.
- An RSE API profile is configured and a valid connection can be established.
- Git for z/OS is installed on the z/OS system, provided by either IBM Open Enterprise Foundation for z/OS or zopen community.
- The RSE API service is running on z/OS.
Windows prerequisite
- Git for Windows is installed. The bash shell bundled with Git for Windows is used to run
localCommandscripts. If your Git for Windows installation is not at the default location (C:\Program Files\Git), set thezopeneditor.scripts.bashHomeVS Code user setting to point tobash.exein your installation.
Tasks in user build v2
A user build v2 profile is defined by a list of tasks. Tasks run sequentially. If a task fails, subsequent tasks are skipped, except for the results task, which always runs so that log files are fetched.
Each task is identified by its type, which also determines its default behavior when you do not provide a command. Learn more about commands in Executing Commands. With these commands, you can override the default behavior. For example, the dependencies task uses the language server by default to determine which include files are required to build a program. If you are building a language that is not supported by a Z Open Editor language server, run custom scripts to identify dependencies that require upload.
You specify exactly one task type per entry in the task list, and you can include the same type more than once, for example, two build tasks that compile different targets. See examples of tasks in the Use Cases section.
The following task types are available:
| Task type | What is does | Default behavior | Customization example |
|---|---|---|---|
prerequisites | Perform checks to ensure the user build can run. | Checks required settings (such as dbbWorkspace) and tests the default Zowe profile connection. | Run the GRUB prerequisites command. |
dependencies | Collects include files required to build the program. | Uses the language servers to resolve build file dependencies (COBOL, PL/I, and HLASM only). | Run a script that searches for include statements. |
upload | Uploads all collected dependencies found by the dependencies task to z/OS UNIX System Services. | Uses the Zowe profile. | GRUB push or bundle command. |
build | Perform the build operation. | None. A command is required. | Run the DBB command with parameters. |
results | Download log files or deploy builds. | Downloads log files matching *.log from dbbWorkspace or all files that match logFilePatterns. | Script that fetches file and/or deploys results. |
post | Runs a command if build and results tasks succeeds without error. | None. A command is required. | Run a Wazi Deploy command. |
custom | A generic task for adding any custom command to the workflow. | None. A command is required. | Run a test script after the build. |
Note: If your profile defines a dependencies task but no upload task, Z Open Editor automatically runs the default upload behavior after dependencies are collected.
Task properties
Every task type accepts the following common properties for running commands:
| Property | Description |
|---|---|
localCommand | A command that runs on your local machine. The working directory is the VS Code workspace that contains the zapp.yaml file. If the first token of the command resolves to a file that exists on disk, bash runs it directly. Otherwise, bash is invoked with -c and the full string. |
remoteCommand | A command that runs on z/OS UNIX System Services in the directory specified by the dbbWorkspace user setting by using the current Zowe profile. |
remoteCommandShell | Same as remoteCommand, but uses a full login shell so that environment variables in your .profile are available. This form is recommended when build scripts depend on environment variables such as DBB_HOME. |
In addition to the common properties, three task types accept specific properties:
dependencies task:
| Property | Description |
|---|---|
additionalDependencies | A list of files and folders, relative to the workspace, to include in the upload. Supports GLOB patterns. |
dependenciesFiles | A list of text files, each containing a newline-separated list of file and folder paths to include. These files can be generated by a localCommand. |
upload task:
| Property | Description |
|---|---|
dependenciesUpload | Set to false to skip the built-in Zowe upload and rely solely on a localCommand for file transfer. The default value is true. |
results task:
| Property | Description |
|---|---|
logFilePatterns | A list of GLOB patterns for files to download from dbbWorkspace to the local log directory. If omitted, the default pattern is *.log. |
Executing commands
Local commands
The localCommand property runs a bash command on your local machine. Z Open Editor provides GRUB scripts in the .zopeneditor folder of your workspace automatically when a userbuild profile is selected. You can reference these scripts by their relative path, as in:
localCommand: >
.zopeneditor/grub_client gitBundle --zoweProfile ${defaultZoweProfile}
--remoteWorkspace ${dbbWorkspace} --verbose
Any executable available in your system PATH can also be used directly without a path prefix:
localCommand: >
bash -c "collect-headers.sh > headers.txt"
On Windows, Z Open Editor uses the bash executable bundled with Git for Windows (C:\Program Files\Git\usr\bin\bash.exe by default). To use a different bash installation, set the zopeneditor.scripts.bashHome VS Code user setting to the absolute path of the preferred bash executable. On Linux and macOS, the bash found in PATH is used by default and can be overridden with the same setting.
Remote commands
The remoteCommand and remoteCommandShell properties run a command on z/OS UNIX System Services using the Zowe profile that is currently active for user build. If you use Zowe with z/OSMF, configure and specify a Zowe profile of type ssh in addition to the z/OSMF profile. If you use Zowe with RSE API, a profile of type rse is sufficient because user build uses the RSE API command facility. If you prefer not to use a Zowe profile and want to use SSH directly to interact with z/OS, use a localCommand. As another option, use the grub_client execute command described in the GRUB Scripts reference.
The command runs in the directory specified by the dbbWorkspace user setting. If you prefer to use SSH directly instead of a Zowe profile, use a localCommand with the grub_client execute command described in the GRUB Scripts reference.
Use remoteCommandShell when a command depends on environment variables that are set in .profile or .bashrc:
build:
remoteCommandShell: >
$DBB_HOME/bin/dbb build user --hlq ${dbbHlq} --errPrefix ${errPrefix}
${currentProgram}
Use remoteCommand for commands that supply their own environment inline:
build:
remoteCommand: >
"CC=clang CXX=clang++ CMAKE_BUILD_PARALLEL_LEVEL=8 && cd
${dbbWorkspace}/myApp && cmake --build . --target install 2>&1 | tee build.log"
ZAPP variables in commands
All command properties support the same ZAPP variable substitution that is available in user build v1. Variables are substituted automatically before the command runs. The following built-in variables are available:
| Variable | Description | Example value |
|---|---|---|
${dbbWorkspace} | Remote UNIX System Services workspace path (from user settings) | /u/ibmuser/projects |
${workspace} | Absolute path to the VS Code workspace in the which the ZAPP file resides | C:/Users/ibmuser/projects/project1 |
${application} | The name of the workspace folder that contains the active build file. This name is also used for the folder created inside dbbWorkspace when uploading the build file and its dependencies. | zopeneditor-sample |
${dbbHlq} | TSO high-level qualifier (from user settings) | IBMUSER.SAMPLE |
${dbbLogDir} | Remote log directory (from user settings) | /u/ibmuser/projects/logs |
${defaultZoweProfile} | Name of the Zowe profile currently active for user build, as selected in the status bar | my-rse-profile |
${currentProgram} | Full remote path to the program to be built | /u/ibmuser/projects/sam/COBOL/SAM1.cbl |
${dependencies} | Space-separated list of dependency paths collected by the dependencies task | /u/ibmuser/projects/dbb-app.yaml /u/ibmuser/projects/resources |
${dependencyFile} | Reference to a special DBB dependency file generated by the language server. See DBB documentation for details. | Will be computed at build time. |
${errPrefix} | Unique qualifier generated for each build run and used for the Problems view data set | U9709142 |
${buildFile} | Build file name with extension | SAM1.cbl |
${buildFile.basename} | Build file name without extension | SAM1 |
${buildFile.extension} | Build file extension | .cbl |
${buildFile.workspaceDir} | Directory of the build file relative to the workspace | COBOL |
${javaHome} | Absolute path to the JAVA Home location of the language server. Can be used to call Java programs such as preprocessors. | C:\Program Files\Semeru\jdk-25.0.3.9-openj9\ |
You can also define your own variables by using the ZAPP variables feature and reference them with the same ${variable-name} syntax. Several examples of these are provided in the Use Cases.
GRUB scripts
Why use the scripts
GRUB (Git Remote User Build) is a set of bash scripts that Z Open Editor provides with user build v2. They provide a Git-based alternative to the built-in Zowe file upload for synchronizing your workspace with z/OS before a build.
The key advantage of GRUB over Zowe upload is efficiency. Instead of uploading every dependency file one by one on each build, GRUB provides two alternatives that transfer only changed files and compress those changes:
- It creates a Git bundle that contains only the changes since the last push and transfers that bundle to the remote repository on z/OS. This solution can be used with an RSE API upload command and requires no password-less SSH access to z/OS. It also supports password-less SSH. z/OSMF profiles are not supported.
- It uses a Git push operation over SSH. This solution is the most efficient because it requires no Git bundle generation and can push changes directly from your local machine to z/OS when password-less SSH is configured.
Both approaches scale well for large applications with many files and work for any programming language.
GRUB script deployment
GRUB is automatically deployed to the .zopeneditor folder in your workspace the first time that you run a user build using the userbuild profile. You can add these files to .gitignore or check them into your repository for use from the command line and for customization. Another reason that they are generated in the workspace is that AI agents, such as IBM Bob™, can access them and use them to run commands. (Note: These files are not open source and are covered by IBM product licenses. Customized GRUB script are also not covered by technical support.)
The .zopeneditor folder contains a README file and two scripts:
grub_client: The client-side script that you invoke fromlocalCommandentries in your ZAPP profile.grub_server: The server-side helper thatgrub_clientuploads and runs on z/OS.
GRUB supports two transport modes:
- SSH mode: Uses
git pushover SSH to transfer changes. Requires password-less SSH to z/OS and Git installed on both sides. Use the--hostnameparameter. - RSE API mode: Uses Zowe CLI with the RSE API plug-in to upload Git bundle files. Requires no SHH. Use the
--zoweProfileparameter. z/OSMF profiles are not supported.
GRUB commands
The six GRUB commands map directly to stages of the user build pipeline:
| Command | What it does | Use in task type |
|---|---|---|
prerequisites | Checks that Git, SSH or Zowe CLI, and the remote workspace are available | prerequisites |
gitPush | Creates a temporary commit and pushes all changes through SSH | upload |
gitBundle | Creates a delta bundle and transfers it through SSH or RSE API | upload |
upload | Uploads individual files and folders that are not in the Git repository | upload |
execute | Runs a command on z/OS in the remote workspace | build, results, post |
fetch | Downloads files from z/OS to your local workspace | results |
For complete command syntax and options, see GRUB Scripts - Git Remote User Build.
How it works
For the gitPush and gitBundle commands, GRUB takes all current staged and unstaged Git changes and creates a temporary commit. It then either pushes the commit or generates a bundle with it. After the push or the bundle upload completes, the script reverts the temporary commit and restores all changes as staged changes in your workspace.
When you run these commands for the first time, the script pushes the entire repository to z/OS UNIX System Services or creates a bundle that contains the entire repository. This approach is flexible because it enables repository transfer without additional setup beyond having Git available on z/OS.However, it is not the most efficient method for creating a large Git repository on z/OS UNIX System Services. If you use a Git management platform such as GitHub or GitLab, the GRUB commands also support cloning the repository for the initial build.
Use cases
The following use cases use profiles from the Z Open Editor sample repository. Each profile is self-contained. Copy the relevant profile into your own zapp.yaml and adjust the variables to match your environment.
Use case 1: DBB build with Zowe upload
This use case is the closest equivalent to user build v1. Z Open Editor collects the program's include files and any files listed under additionalDependencies, uploads them to z/OS by using the active Zowe profile, and then runs a DBB zBuilder build command on z/OS.
- name: zowe-upload-userbuild2
type: userbuild
settings:
tasks:
- dependencies:
additionalDependencies:
- dbb-app.yaml
- build:
remoteCommandShell: >
$DBB_HOME/bin/dbb build user --hlq ${dbbHlq} --errPrefix ${errPrefix}
${currentProgram}
- results:
logFilePatterns:
- "${application}/logs/*.log"
- "${application}/logs/*.json"
- "${application}/logs/BuildReport.html"
How it works:
- The
dependenciestask collects the program's include files (copybooks, include files, or macros) and the DBB zBuilder configuration filedbb-app.yamlthat is listed underadditionalDependencies. - Because no
uploadtask is defined, Z Open Editor automatically uploads all collected dependencies todbbWorkspaceon z/OS using the default Zowe profile. - The
buildtask runs the DBB zBuilder command on z/OS in a login shell, enabling the use of environment variables defined in.profile, includingDBB_HOME. The command-line variable${dbbHlq}is defined through the user settings. - The
resultstask downloads the log and report files that match the specified patterns from the${application}/logsdirectory underdbbWorkspace.
Note: To enable compiler errors in the VS Code Problems view, include --errPrefix ${errPrefix} in the build command, as shown. See Advanced problems view integration for information about how this feature works.
Use case 2: DBB build with GRUB and Zowe (RSE API)
This profile replaces the Zowe file upload with GRUB's Git-based synchronization, which transfers only changed files. It uses the RSE API transport mode (no SSH required) and is well suited for teams that already use Zowe Explorer with an RSE API profile.
- name: grub-zowe-userbuild2
type: userbuild
settings:
tasks:
- upload:
localCommand: >
.zopeneditor/grub_client gitBundle --zoweProfile ${defaultZoweProfile}
--remoteWorkspace ${dbbWorkspace} --verbose
- build:
localCommand: >
.zopeneditor/grub_client execute --zoweProfile ${defaultZoweProfile}
--remoteWorkspace ${dbbWorkspace}/${application}
--command "$DBB_HOME/bin/dbb build user --hlq ${dbbHlq}
--errPrefix ${errPrefix} ${currentProgram}" --verbose
- results:
logFilePatterns:
- "${application}/logs/*.log"
- "${application}/logs/*.json"
- "${application}/logs/BuildReport.html"
How it works:
- The
uploadtask runsgrub_client gitBundlelocally. GRUB creates a temporary commit of all workspace changes, bundles only the delta since the last push, and uploads and applies that bundle to the Git repository on z/OS by using the active Zowe RSE API profile. Files outside the Git repository are not transferred during this step. Add a separate GRUBuploadcommand or adependenciestask for those files. The${defaultZoweProfile}is one of the predefined variables and evaluates to the value of the default Zowe profile displayed in the status bar. - The
buildtask runsgrub_client executelocally, which uses the Zowe profile to run the DBB command on z/OS in the application subdirectory ofdbbWorkspace. The variable${currentProgram}is automatically evaluated to the currently open program in the editor from which you executed the build command. - The
resultstask downloads log and report files as described in use case 1.
Note: This profile skips the dependencies task, so include files are not uploaded by Z Open Editor. GRUB transfers them as part of the Git repository. Ensure that all relevant source files, copybooks, and include files are tracked by Git.
Use case 3: DBB build with GRUB and SSH (git push)
This profile uses SSH and git push for fast file transfer. It is suited for teams with password-less SSH configured for z/OS and is the recommended approach when SSH is available. Define the ZAPP variables HLQ, ZOSHOST, DBB_HOME, and DBB_BUILD in the user settings before using this profile.
- name: grub-ssh-userbuild2
type: userbuild
settings:
tasks:
- prerequisites:
localCommand: >
.zopeneditor/grub_client prerequisites --hostname ${HLQ}@${ZOSHOST}
--remoteWorkspace ${dbbWorkspace} --verbose
- upload:
dependenciesUpload: false
localCommand: >
.zopeneditor/grub_client gitPush --hostname ${HLQ}@${ZOSHOST}
--remoteWorkspace ${dbbWorkspace} --verbose
- build:
localCommand: >
.zopeneditor/grub_client execute --hostname ${HLQ}@${ZOSHOST}
--remoteWorkspace ${dbbWorkspace}/${application}
--command "DBB_HOME=${DBB_HOME} DBB_BUILD=${DBB_BUILD}
$DBB_HOME/bin/dbb build user --hlq ${dbbHlq}
--errPrefix ${errPrefix} ${currentProgram}" --verbose
- results:
logFilePatterns:
- "${application}/logs/*.log"
- "${application}/logs/*.json"
- "${application}/logs/BuildReport.html"
How it works:
- The explicit
prerequisitestask runsgrub_client prerequisitesto verify that Git, SSH connectivity, and the remote workspace path are available before the build starts. By using ZAPP variables for the--hostnameparameter value, you can make the ZAPP file portable and share it among users who use different accounts and z/OS development systems. - The
uploadtask runsgrub_client gitPushto push all workspace changes to the z/OS Git repository over SSH. SettingdependenciesUpload: falsesuppresses the built-in Zowe upload so that GRUB is the only file transfer mechanism. - The
buildtask supplies the required environment variables (DBB_HOME,DBB_BUILD) inline in the command string by using the values of your custom ZAPP variables, and runs the DBB build by usinggrub_client executeover SSH. This approach also enables you to use the same ZAPP file across multiple z/OS systems where DBB might be installed in different locations. If these locations are standardized, you can hard-code the values in the command instead of using variables. Alternatively, you can define these variables in the workspace settings and share the values with the team through that file by using Git. - The
resultstask downloads log and report files as described in the previous use cases.
Tip: Because SSH runs without the login shell environment, specify the required environment variables inline in the command string, as shown, or source them from a profile file by using . ~/.profile && at the beginning of the command.
Use case 4: C++ build with GRUB and Zowe (RSE API)
This profile demonstrates user build v2 with a language that is not supported by a Z Open Editor language server. It builds a C++ application on z/OS by using make, with GRUB handling file synchronization. Use this profile with the CPP/ccnubrc.C sample file.
- name: grub-cpp-zowe-userbuild2
type: userbuild
settings:
tasks:
- upload:
localCommand: >
.zopeneditor/grub_client gitBundle --zoweProfile ${defaultZoweProfile}
--remoteWorkspace ${dbbWorkspace} --verbose
- build:
localCommand: >
.zopeneditor/grub_client execute --zoweProfile ${defaultZoweProfile}
--remoteWorkspace ${dbbWorkspace}/${application}/CPP
--command "make > build.log 2>&1" --verbose
- results:
logFilePatterns:
- "${application}/CPP/*.log"
- post:
localCommand: >
.zopeneditor/grub_client execute --zoweProfile ${defaultZoweProfile}
--remoteWorkspace ${dbbWorkspace}/${application}/CPP
--command "./bio 1970/01/01" --verbose
How it works:
- The
uploadtask usesgrub_client gitBundleto push the C++ source changes to z/OS by using RSE API transport. - The
buildtask runsmakein theCPPsubdirectory on z/OS and redirects output tobuild.log. - The
resultstask downloads thebuild.logfile to the local workspace. - The
posttask runs the compiled program (bio) on z/OS after a successful build. Theposttask is skipped if thebuildtask fails.
Running a user build v2
After the zapp.yaml is configured and all prerequisites are in place, open the program to build in Z Open Editor and start a build by using one of the following commands:
- Run IBM User Build with full upload: Uploads all dependencies, regardless of whether they have changed since the previous build. Use this option for the first build or after significant changes to the dependency set.
- Run IBM User Build: Uploads only dependencies that have changed since the previous build. Use this option for subsequent builds to reduce upload time.
Right-click in the editor and select one of these commands from the context menu, or open the Command Palette (Ctrl+Shift+P on Windows, Cmd+Shift+P on Mac) and type IBM User Build.
If the zapp.yaml file contains more than one profile of type dbb or userbuild, Z Open Editor presents a profile picker. The most recently used profile appears first. User build v1 profiles are marked with (user build v1) to distinguish them from user build v2 profiles.
Z Open Editor reports build progress in a notification at the lower-right corner of the window and displays the name of the current task. Build output is streamed to the IBM User Build output channel. To view the output, click View > Output and select IBM User Build from the list.