CI/CD
A project is a git repository, so the pipeline is short: install zsql, put a personal key in ZSQL_API_KEY, run zsql check on pull requests and zsql deploy on merge. The deployed branch is whatever --branch names, and the job fails when a test fails because zsql exits non-zero.
What you need
- A personal key (
zsk_...) for a user with write access to the project, stored as a CI secret. Query keys cannot deploy. Create keys in the console athttps://app.0sql.io(see Accounts); a dedicated “ci” key is easy to revoke. ZSQL_API_KEYset from that secret. It wins over any.zsqlfile, and nothing is written to disk.ZSQL_SERVER=https://app.0sql.io, unlessproject.ymlor a committed config names the server.--branch. CI checkouts are usually detached (git rev-parse --abbrev-ref HEADsaysHEAD), andzsqltakes the branch from git. Pass the CI’s branch variable explicitly, always.
GitHub Actions
.github/workflows/zsql.yml:
name: zsql
on:
pull_request:
push:
branches: [main]
env:
ZSQL_API_KEY: ${{ secrets.ZSQL_API_KEY }}
ZSQL_SERVER: https://app.0sql.io
jobs:
check:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install zsql
run: curl -fsSL https://0sql.io/install.sh | sh
- name: Validate and run tests
run: zsql check --branch "${{ github.head_ref }}"
deploy:
if: github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install zsql
run: curl -fsSL https://0sql.io/install.sh | sh
- name: Deploy
run: zsql deploy --branch "${{ github.ref_name }}"
On a pull request, zsql check validates the model and runs the tests on the service without deploying; the branch name only labels the output. On a push to main, zsql deploy --branch main updates tpcds/main. To also deploy feature branches as isolated previews, add their pattern to push.branches and the same step deploys tpcds/<branch>; remove them with zsql remove --yes --branch <branch> when the pull request closes.
GitLab CI
.gitlab-ci.yml:
variables:
ZSQL_SERVER: https://app.0sql.io
default:
image: debian:bookworm-slim
before_script:
- apt-get update -qq && apt-get install -y -qq curl ca-certificates git
- curl -fsSL https://0sql.io/install.sh | sh
check:
stage: test
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
script:
- zsql check --branch "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME"
deploy:
stage: deploy
rules:
- if: $CI_COMMIT_BRANCH == "main"
script:
- zsql deploy --branch "$CI_COMMIT_BRANCH"
Store ZSQL_API_KEY as a masked, protected CI/CD variable; it reaches the job as an environment variable, which is where zsql looks first.
Failing on tests
zsql check and zsql deploy exit non-zero when the archive is rejected or when any test fails. In the deploy case the model is already live (the HTTP call returned 200 with test_results.failed > 0), so a red job after a merge means “deployed, and a test broke”: fix forward. To keep a broken model off main, require the check job on pull requests before merging.
deploy tpcds (6240 bytes) as tpcds/main (the production branch) to https://app.0sql.io
deployed tpcds/main: 6 tables, 42 fields, 5 joins, 9 paths, 1 policies
FAILED catalog quantity by month
--- generated
...
tests: 2 passed, 1 failed
Error: tests failed
Protected production branches
A project owner can mark the production branch protected in the console. Then only an owner’s key may deploy to it, and anyone else gets:
Forbidden: deploying to the protected production branch 'main' of tpcds needs an owner
Give the CI key’s user owner access on the project, or keep production deploys to a job that uses an owner’s key. Everyone with write access can still deploy feature branches.