{"id":999,"date":"2026-05-20T04:50:38","date_gmt":"2026-05-20T04:50:38","guid":{"rendered":"https:\/\/www.devopsschool.com\/tutorials\/?p=999"},"modified":"2026-05-20T04:50:38","modified_gmt":"2026-05-20T04:50:38","slug":"github-github-cli-gh-install-authenticate-and-use-github-from-the-terminal","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/tutorials\/github-github-cli-gh-install-authenticate-and-use-github-from-the-terminal\/","title":{"rendered":"Github: GitHub CLI gh \u2014 Install, Authenticate, and Use GitHub from the Terminal"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">1. What is <code>gh<\/code>?<\/h2>\n\n\n\n<p><code>gh<\/code> is the <strong>official GitHub command-line interface<\/strong>. It brings GitHub features such as repositories, pull requests, issues, GitHub Actions, Codespaces, releases, secrets, variables, and API access into your terminal, right next to where you already use <code>git<\/code>. GitHub describes it nicely: <code>gh<\/code> lets you work with GitHub from the command line and avoid constantly switching between terminal and browser. (<a href=\"https:\/\/github.com\/cli\/cli\">GitHub<\/a>)<\/p>\n\n\n\n<p>A simple way to remember it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git  # works with Git: commits, branches, remotes, merges\ngh   # works with GitHub: PRs, issues, Actions, releases, repos, APIs\n<\/code><\/pre>\n\n\n\n<p>Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git status\ngit add .\ngit commit -m \"Add login page\"\n\ngh pr create\n<\/code><\/pre>\n\n\n\n<p>So <code>git<\/code> handles your source-control work, while <code>gh<\/code> handles the GitHub workflow around it.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">2. Install <code>gh<\/code> on Windows, macOS, and Linux<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Windows installation<\/h3>\n\n\n\n<p>The official recommended Windows method is <strong>WinGet<\/strong>. GitHub notes that the Windows installer modifies PATH, so after installing, open a new Windows Terminal window, not only a new tab. (<a href=\"https:\/\/github.com\/cli\/cli\/blob\/trunk\/docs\/install_windows.md\">GitHub<\/a>)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>winget install --id GitHub.cli --source winget\n<\/code><\/pre>\n\n\n\n<p>Upgrade:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>winget upgrade --id GitHub.cli --source winget\n<\/code><\/pre>\n\n\n\n<p>Community alternatives include Chocolatey, Scoop, Conda, and Webi, but the official recommendation is WinGet. (<a href=\"https:\/\/github.com\/cli\/cli\/blob\/trunk\/docs\/install_windows.md\">GitHub<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">macOS installation<\/h3>\n\n\n\n<p>The official recommended macOS method is <strong>Homebrew<\/strong>. (<a href=\"https:\/\/github.com\/cli\/cli\/blob\/trunk\/docs\/install_macos.md\">GitHub<\/a>)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>brew install gh\n<\/code><\/pre>\n\n\n\n<p>Upgrade:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>brew upgrade gh\n<\/code><\/pre>\n\n\n\n<p>GitHub also provides precompiled binaries for macOS amd64 and arm64, plus a universal installer. (<a href=\"https:\/\/github.com\/cli\/cli\/blob\/trunk\/docs\/install_macos.md\">GitHub<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Linux installation<\/h3>\n\n\n\n<p>For Ubuntu, Debian, and Raspberry Pi OS, GitHub recommends the official Debian-style package repository. GitHub\u2019s Linux packages and repository metadata are signed, and the install docs list PGP key fingerprints for verification. (<a href=\"https:\/\/github.com\/cli\/cli\/blob\/trunk\/docs\/install_linux.md\">GitHub<\/a>)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(type -p wget &gt;\/dev\/null || (sudo apt update &amp;&amp; sudo apt install wget -y)) \\\n  &amp;&amp; sudo mkdir -p -m 755 \/etc\/apt\/keyrings \\\n  &amp;&amp; out=$(mktemp) &amp;&amp; wget -nv -O$out https:\/\/cli.github.com\/packages\/githubcli-archive-keyring.gpg \\\n  &amp;&amp; cat $out | sudo tee \/etc\/apt\/keyrings\/githubcli-archive-keyring.gpg &gt; \/dev\/null \\\n  &amp;&amp; sudo chmod go+r \/etc\/apt\/keyrings\/githubcli-archive-keyring.gpg \\\n  &amp;&amp; sudo mkdir -p -m 755 \/etc\/apt\/sources.list.d \\\n  &amp;&amp; echo \"deb &#91;arch=$(dpkg --print-architecture) signed-by=\/etc\/apt\/keyrings\/githubcli-archive-keyring.gpg] https:\/\/cli.github.com\/packages stable main\" \\\n    | sudo tee \/etc\/apt\/sources.list.d\/github-cli.list &gt; \/dev\/null \\\n  &amp;&amp; sudo apt update \\\n  &amp;&amp; sudo apt install gh -y\n<\/code><\/pre>\n\n\n\n<p>Upgrade:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt update\nsudo apt install gh\n<\/code><\/pre>\n\n\n\n<p>For Fedora\/RHEL\/CentOS-style systems using DNF5:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo dnf install dnf5-plugins\nsudo dnf config-manager addrepo --from-repofile=https:\/\/cli.github.com\/packages\/rpm\/gh-cli.repo\nsudo dnf install gh\n<\/code><\/pre>\n\n\n\n<p>For DNF4:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo dnf install 'dnf-command(config-manager)'\nsudo dnf config-manager --add-repo https:\/\/cli.github.com\/packages\/rpm\/gh-cli.repo\nsudo dnf install gh\n<\/code><\/pre>\n\n\n\n<p>For openSUSE\/SUSE:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo zypper addrepo https:\/\/cli.github.com\/packages\/rpm\/gh-cli.repo\nsudo zypper ref\nsudo zypper install gh\n<\/code><\/pre>\n\n\n\n<p>GitHub\u2019s docs also mention Homebrew on Linux, precompiled binaries, and several community-maintained package options. They specifically discourage using Snap for GitHub CLI. (<a href=\"https:\/\/github.com\/cli\/cli\/blob\/trunk\/docs\/install_linux.md\">GitHub<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">3. Verify installation<\/h2>\n\n\n\n<p>After installing, check the version:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh --version\n<\/code><\/pre>\n\n\n\n<p>Then authenticate:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh auth login\n<\/code><\/pre>\n\n\n\n<p>The login flow asks whether you use GitHub.com or another GitHub Enterprise host, then walks you through browser-based authentication. If you choose HTTPS for Git operations, GitHub CLI can also store Git credentials so commands like <code>git push<\/code> and <code>git pull<\/code> work without separate credential setup. (<a href=\"https:\/\/docs.github.com\/en\/github-cli\/github-cli\/quickstart\">GitHub Docs<\/a>)<\/p>\n\n\n\n<p>Check login status:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh auth status\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">4. Basic <code>gh<\/code> command structure<\/h2>\n\n\n\n<p>Most commands follow this pattern:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh &lt;area&gt; &lt;action&gt; &#91;options]\n<\/code><\/pre>\n\n\n\n<p>Examples:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh repo view\ngh repo clone owner\/repo\ngh issue list\ngh pr create\ngh workflow list\ngh run list\ngh release create\n<\/code><\/pre>\n\n\n\n<p>To see all top-level commands:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh\n<\/code><\/pre>\n\n\n\n<p>To see subcommands:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh repo\ngh pr\ngh issue\n<\/code><\/pre>\n\n\n\n<p>To get help:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh pr create --help\ngh repo clone --help\n<\/code><\/pre>\n\n\n\n<p>GitHub\u2019s reference says you can use <code>gh<\/code> without arguments for top-level commands, <code>gh COMMAND<\/code> for subcommands, and <code>--help<\/code> for details on any command. (<a href=\"https:\/\/docs.github.com\/en\/github-cli\/github-cli\/github-cli-reference\">GitHub Docs<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">5. Main capabilities of the <code>gh<\/code> command line<\/h1>\n\n\n\n<p>GitHub CLI has a surprisingly wide command surface. The current manual includes core commands for auth, repositories, issues, pull requests, organizations, projects, releases, gists, Codespaces, and GitHub Actions, plus additional commands for API calls, aliases, completions, config, extensions, GPG keys, labels, rulesets, search, secrets, SSH keys, status, and variables. (<a href=\"https:\/\/cli.github.com\/manual\/gh\">GitHub CLI<\/a>)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Repository management<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>gh repo clone owner\/repo\ngh repo view owner\/repo\ngh repo create\ngh repo fork owner\/repo\n<\/code><\/pre>\n\n\n\n<p>Real use case: You join a new project and need to clone the repo quickly.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh repo clone kubernetes\/kubernetes\ncd kubernetes\ngh repo view --web\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Issue management<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>gh issue list\ngh issue view 42\ngh issue create\ngh issue close 42\n<\/code><\/pre>\n\n\n\n<p>Real use case: A tester finds a bug and creates an issue from the terminal.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh issue create \\\n  --title \"Login button disabled after password reset\" \\\n  --body \"Steps: reset password, log out, try to log in again. Expected: login button active. Actual: button remains disabled.\" \\\n  --label bug\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Pull request workflow<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>gh pr list\ngh pr create\ngh pr checkout 123\ngh pr view 123\ngh pr review 123\ngh pr merge 123\n<\/code><\/pre>\n\n\n\n<p>Real use case: You finish a feature branch and create a PR without opening GitHub in the browser.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git checkout -b feature\/add-profile-page\ngit add .\ngit commit -m \"Add profile page\"\ngit push -u origin feature\/add-profile-page\n\ngh pr create \\\n  --title \"Add profile page\" \\\n  --body \"Adds a user profile page with editable display name and avatar.\"\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">GitHub Actions<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>gh workflow list\ngh workflow run ci.yml\ngh run list\ngh run view\ngh run watch\ngh run download\n<\/code><\/pre>\n\n\n\n<p>Real use case: You push code and want to watch CI from the terminal.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh run list\ngh run watch\n<\/code><\/pre>\n\n\n\n<p>The <code>gh run<\/code> command supports listing, viewing, watching, canceling, deleting, downloading logs\/artifacts, and rerunning workflow runs. (<a href=\"https:\/\/cli.github.com\/manual\/gh_run?utm_source=chatgpt.com\">GitHub CLI<\/a>)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Releases<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>gh release list\ngh release view v1.0.0\ngh release create v1.0.0\ngh release upload v1.0.0 .\/dist\/app.zip\n<\/code><\/pre>\n\n\n\n<p>Real use case: You build a CLI tool and publish a release with binaries.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh release create v1.0.0 .\/dist\/myapp-linux.tar.gz .\/dist\/myapp-macos.zip \\\n  --title \"v1.0.0\" \\\n  --notes \"First stable release.\"\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Secrets and variables<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>gh secret set DOCKER_TOKEN\ngh secret list\ngh variable set APP_ENV --body production\ngh variable list\n<\/code><\/pre>\n\n\n\n<p>Real use case: You need to add a deployment token for GitHub Actions.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh secret set DOCKERHUB_TOKEN\n<\/code><\/pre>\n\n\n\n<p>Then paste the secret value when prompted.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">GitHub API access<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>gh api repos\/OWNER\/REPO\ngh api user\ngh api graphql\n<\/code><\/pre>\n\n\n\n<p>Real use case: You want to script a GitHub operation that does not have a dedicated high-level <code>gh<\/code> command.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh api repos\/OWNER\/REPO\/issues\n<\/code><\/pre>\n\n\n\n<p>This is one of the sleeper superpowers of <code>gh<\/code>: it gives you authenticated API access without manually managing tokens in every script.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Codespaces<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>gh codespace list\ngh codespace create\ngh codespace ssh\ngh codespace code\n<\/code><\/pre>\n\n\n\n<p>Real use case: You are on a lightweight laptop and want to develop inside a cloud dev environment.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh codespace create\ngh codespace code\n<\/code><\/pre>\n\n\n\n<p>GitHub\u2019s quickstart shows <code>gh codespace create<\/code>, <code>gh codespace list<\/code>, and <code>gh codespace code -w<\/code> as common Codespaces commands. (<a href=\"https:\/\/docs.github.com\/en\/github-cli\/github-cli\/quickstart\">GitHub Docs<\/a>)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Search<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>gh search repos \"language:go stars:&gt;1000\"\ngh search issues \"is:open label:bug\"\ngh search prs \"review-requested:@me state:open\"\n<\/code><\/pre>\n\n\n\n<p>Real use case: You want to find all open PRs awaiting your review.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh search prs --review-requested=@me --state=open\n<\/code><\/pre>\n\n\n\n<p>GitHub\u2019s quickstart uses this exact pattern for PR review discovery. (<a href=\"https:\/\/docs.github.com\/en\/github-cli\/github-cli\/quickstart\">GitHub Docs<\/a>)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Aliases and customization<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>gh alias set co \"pr checkout\"\ngh alias set prd \"pr create --draft\"\n<\/code><\/pre>\n\n\n\n<p>Then use:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh co 123\ngh prd\n<\/code><\/pre>\n\n\n\n<p>GitHub\u2019s docs mention aliases and extensions as ways to customize the CLI for your workflow. (<a href=\"https:\/\/docs.github.com\/en\/github-cli\/github-cli\/quickstart\">GitHub Docs<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">6. End-to-end real-world workflows<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Workflow 1: New developer joining a project<\/h2>\n\n\n\n<p>Scenario: You are assigned to a repository and need to clone it, inspect it, and check assigned work.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh auth login\ngh repo clone my-org\/my-app\ncd my-app\ngh repo view\ngh issue list --assignee \"@me\"\ngh pr list\n<\/code><\/pre>\n\n\n\n<p>Why this is useful: onboarding becomes faster. You can see the README, issues, and PRs without bouncing between browser tabs.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Workflow 2: Create a bug report from terminal<\/h2>\n\n\n\n<p>Scenario: You are testing an app and discover a bug.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh issue create \\\n  --title \"Checkout fails when coupon code is empty\" \\\n  --body \"Steps to reproduce:\n1. Open checkout page\n2. Leave coupon code empty\n3. Click Apply\n\nExpected: no error\nActual: checkout form crashes\" \\\n  --label bug\n<\/code><\/pre>\n\n\n\n<p>Then list bugs:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh issue list --label bug\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Workflow 3: Create a pull request<\/h2>\n\n\n\n<p>Scenario: You fixed an issue and want to open a PR.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git checkout -b fix\/checkout-empty-coupon\ngit add .\ngit commit -m \"Fix checkout crash for empty coupon\"\ngit push -u origin fix\/checkout-empty-coupon\n\ngh pr create \\\n  --title \"Fix checkout crash for empty coupon\" \\\n  --body \"Fixes validation when coupon field is empty.\"\n<\/code><\/pre>\n\n\n\n<p>Open the PR in browser only when needed:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh pr view --web\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Workflow 4: Review someone else\u2019s PR locally<\/h2>\n\n\n\n<p>Scenario: A teammate asks you to review PR #58.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh pr checkout 58\nnpm test\ngh pr view\ngh pr review 58 --comment --body \"Tested locally. Left one small suggestion.\"\n<\/code><\/pre>\n\n\n\n<p>Approve:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh pr review 58 --approve\n<\/code><\/pre>\n\n\n\n<p>Merge:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh pr merge 58 --squash --delete-branch\n<\/code><\/pre>\n\n\n\n<p>Tiny quality-of-life upgrade, huge time saver.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Workflow 5: Watch CI\/CD after pushing code<\/h2>\n\n\n\n<p>Scenario: You pushed a branch and want to see whether GitHub Actions passed.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh run list\ngh run watch\n<\/code><\/pre>\n\n\n\n<p>View logs for a failed run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh run view --log\n<\/code><\/pre>\n\n\n\n<p>Rerun failed jobs:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh run rerun --failed\n<\/code><\/pre>\n\n\n\n<p>This is especially useful in DevOps, platform engineering, and CI\/CD-heavy teams.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Workflow 6: Trigger a deployment workflow manually<\/h2>\n\n\n\n<p>Scenario: Your repo has a deployment workflow that supports manual runs.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh workflow list\ngh workflow run deploy.yml\ngh run watch\n<\/code><\/pre>\n\n\n\n<p>With inputs:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh workflow run deploy.yml \\\n  -f environment=staging \\\n  -f version=v1.2.3\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Workflow 7: Publish a release<\/h2>\n\n\n\n<p>Scenario: You built version <code>v1.0.0<\/code> of your app.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git tag v1.0.0\ngit push origin v1.0.0\n\ngh release create v1.0.0 \\\n  .\/dist\/app-linux-amd64.tar.gz \\\n  .\/dist\/app-darwin-arm64.zip \\\n  --title \"v1.0.0\" \\\n  --notes \"Initial production release.\"\n<\/code><\/pre>\n\n\n\n<p>View releases:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh release list\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Workflow 8: Use <code>gh<\/code> inside automation scripts<\/h2>\n\n\n\n<p>Scenario: You want to script GitHub tasks.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/usr\/bin\/env bash\nset -e\n\nREPO=\"my-org\/my-app\"\n\necho \"Open issues:\"\ngh issue list --repo \"$REPO\" --state open\n\necho \"Open PRs:\"\ngh pr list --repo \"$REPO\" --state open\n<\/code><\/pre>\n\n\n\n<p>For structured output, many <code>gh<\/code> commands support JSON output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh pr list --json number,title,author,state\n<\/code><\/pre>\n\n\n\n<p>That makes <code>gh<\/code> handy for shell scripts, dashboards, reports, and automation.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">7. Handy commands cheat sheet<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Task<\/th><th>Command<\/th><\/tr><\/thead><tbody><tr><td>Login<\/td><td><code>gh auth login<\/code><\/td><\/tr><tr><td>Check login<\/td><td><code>gh auth status<\/code><\/td><\/tr><tr><td>Clone repo<\/td><td><code>gh repo clone owner\/repo<\/code><\/td><\/tr><tr><td>View repo<\/td><td><code>gh repo view<\/code><\/td><\/tr><tr><td>Create repo<\/td><td><code>gh repo create<\/code><\/td><\/tr><tr><td>List issues<\/td><td><code>gh issue list<\/code><\/td><\/tr><tr><td>Create issue<\/td><td><code>gh issue create<\/code><\/td><\/tr><tr><td>List PRs<\/td><td><code>gh pr list<\/code><\/td><\/tr><tr><td>Create PR<\/td><td><code>gh pr create<\/code><\/td><\/tr><tr><td>Checkout PR<\/td><td><code>gh pr checkout 123<\/code><\/td><\/tr><tr><td>Review PR<\/td><td><code>gh pr review 123<\/code><\/td><\/tr><tr><td>Merge PR<\/td><td><code>gh pr merge 123<\/code><\/td><\/tr><tr><td>List workflows<\/td><td><code>gh workflow list<\/code><\/td><\/tr><tr><td>Run workflow<\/td><td><code>gh workflow run workflow.yml<\/code><\/td><\/tr><tr><td>List workflow runs<\/td><td><code>gh run list<\/code><\/td><\/tr><tr><td>Watch workflow run<\/td><td><code>gh run watch<\/code><\/td><\/tr><tr><td>Create release<\/td><td><code>gh release create v1.0.0<\/code><\/td><\/tr><tr><td>Set secret<\/td><td><code>gh secret set NAME<\/code><\/td><\/tr><tr><td>Set variable<\/td><td><code>gh variable set NAME --body value<\/code><\/td><\/tr><tr><td>Open repo\/PR\/page in browser<\/td><td><code>gh browse<\/code><\/td><\/tr><tr><td>Call GitHub API<\/td><td><code>gh api ...<\/code><\/td><\/tr><tr><td>Create alias<\/td><td><code>gh alias set name \"command\"<\/code><\/td><\/tr><tr><td>Install extension<\/td><td><code>gh extension install owner\/gh-extension<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">8. Recommended beginner practice lab<\/h1>\n\n\n\n<p>Try this safe practice workflow on a test repository.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh auth login\ngh repo create gh-practice-demo --public --clone\ncd gh-practice-demo\n\necho \"# GH Practice Demo\" &gt; README.md\ngit add README.md\ngit commit -m \"Add README\"\ngit push origin main\n<\/code><\/pre>\n\n\n\n<p>Create an issue:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh issue create \\\n  --title \"Add installation instructions\" \\\n  --body \"The README should include setup steps.\"\n<\/code><\/pre>\n\n\n\n<p>Create a branch and PR:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git checkout -b docs\/install-steps\necho \"\" &gt;&gt; README.md\necho \"## Installation\" &gt;&gt; README.md\necho \"Run the app setup commands here.\" &gt;&gt; README.md\n\ngit add README.md\ngit commit -m \"Add installation section\"\ngit push -u origin docs\/install-steps\n\ngh pr create \\\n  --title \"Add installation section\" \\\n  --body \"Adds basic installation instructions to README.\"\n<\/code><\/pre>\n\n\n\n<p>Merge it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh pr merge --squash --delete-branch\n<\/code><\/pre>\n\n\n\n<p>Clean up:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git checkout main\ngit pull\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">9. Best practices<\/h1>\n\n\n\n<p>Use <code>gh auth status<\/code> when commands fail mysteriously. A lot of \u201cwhy is GitHub rejecting me?\u201d problems are just expired or missing auth.<\/p>\n\n\n\n<p>Use <code>--help<\/code> aggressively:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh pr create --help\ngh workflow run --help\ngh release create --help\n<\/code><\/pre>\n\n\n\n<p>Use aliases for commands you repeat often:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh alias set mine \"issue list --assignee @me\"\ngh alias set reviews \"search prs --review-requested=@me --state=open\"\n<\/code><\/pre>\n\n\n\n<p>Use <code>gh pr checkout<\/code> instead of manually finding branches from forks. It is cleaner and less error-prone.<\/p>\n\n\n\n<p>Use <code>gh run watch<\/code> right after pushing a PR. It keeps your feedback loop tight.<\/p>\n\n\n\n<p>For Linux, prefer GitHub\u2019s official package repositories over stale distro packages when available. GitHub\u2019s own Linux install docs warn that some community Debian\/Ubuntu packages had broken older versions due to deprecated GitHub APIs as of November 2025. (<a href=\"https:\/\/github.com\/cli\/cli\/blob\/trunk\/docs\/install_linux.md\">GitHub<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">10. Final summary<\/h1>\n\n\n\n<p><code>gh<\/code> is one of those tools that feels small at first, then quietly takes over your workflow. For developers, it speeds up cloning repos, creating issues, opening PRs, reviewing code, and checking CI. For DevOps teams, it helps trigger workflows, inspect GitHub Actions, manage secrets, publish releases, and script GitHub operations. For open-source maintainers, it makes triage and PR review dramatically faster.<\/p>\n\n\n\n<p>Start with these five commands:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh auth login\ngh repo clone owner\/repo\ngh issue list\ngh pr create\ngh run watch\n<\/code><\/pre>\n\n\n\n<p>Once those feel natural, add releases, secrets, API calls, aliases, and workflow automation. That is where <code>gh<\/code> turns from \u201cnice CLI tool\u201d into a proper GitHub power tool.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. What is gh? gh is the official GitHub command-line interface. It brings GitHub features such as repositories, pull requests, issues, GitHub Actions, Codespaces, releases, secrets, variables,&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-999","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/999","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/comments?post=999"}],"version-history":[{"count":1,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/999\/revisions"}],"predecessor-version":[{"id":1000,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/999\/revisions\/1000"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/media?parent=999"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/categories?post=999"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/tags?post=999"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}