Skip to content
Source

CI variables

Some jobs need values that are not secret: a deploy URL, a region, a feature switch. You want to change such a value without a commit, and keep it out of the workflow file.

A CI variable is a plain value that the repository keeps. A job names the variables that it needs, and gets each one as an environment variable.

1. Set the variables

Only admins of the repository set and delete variables. People with write access can read them.

src variable set DEPLOY_URL --body https://staging.example.com
src variable set REGION --body eu-west
src variable list
  • The commands use your src login and the repository of your clone. For another repository, add -R <owner>/<repo>.
  • Without --body, the value comes from stdin: src variable set NOTES < notes.txt.
  • --env-file ci.env sets one variable for each line of a dotenv file.
  • src variable get REGION prints one value. src variable delete REGION deletes the variable.

On the web, admins add, change and delete variables under Variables on the CI settings page (/<owner>/<repo>/settings/ci). A tool uses GET /api/v1/repos/<owner>/<repo>/ci/variables or the MCP tool list_ci_variables. The CI reference has each route and tool.

2. Declare them in the job

Add vars to the job, next to secrets. The workflow syntax is in Your first workflow.

import { defineWorkflow, push } from '@tanstack-source/ci'

export default defineWorkflow('deploy', { on: [push({ branches: ['main'] })] })
  .job('deploy', {
    vars: ['DEPLOY_URL', 'REGION'],
    steps: [
      { name: 'Deploy', run: 'echo "Deploy to $DEPLOY_URL in $REGION"' },
      { name: 'Summary', do: (ctx) => ctx.summary(`Deployed to ${ctx.vars.DEPLOY_URL}`) },
    ],
  })
  • A job gets only the variables that it declares.
  • A command step reads a variable as $DEPLOY_URL. A function step reads it as ctx.vars.DEPLOY_URL, typed from the names in vars.
  • A declared variable that the repository does not have is not set. The job still runs.
  • A name cannot be in secrets and in vars of the same job. The plan refuses it.

3. Push and read the log

git add .source/workflows/deploy.ts
git commit -m "ci: deploy with CI variables"
git push
src run list --workflow deploy

When the run ends, read its log:

src run view <run> --log

Done

The log of the Deploy step shows Deploy to https://staging.example.com in eu-west. To deploy to another place, run src variable set DEPLOY_URL --body <url> again. The next run gets the new value, with no commit.

Later: run the job on your machine

src ci run deploy deploy reads each declared variable from your environment, then from .env. A variable that neither has is not set. See Run CI jobs on your machine.

Later: pull requests and forks

  • A pull request run takes the vars of each job from the base branch, as it does for secrets. If a pull request adds a variable to a job, the run shows a warning. The job runs without it until the change is merged.
  • Variables are not secret. When the base branch declares them, a run of a pull request from a fork gets them too. Keep tokens and passwords in secrets.

Later: rules and limits

Names:

  • A name has letters, digits and _, does not start with a digit, and has at most 128 characters.
  • A name cannot be CI, and cannot start with CI_, TANSTACK_SOURCE_, GITFLARE_ or TSS_. The forge sets those names.

Values and limits:

  • A value is not empty, has no NUL character, and is at most 48 KiB. Line breaks are fine.
  • A repository has at most 100 variables, and a job declares at most 100.
  • The variables of one job total at most 256 KiB, each counted as NAME=value. Over that, the job does not start, and its error says why.
  • A job reads its variables once, when it starts. A change counts from the next job.