Set GitHub Actions Variables with gh variable set
Set a GitHub Actions variable with gh variable set and know exactly which scope you just wrote to. It takes about ten minutes for one variable, provided you are already logged in to GitHub and know the repository or organisation name.
The route
Jump straight to the step you need, or tick off Done means at the end.
This guide covers GitHub CLI 2.87.3, installed on this machine in February 2026. The command changes GitHub state remotely, so read the target name and scope before pressing Enter.
Warning
A variable is not a secret. Never put passwords, tokens or private keys in one. Use gh secret set for sensitive values instead.
1. Check the CLI and authentication
Run these read-only checks first. The repository form uses the current directory's GitHub repository; use --repo OWNER/REPO when you want an explicit target.
$ gh --version
gh version 2.87.3
$ gh auth status
$ gh variable set --help
The installed command accepts --body, --env, --env-file, --org, --repos and --visibility. Your login needs permission to administer variables at the level you pick. No sudo is needed: this is a GitHub API call, not a local system change.
Checkpoint
Before you go on, write down the variable name, its value and where a workflow should read it. Repository variables are the default. Environment variables are tied to a deployment environment. Organisation variables can be open to the whole organisation or restricted to selected repositories.
2. Set a repository variable
Pass a non-sensitive value with --body. This example targets an explicitly named repository and records a build label:
$ gh variable set RELEASE_CHANNEL \
--repo EXAMPLE_OWNER/EXAMPLE_REPO \
--body 'stable'
The command creates the variable if it does not exist and updates it if it does. The remote value changes immediately. Success usually prints nothing useful, so read it back:
$ gh variable get RELEASE_CHANNEL \
--repo EXAMPLE_OWNER/EXAMPLE_REPO \
--json name,value,visibility
{"name":"RELEASE_CHANNEL","value":"stable","visibility":"private"}
The exact JSON formatting can vary, but the name and value should match. If the command fails, keep the error text and exit status. Zero means success; authentication failures follow the GitHub CLI exit-code conventions.
3. Set a deployment-environment variable
Use --env when the value belongs to a deployment environment rather than every workflow run in the repository:
$ gh variable set API_BASE_URL \
--repo EXAMPLE_OWNER/EXAMPLE_REPO \
--env staging \
--body 'https://staging.example.invalid/api'
Keep the environment name exact. staging and Staging are different choices if your repository has both. Verify the scope with the matching read command:
$ gh variable get API_BASE_URL \
--repo EXAMPLE_OWNER/EXAMPLE_REPO \
--env staging \
--json name,value
4. Import several values from a dotenv file
For a small group of ordinary configuration values, use --env-file. Create the file outside version control, or review its contents first:
$ cat .env.actions
RELEASE_CHANNEL=stable
FEATURE_FLAG_NEW_UI=false
$ gh variable set --repo EXAMPLE_OWNER/EXAMPLE_REPO --env-file .env.actions
Warning
The file is input to a remote update. Every line becomes a variable, so leave out comments and anything you would not want workflow users to see, unless you have tested that the installed CLI accepts that exact dotenv syntax.
Check the resulting names without printing values:
$ gh variable list \
--repo EXAMPLE_OWNER/EXAMPLE_REPO \
--json name,visibility
5. Set an organisation variable deliberately
Organisation scope reaches more repositories, so check the target twice. This makes a variable visible to public and private repositories in the organisation:
$ gh variable set RELEASE_CHANNEL \
--org EXAMPLE_ORG \
--visibility all \
--body 'stable'
For a narrower audience, give the repository names as a comma-separated list:
$ gh variable set INTERNAL_TOOLCHAIN \
--org EXAMPLE_ORG \
--repos platform-api,platform-web \
--body 'v3'
A repository variable and an organisation variable with the same name are not interchangeable. The workflow's context and GitHub's variable precedence decide which value it sees. Read the organisation value back after setting it:
$ gh variable get INTERNAL_TOOLCHAIN \
--org EXAMPLE_ORG \
--json name,value,visibility,numSelectedRepos
6. Recover from a wrong value or scope
Recovery
Updating is the same operation, so rerun gh variable set with the correct scope and value. If you wrote a variable where it should not exist, stop any workflow that depends on it, then remove it with the matching gh variable delete command after checking its help.
Warning
Deletion is irreversible from the CLI. Keep the intended value in a reviewed local note first if you may need to recreate it.
If a workflow still sees an old value, check the exact repository, environment and organisation arguments before changing anything else. A successful update in one scope does not touch a same-named variable in another scope.
Done means
- Tooling checked. You confirmed the installed GitHub CLI version and authentication status.
- Target confirmed. The variable name, value and repository, environment or organisation scope were all checked.
- No secrets stored. The value came from
--bodyor a reviewed dotenv file. - Result verified. A matching
gh variable getorgh variable listcommand confirmed it. - Fix path known. A wrong value is corrected by rerunning the same scoped set command, and deletion was not your first resort.