CLI

Etlworks client

The etlworks command keeps flows, connections, formats, macros and schedules in Git and deploys them from your laptop or a CI pipeline. Export a project to a folder, review a plan of what will change, apply it. The client only moves commands and files; all the work runs on the Etlworks server, under the permissions of the API key you sign in with. To deploy straight from a Git repository, run code from Git, or deploy on push, see Git in Etlworks. The full guide is Data Integration as Code in the support center.

Install

Requirements: Java 17 or later (from JAVA_HOME or the PATH) and an Etlworks instance on release 10.1.0 or later, Cloud or on-prem.

  1. Download the client (one zip for macOS, Linux and Windows). Check it against the SHA-256 checksum. A specific release: /installers/download/client?version=10.1.0.
  2. Unzip it anywhere and add the folder to your PATH. On Windows, the command is etlworks.cmd.
  3. Run etlworks version. The launcher tells you if Java 17 or later is missing.
Shell
curl -fsSL -o etlworks-client.zip https://etlworks.com/installers/download/client
unzip -q etlworks-client.zip -d ~/tools
export PATH="$(ls -d ~/tools/etlworks-client-* | tail -1):$PATH"
etlworks version

Sign in

The client signs in with an Etlworks API key. Create one in Etlworks under Preferences → Security (your user menu); an admin can create one for another user under Settings → Users. The client acts with that user's role and tenant.

Shell
etlworks login --url https://app.etlworks.com --api-key YOUR_API_KEY
etlworks login --profile prod --url https://etl.example.com --api-key PROD_KEY
etlworks profiles            # lists profiles; keys are shown masked
etlworks run "whoami" --profile prod

The project folder

A project is a folder with one readable JSON file per object, ready for Git. Long SQL and scripts are stored as separate files, so diffs and reviews read like code.

Folder
etlworks.json                    manifest: project name, objects, collision policy
flows/load-orders.json
flows/load-orders/source-sql.sql code stored as files
connections/snowflake.json
formats/csv-default.json
macros/common-filters.json
schedules/nightly.json
environments/prod.json           per-environment overrides (you write these)

Export, plan, apply

Shell
# 1. Export from the development tenant into a Git working copy
etlworks project export ./analytics --project analytics --flows "Load orders,Load customers" --profile dev
git add analytics && git commit -m "Load orders: new filter"

# 2. See what would change in production (exit code 2 = there are changes)
etlworks project plan ./analytics --env prod --profile prod --out plan.json

# 3. Deploy exactly what was reviewed
etlworks project apply ./analytics --env prod --profile prod --plan plan.json --message "Release 42"

What happens to objects that already exist

The default policy, KeepAllReplaceFlowsAndMacros, replaces flows and macros from the folder and keeps the target's existing connections, formats and schedules. New objects are always created. Change it per run, or set it in etlworks.json or the environment file:

Shell
--collision Replace|Keep|KeepAllReplaceFlowsAndMacros
--replace formats,schedules      # also replace these types
--keep macros                    # keep these types as they are on the target
--fail connections               # stop if any of these already exist

Environments

One folder deploys to every environment. environments/<env>.json holds the values that differ, selected with --env. Overrides apply before planning, so the plan shows the final values.

environments/prod.json
{
  "connections": { "Snowflake": { "host": "acme.snowflakecomputing.com", "warehouse": "PROD_WH" } },
  "flows":       { "Load orders": { "variables": { "batch_size": "50000" } } },
  "schedules":   { "Nightly": { "enabled": true, "cron": "0 2 * * *" } }
}

Commands

CommandWhat it does
login, logout, profilesSave, remove and list connection profiles (--profile NAME, --url, --api-key).
versionClient and server versions, and whether they work together.
run "<cli command>"
run -f script.cli
Run any CLI command or script. --var k=v sets variables; --tenant ID|NAME runs it in another tenant you can access.
project export <dir>--project NAME, --flows a,b or --all, --connections nosecrets|reference|encrypted, --no-schedules, --clean.
project validate <dir>Checks the folder, references and overrides without comparing. --env, collision options.
project plan <dir>--env, --prune, collision options, --out plan.json, --verbose. Exit code 2 when there are changes.
project apply <dir>--env, --prune, collision options, --plan plan.json, --message TEXT, --yes.
project driftDeployed objects changed since the last deploy. --project NAME, --changed.
project env-get|env-set|env-unsetValues stored on the server for a project's environment (see above).
flow run "<name>"Runs a flow. --wait waits for it to finish (--timeout 30m) and the exit code follows the flow's result. --var k=v passes flow variables.

Global options: --profile NAME, --json (machine-readable output), --quiet, --insecure. Results go to stdout; progress and messages go to stderr, so stdout stays clean for pipes. etlworks --help prints the full syntax.

Exit codes

CodeMeaning
0OK
1The command, the deploy or the flow failed
2project plan: the plan has changes
3Not signed in, bad API key, or not allowed
4The client and server versions don't work together
5Usage error, such as a missing argument or apply without --yes in CI
130Cancelled (Ctrl-C)

GitHub Actions

Plan on every pull request, deploy on merge to main. Store the URL and API key as repository secrets.

.github/workflows/etlworks.yml
name: etlworks
on:
  pull_request:
  push:
    branches: [main]

env:
  ETLWORKS_URL: ${{ secrets.ETLWORKS_URL }}
  ETLWORKS_API_KEY: ${{ secrets.ETLWORKS_API_KEY }}

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with: { distribution: temurin, java-version: '17' }
      - name: Install the etlworks client
        run: |
          curl -fsSL -o client.zip https://etlworks.com/installers/download/client
          unzip -q client.zip -d "$RUNNER_TEMP"
          echo "$(ls -d "$RUNNER_TEMP"/etlworks-client-*)" >> "$GITHUB_PATH"
      - name: Validate and plan
        run: |
          etlworks project validate ./analytics --env prod
          etlworks project plan ./analytics --env prod --out plan.json || [ $? -eq 2 ]
      - name: Deploy
        if: github.event_name == 'push'
        run: etlworks project apply ./analytics --env prod --plan plan.json --yes --message "${{ github.sha }}"

|| [ $? -eq 2 ] lets the job continue when the plan has changes. To block a merge until someone reviews production changes, drop it, or post plan.json as a pull request comment.

GitLab CI

.gitlab-ci.yml
image: eclipse-temurin:17-jdk

# Set ETLWORKS_URL and ETLWORKS_API_KEY as masked CI/CD variables.

before_script:
  - curl -fsSL -o client.zip https://etlworks.com/installers/download/client
  - apt-get update -qq && apt-get install -y -qq unzip >/dev/null
  - unzip -q client.zip -d /opt
  - export PATH="$(ls -d /opt/etlworks-client-*):$PATH"

plan:
  stage: test
  script:
    - etlworks project plan ./analytics --env prod --out plan.json || [ $? -eq 2 ]
  artifacts: { paths: [plan.json] }

deploy:
  stage: deploy
  rules: [{ if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' }]
  script:
    - etlworks project apply ./analytics --env prod --plan plan.json --yes --message "$CI_COMMIT_SHA"

Azure DevOps

azure-pipelines.yml
trigger: [main]
pool: { vmImage: ubuntu-latest }

steps:
  - task: JavaToolInstaller@0
    inputs: { versionSpec: '17', jdkArchitectureOption: x64, jdkSourceOption: PreInstalled }
  - script: |
      curl -fsSL -o client.zip https://etlworks.com/installers/download/client
      unzip -q client.zip -d "$(Agent.TempDirectory)"
      echo "##vso[task.prependpath]$(ls -d "$(Agent.TempDirectory)"/etlworks-client-*)"
    displayName: Install the etlworks client
  - script: |
      etlworks project plan ./analytics --env prod --out plan.json || [ $? -eq 2 ]
      etlworks project apply ./analytics --env prod --plan plan.json --yes --message "$(Build.SourceVersion)"
    displayName: Plan and deploy
    env:
      ETLWORKS_URL: $(ETLWORKS_URL)
      ETLWORKS_API_KEY: $(ETLWORKS_API_KEY)   # a secret pipeline variable

Feedback

Missing a command, or a pipeline recipe worth adding? product@etlworks.com.