Home DevOps GitHub CLI — The Deployment That Succeeded via Wrong Workflow
Intermediate 3 min · July 12, 2026
GitHub CLI: Manage Repositories from the Terminal

GitHub CLI — The Deployment That Succeeded via Wrong Workflow

A developer used the GitHub web UI to trigger a workflow.

N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Notes here come from systems that actually shipped.

Follow
Production
production tested
July 12, 2026
last updated
2,406
articles · all by Naren
Before you start⏱ 15 min
  • Git installed (v2.30+), GitHub CLI (gh v2.0+), a GitHub account with repository permissions, basic familiarity with Git commands (clone, commit, push), and terminal proficiency.
 ● Production Incident
Quick Answer

Install: brew install gh or apt install gh. Authenticate: gh auth login. Key commands: gh pr create, gh pr review, gh run list, gh issue create, gh repo clone.

✦ Definition~90s read
What is GitHub CLI?

GitHub CLI (gh) lets you manage GitHub from the terminal: create PRs, review code, run workflows, manage issues, and more without leaving your editor.

GitHub CLI is the remote control for GitHub.
Plain-English First

GitHub CLI is the remote control for GitHub. Instead of clicking buttons on a website, you type commands in your terminal. Create a PR without opening a browser. Merge without leaving the editor. Run a deploy workflow with a single command. It's faster, scriptable, and harder to misclick than the web UI.

The GitHub web UI is designed for casual use. For daily operations — creating PRs, reviewing code, running workflows, managing issues — the CLI is faster and safer. A single gh pr create --fill creates a PR from your current branch without touching the mouse. gh workflow run deploy.yml --ref main triggers a deployment with a specific ref — no risk of clicking the wrong button. This guide covers the essential gh commands, the incident where web UI clicking triggered the wrong workflow, and how to script common operations.

Why GitHub CLI?

GitHub CLI (gh) replaces context-switching between terminal and browser. For DevOps engineers, staying in the terminal means faster workflows, easier scripting, and fewer distractions. gh supports authentication, repo management, issues, PRs, actions, and more. It's not a toy—it's a production tool. If you're still clicking through the GitHub UI for routine tasks, you're wasting time. Install gh, authenticate, and never open a browser for repo management again.

install-gh.shBASH
1
2
3
4
5
6
7
8
# macOS
brew install gh

# Linux (Ubuntu/Debian)
sudo apt install gh

# Verify
gh --version
Output
gh version 2.45.0 (2024-03-15)
https://github.com/cli/cli/releases/tag/v2.45.0
🔥Authentication First
Run gh auth login before anything else. It supports HTTPS, SSH, and token-based auth. For CI/CD, use GH_TOKEN env var.
📊 Production Insight
In production, we script gh commands in CI pipelines. A misconfigured auth can silently fail—always test with gh auth status.
🎯 Key Takeaway
GitHub CLI eliminates browser context-switching for repo management.
github-cli THECODEFORGE.IO GitHub CLI Deployment Architecture Layered components in CLI-based deployment User Interface Terminal | gh Command | Shell Scripts Authentication OAuth Token | SSH Key | gh auth CLI Core Repository Manager | Release Manager | Workflow Runner GitHub API REST Endpoints | GraphQL Queries | Webhooks Deployment Target GitHub Actions | Environments | Artifacts THECODEFORGE.IO
thecodeforge.io
Github Cli

Creating Repositories from the Terminal

Creating a repo via UI is slow. With gh, you can create a repo, initialize it, and push code in seconds. Use gh repo create with flags for visibility, license, and gitignore. For teams, set defaults in ~/.config/gh/config.yml. This is especially useful for bootstrapping microservices or spinning up ephemeral repos for experiments. Avoid the trap of creating repos manually—automate it.

create-repo.shBASH
1
2
3
4
5
6
7
8
9
10
11
# Create a public repo with README, license, and gitignore
gh repo create my-new-project --public --add-readme --license mit --gitignore Node

# Clone it locally
git clone https://github.com/your-org/my-new-project.git
cd my-new-project

# Add code and push
echo "# My New Project" > README.md
git add . && git commit -m "Initial commit"
git push origin main
Output
✓ Created repository your-org/my-new-project on GitHub
✓ Initialized repository in ./my-new-project
💡Default Settings
Set default visibility and license in gh config set -h github.com visibility public to avoid typing flags every time.
📊 Production Insight
We use gh repo create in our service scaffolding tool. One misstep: forgetting --push flag—always verify remote is set.
🎯 Key Takeaway
Create repos in seconds with gh repo create and avoid UI overhead.

Cloning and Forking Repositories

Cloning a repo is basic, but gh adds convenience: gh repo clone uses the authenticated user by default, supports SSH, and can clone from any org. Forking is a one-liner: gh repo fork. This is critical for open-source contributions or internal forks. gh also sets up the upstream remote automatically. Avoid manual git remote add—let gh handle it.

clone-fork.shBASH
1
2
3
4
5
6
7
8
9
# Clone a repo (defaults to SSH if configured)
gh repo clone cli/cli

# Fork a repo and clone your fork
gh repo fork cli/cli --clone

# Verify remotes
cd cli
git remote -v
Output
origin git@github.com:your-username/cli.git (fetch)
origin git@github.com:your-username/cli.git (push)
upstream https://github.com/cli/cli.git (fetch)
upstream https://github.com/cli/cli.git (push)
⚠ SSH vs HTTPS
If you use HTTPS, gh will prompt for credentials. Configure SSH keys and set gh config set git_protocol ssh for a seamless experience.
📊 Production Insight
In CI, we use gh repo clone with deploy keys. A common failure: missing SSH keys in the runner—always test clone step first.
🎯 Key Takeaway
gh simplifies cloning and forking with automatic remote setup.
github-cli THECODEFORGE.IO GitHub CLI and Actions Deployment Stack Layered view of components involved in the misconfigured deployment User Interface Terminal | gh CLI | Git Commands Repository Management Remote Repo | Local Clone | Fork CI/CD Pipeline GitHub Actions | Workflow YAML | Deploy Job Trigger Configuration Branch Filter | Event Type | Wrong Branch Deployment Target Production Server | Artifact | Environment THECODEFORGE.IO
thecodeforge.io
Github Cli

Managing Repository Settings

Repository settings like description, homepage, topics, and visibility are configurable via gh. Use gh repo edit to update multiple fields. This is essential for automation: when spinning up repos, enforce naming conventions and metadata. You can also enable/disable issues, wiki, and projects. Avoid manual UI edits—script them.

edit-repo.shBASH
1
2
3
4
5
6
7
8
9
10
11
# Update description and homepage
gh repo edit my-repo --description "A microservice for user auth" --homepage "https://auth.example.com"

# Add topics
github repo edit my-repo --add-topic "go" --add-topic "authentication"

# Change visibility to private
gh repo edit my-repo --visibility private

# Disable wiki
gh repo edit my-repo --enable-wiki=false
Output
✓ Updated repository your-org/my-repo
🔥Bulk Updates
Combine with gh repo list to bulk edit repos. For example, add a topic to all repos in an org.
📊 Production Insight
We once had a security incident because a repo was accidentally public. Now we enforce visibility via a post-create webhook that runs gh repo edit --visibility private.
🎯 Key Takeaway
Script repo settings with gh repo edit to enforce consistency.

Listing and Searching Repositories

Finding repos in large orgs is painful. gh repo list filters by owner, language, topic, and visibility. Use --json for machine-readable output. This is invaluable for audits, reporting, or feeding into other tools. Combine with jq for complex queries. Avoid scrolling through the UI—use the terminal.

list-repos.shBASH
1
2
3
4
5
6
7
8
# List all repos in your org, public only, with Go language
gh repo list your-org --visibility public --language go --limit 100

# JSON output for scripting
gh repo list your-org --json name,url,description,primaryLanguage

# Filter by topic
gh repo list your-org --topic "production"
Output
Showing 3 of 3 repositories in your-org
go-auth-service Go Authentication microservice
api-gateway Go API gateway
user-service Go User management
💡Pagination
Use --limit to control output. For all repos, loop with --page flag. Default limit is 30.
📊 Production Insight
We run a weekly audit script using gh repo list --json name,visibility to detect unintended public repos. It saved us twice.
🎯 Key Takeaway
List and search repos efficiently with gh repo list filters.

Deleting and Archiving Repositories

Cleanup is part of lifecycle management. gh repo delete removes a repo permanently (requires confirmation). gh repo archive marks it read-only. Use these in automation for ephemeral environments or stale projects. Be careful: deletion is irreversible. Always archive before delete in production workflows.

delete-archive.shBASH
1
2
3
4
5
6
7
8
# Archive a repo
gh repo archive your-org/stale-project

# Delete a repo (requires confirmation or --yes flag)
gh repo delete your-org/stale-project --yes

# Verify deletion
gh repo list your-org | grep stale-project
Output
✓ Archived repository your-org/stale-project
✓ Deleted repository your-org/stale-project
⚠ Irreversible Action
Deleting a repo cannot be undone. Always archive first and wait a grace period before deletion. Use --yes only in scripts after careful checks.
📊 Production Insight
Our cleanup cron job archives repos inactive for 90 days, then deletes after 30 more days. We once deleted a repo with unmerged PRs—now we check open PRs first.
🎯 Key Takeaway
Archive before delete to prevent accidental data loss.

Working with Pull Requests and Issues

gh isn't just for repo management—it handles PRs and issues too. Create, list, review, and merge PRs without leaving the terminal. This speeds up code review workflows. For DevOps, automating PR creation for dependency updates or release branches is a game-changer. Use gh pr create with templates and labels.

pr-workflow.shBASH
1
2
3
4
5
6
7
8
# Create a PR with title, body, and labels
gh pr create --title "Update dependencies" --body "Automated dependency update" --label "dependencies"

# List open PRs assigned to you
gh pr list --assignee @me --state open

# Merge a PR with squash
gh pr merge 42 --squash --delete-branch
Output
✓ Created pull request #42: Update dependencies
✓ Merged pull request #42 (Update dependencies)
💡PR Templates
Use gh pr create --fill to auto-fill from commit messages. For complex PRs, use --template with a custom file.
📊 Production Insight
We automated release PRs with gh pr create in CI. One failure: missing labels caused skipped CI checks. Always include required labels.
🎯 Key Takeaway
Manage PRs and issues from terminal to stay in flow.

Automating with GitHub Actions and gh

gh integrates seamlessly with GitHub Actions. Use gh workflow run to trigger workflows, gh run list to check status, and gh run watch to monitor in real-time. This enables complex automation: e.g., trigger a deployment workflow after a PR merge. Avoid polling the API—use gh's built-in commands.

actions-gh.shBASH
1
2
3
4
5
6
7
8
# Trigger a workflow with parameters
gh workflow run deploy.yml --ref main --field environment=staging

# List recent runs
gh run list --workflow=deploy.yml --limit 5

# Watch a specific run
gh run watch 1234567890
Output
✓ Created workflow_dispatch event for deploy.yml@main
✓ Run 1234567890 (deploy.yml) completed with 'success'
🔥Workflow Dispatch
Your workflow must have a workflow_dispatch event with inputs. Use --field to pass parameters.
📊 Production Insight
We use gh run watch in CI to block until deployment completes. A timeout caused a false positive—always set a timeout in your script.
🎯 Key Takeaway
Trigger and monitor Actions workflows directly from terminal.

Scripting and CI/CD Integration

gh is designed for scripting. Use --json and --jq to parse output in shell scripts. For CI/CD, set GH_TOKEN environment variable for authentication. Common patterns: create release, upload assets, manage environments. Avoid brittle parsing of human-readable output—always use --json.

ci-script.shBASH
1
2
3
4
5
6
7
8
9
#!/bin/bash
# Create a release and upload asset
VERSION="v1.0.0"
gh release create $VERSION --title "Release $VERSION" --notes "Changelog..."
gh release upload $VERSION ./dist/app.tar.gz

# Get latest release tag
LATEST=$(gh release list --json tagName --jq '.[0].tagName')
echo "Latest release: $LATEST"
Output
✓ Created release v1.0.0
✓ Uploaded app.tar.gz to v1.0.0
Latest release: v1.0.0
⚠ Token Security
Never hardcode tokens. Use secrets in CI/CD. For local scripts, use gh auth token to get the current token securely.
📊 Production Insight
We had a script that parsed gh release list output with awk—it broke when GitHub changed the format. Now we always use --json.
🎯 Key Takeaway
Script gh commands with --json and --jq for reliable automation.
Intended vs Actual Workflow Trigger Comparing the planned and executed deployment paths Intended Workflow Actual Workflow Trigger Branch main develop Workflow File deploy-main.yml deploy-develop.yml Deployment Environment Production Staging Result Deployment skipped Deployment succeeded Root Cause Correct branch filter Misconfigured branch filter THECODEFORGE.IO
thecodeforge.io
Github Cli

Troubleshooting Common Issues

Even with gh, things go wrong. Common issues: authentication failures, rate limiting, and permission errors. Use gh auth status to verify auth. Check rate limits with gh api rate_limit. For permission issues, verify your token scopes. Always test commands in a dry-run manner first. Avoid assuming everything works—build in error handling.

troubleshoot.shBASH
1
2
3
4
5
6
7
8
9
10
11
# Check authentication status
gh auth status

# Check rate limit
gh api rate_limit --jq '.rate.remaining'

# Test a simple command
gh repo view cli/cli --json name

# Debug with verbose flag
gh repo list --verbose
Output
✓ Logged in to github.com as your-username (keyring)
✓ Git operations for github.com configured to use ssh protocol
5000
⚠ Rate Limits
Unauthenticated requests have strict limits. Always authenticate. For high-volume automation, use a machine user token with appropriate scopes.
📊 Production Insight
Our CI pipeline failed silently because a token expired. Now we run gh auth status as a first step and alert on failure.
🎯 Key Takeaway
Use gh auth status and gh api rate_limit to diagnose issues quickly.
● Production incidentPOST-MORTEMseverity: high

The 'Run Workflow' Button That Deployed Staging to Production

Symptom
A developer navigated to the GitHub Actions page to trigger a staging deploy. The 'Run workflow' button was scrolled to show the production workflow. They clicked without checking the dropdown. The production deploy ran with staging's configuration.
Assumption
The developer assumed the 'Run workflow' button would default to the workflow they were currently viewing. GitHub's UI shows the most recently used workflow, not the page context.
Root cause
1. Developer opened the GitHub Actions tab to trigger a staging deploy. 2. They clicked 'Run workflow' without checking the workflow dropdown. 3. GitHub's UI had the production workflow selected (from a previous deployment). 4. The production workflow ran with staging's branch and environment variables. 5. The production site briefly served staging's content before monitoring caught it. 6. The developer couldn't stop the workflow quickly — the 'Cancel' button is small and easy to miss.
Fix
1. Reverted the production deployment: gh run list --workflow=deploy.yml then gh run cancel <id>. 2. Updated the deploy workflow to require a confirmation input: workflow_dispatch: inputs: confirm: description: 'Type PRODUCTION to confirm'. 3. Switched team to CLI-only deploys: gh workflow run deploy.yml --ref main -f env=production. 4. Added environment protection rules on GitHub requiring manual approval for production deployments.
Key lesson
  • GitHub web UI makes it easy to click the wrong workflow.
  • Use CLI for critical operations — it forces explicit parameters.
  • Add confirmation inputs to workflow_dispatch workflows.
  • Require environment protection rules for production deployments.
Production debug guideUse this when production is on fire4 entries
Symptom · 01
Create a PR from the current branch
Fix
Run gh pr create --fill — auto-fills title and body from commits
Symptom · 02
Review a PR without opening browser
Fix
Run gh pr review <number> --approve or --request-changes
Symptom · 03
Run a deploy workflow
Fix
Run gh workflow run deploy.yml --ref main — specify exact branch
Symptom · 04
Clone a repo without finding the URL
Fix
Run gh repo clone owner/repo
⚙ Quick Reference
10 commands from this guide
FileCommand / CodePurpose
install-gh.shbrew install ghWhy GitHub CLI?
create-repo.shgh repo create my-new-project --public --add-readme --license mit --gitignore No...Creating Repositories from the Terminal
clone-fork.shgh repo clone cli/cliCloning and Forking Repositories
edit-repo.shgh repo edit my-repo --description "A microservice for user auth" --homepage "ht...Managing Repository Settings
list-repos.shgh repo list your-org --visibility public --language go --limit 100Listing and Searching Repositories
delete-archive.shgh repo archive your-org/stale-projectDeleting and Archiving Repositories
pr-workflow.shgh pr create --title "Update dependencies" --body "Automated dependency update" ...Working with Pull Requests and Issues
actions-gh.shgh workflow run deploy.yml --ref main --field environment=stagingAutomating with GitHub Actions and gh
ci-script.shVERSION="v1.0.0"Scripting and CI/CD Integration
troubleshoot.shgh auth statusTroubleshooting Common Issues

Key takeaways

1
GitHub CLI is faster and safer than the web UI for daily operations
2
Use gh pr create --fill for auto-filled PRs
3
Use gh workflow run with explicit parameters for production deploys
4
Add confirmation inputs and environment protection rules for production
FAQ · 6 QUESTIONS

Frequently Asked Questions

01
How do I authenticate GitHub CLI in CI/CD?
02
Can I manage organization repositories with gh?
03
How do I delete a repository without confirmation?
04
What's the difference between `gh repo clone` and `git clone`?
05
How do I get JSON output from gh commands?
06
Can I trigger a GitHub Actions workflow from gh?
N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Notes here come from systems that actually shipped.

Follow
Verified
production tested
July 12, 2026
last updated
2,406
articles · all by Naren
🔥

That's Git. Mark it forged?

3 min read · try the examples if you haven't

Previous
GitHub Pages: Host Static Sites from Your Repository
36 / 47 · Git
Next
Forking and Contributing: The Open Source Workflow