Build your local git repository on a remote server
GRUB synchronizes your local repository (including uncommitted changes) to a remote server and runs a build command there:
- Creates a patch file of all local changes (staged, unstaged, and untracked files)
- Pushes committed changes via git
- Transfers the patch file to the server
- Applies the patch on the server
- Runs your build command
- Downloads build output and errors
Your local git working directory is never modified.
Recommended (one-line install):
curl -fsSL https://raw.githubusercontent.com/andrewhughes101/grub/main/install.sh | bashOr with wget:
wget -qO- https://raw.githubusercontent.com/andrewhughes101/grub/main/install.sh | bashThen add to your shell profile (~/.bashrc, ~/.zshrc, etc.):
export PATH="$HOME/.grub/bin:$PATH"Alternative - Manual Installation:
# Download latest release
wget https://github.com/andrewhughes101/grub/releases/latest/download/grub-*.tar.gz
tar -xzf grub-*.tar.gz
export PATH="$PWD/grub/bin:$PATH"Alternative - Clone from source:
cd ~/tools
git clone git@github.com:andrewhughes101/grub.git
export PATH="$HOME/tools/grub/bin:$PATH"Configure SSH with public/private key authentication. Either use ~/.ssh/config:
Host myserver
HostName server.example.com
User myusername
Or define connection details in a host_vars file (see Inventory Support below) — no ~/.ssh/config entry required when ansible_host and ansible_user are set.
cd /path/to/your/repo
grub_client <server> [build_command]Example:
grub_client myserver ./buildWith custom repo path:
grub_client --repo-path ~/projects/myapp myserver makePress Cmd-Shift-P → "Preferences: Open User Settings (JSON)" and add:
{
"grub.server": "myserver",
"grub.client_build_tool": "/Users/you/tools/grub/bin/grub_client",
"grub.server_root": "/u/user/projects",
"grub.git_dir": "/opt/git/bin"
}grub.server_root and grub.git_dir are optional — omit them to use the defaults (~/dev and auto-detected platform path respectively).
Press Cmd-Shift-P → "Tasks: Open User Tasks" and add:
{
"version": "2.0.0",
"tasks": [
{
"label": "GRUB Build",
"type": "shell",
"command": "${config:grub.client_build_tool}",
"args": [
"--repo-path", "${workspaceFolder}",
"--server-root", "${config:grub.server_root}",
"--git-dir", "${config:grub.git_dir}",
"${config:grub.server}"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}Remove --server-root and --git-dir lines from args if you are not setting those in your VSCode settings.
Press Cmd-Shift-B to run the build. Output streams in real-time to the terminal.
grub_client [options] <server> [build_command]
Options:
-v, --verbose Verbose output
-o, --output Print stdout/stderr from downloaded files
-h, --help Show help
--version Show version
--repo-path <path> Repository path (default: current directory)
--server-root <path> Remote root directory (default: ~/dev)
--git-dir <path> Git directory on server (default: auto-detect)
-i, --inventory <file> Ansible inventory YAML file
-e, --extra-vars <file> YAML file of variables to export as env vars during build
--no-multiplex Disable OpenSSH connection multiplexing (ControlMaster)
--clear-cache <server> Clear cached git directory and multiplex socket for server
Arguments:
server SSH host name (must match ~/.ssh/config Host or inventory host name)
build_command Command to run (default: ./build)
You can pass environment variables to your remote build in multiple ways:
Variables specified directly in the build command have the highest precedence:
grub_client myserver TEST=21 ./build
# or with multiple variables
grub_client myserver "FOO=bar BAZ=qux ./build"When unquoted or in double quotes, your local shell expands $VAR before passing it to GRUB. GRUB safely quotes the value across SSH so special characters and spaces are preserved:
grub_client myserver RELEASE_TAG=$VERSION ./build
# or
grub_client myserver "API_KEY=$MY_LOCAL_TOKEN make test"When single-quoted, the literal variable reference is sent over SSH and evaluated on the remote server environment at runtime:
grub_client myserver 'PATH=$PATH:/opt/ibm/bin ./build'For passing multiple variables without command-line escaping, use a flat YAML file (see Extra Vars below).
When the same environment variable is defined in multiple places for a build, the following precedence applies (highest to lowest):
- Inline Command-Line Overrides (e.g.
grub_client myserver TEST=21 ./build) — takes precedence over everything - Extra Vars File (
-e/--extra-vars <file>) — exported into the build subshell environment - Remote Server Environment — existing environment variables on the remote system
GRUB can read host configuration from Ansible-compatible YAML files. This lets you share a single inventory between GRUB (local builds) and Ansible (CI/CD).
Place a file named after your server in a host_vars/ directory in your project:
# host_vars/myzos.yml
ansible_host: zos.example.com
ansible_user: myuser
# ansible_ssh_private_key_file: ~/.ssh/id_zos # optional
grub_server_root: /u/myuser/projects
grub_git_dir: /usr/lpp/IBM/foz/v1r1/bingrub_client myzos # picks up host_vars/myzos.yml automaticallyUse an existing Ansible inventory that covers multiple hosts:
# inventory.yml
all:
hosts:
myzos:
ansible_host: zos.example.com
ansible_user: myuser
grub_server_root: /u/myuser/projects
grub_git_dir: /usr/lpp/IBM/foz/v1r1/bin
mylinux:
ansible_host: linux.example.com
ansible_user: devusergrub_client -i ~/ansible/inventory.yml myzos
# or
grub_client --inventory ~/ansible/inventory.yml myzos| Variable | Equivalent to |
|---|---|
ansible_host |
SSH HostName |
ansible_user |
SSH User |
ansible_ssh_private_key_file |
SSH IdentityFile |
ansible_port |
SSH Port |
ansible_ssh_common_args |
Extra SSH options (e.g. -o ProxyJump=...) |
grub_ssh_multiplex |
Set to false to disable ControlMaster |
grub_server_root |
--server-root |
grub_git_dir |
--git-dir |
Configuration settings are resolved in the following priority order (highest to lowest):
- CLI Arguments (
--server-root,--git-dir,--no-multiplex) - Inventory / host_vars (
-i <file>orhost_vars/<server>.yml) - Cached Git Config (
~/.gitconfigcachedgit_dirfrom prior auto-detection) - SSH Config (
~/.ssh/configfallback for hostname, user, identity, port) - Built-in Defaults (
server_root="~/dev", auto-detectedgit_dir,build_command="./build")
See sample/inventory.yml and sample/host_vars/myzos.yml for templates.
Pass a flat YAML file of key/value pairs to the remote build as environment variables:
grub_client -e build_vars.yml myserver# build_vars.yml
MY_API_KEY: s3cr3t
BUILD_FLAGS: --releaseVariables are exported into the build command's environment only. They are:
- Not visible client-side — processed locally and transferred as a temp file
- Not stored in the repo — the file is deleted from the remote immediately after sourcing
- Not applied during patch — only active when your build script runs
Keys must be valid shell identifiers (letters, digits, underscores; must not start with a digit). Flat key/value pairs are recommended; if nested mappings are provided, line-by-line parsing flattens child keys directly while parent mapping keys receive empty values.
See sample/build_vars.yml for a template.
- server_root:
~/dev(expands to remote user's home directory) - git_dir: Auto-detected based on platform
- z/OS:
/usr/lpp/IBM/foz/v1r1/bin - Other:
/usr/bin
- z/OS:
- build_command:
./build
TMPDIR: Temporary directory for local and remote files (default:/tmp)
- Git installed locally and on server
- SSH with key-based authentication