diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..e7cfca7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=lf diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..754017b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,106 @@ +on: + push: + branches: + - master + schedule: + - cron: '0 1 * * *' + workflow_dispatch: + +name: Checkout and Create Release Version + +jobs: + check: + runs-on: ubuntu-latest + outputs: + version: ${{ steps.get-version.outputs.version }} + build: ${{ steps.check-build.outputs.build }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Check Version + id: get-version + run: | + version=$(curl -s 'https://api.github.com/repos/cli/cli/releases/latest' | jq -r ".tag_name") + echo "Current Version: ${version}" + if [ -z "${version}" ] || [ "${version}" == "null" ]; then + echo "Failed to get version" + exit 1 + fi + echo "version=${version}" >> $GITHUB_ENV + echo "version=${version}" >> $GITHUB_OUTPUT + + - name: Check Release + id: check-release + run: | + gh release view ${{ env.version }} -R ${{ github.repository }} >/dev/null 2>&1 || echo "create=1" >> $GITHUB_OUTPUT + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Check Build + id: check-build + run: | + gh release view ${{ env.version }} -R ${{ github.repository }} | grep gh_.*_checksums.txt >/dev/null 2>&1 || echo "build=1" >> $GITHUB_OUTPUT + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create Tag + run: | + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git add . + git commit -m "Release ${{ env.version }}" || echo "No changes to commit" + git tag -a "${{ env.version }}" -m "Release ${{ env.version }}" || true + git push origin "${{ env.version }}" || true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create Release + if: steps.check-release.outputs.create == 1 + run: | + gh release create ${{ env.version }} --notes "Release ${{ env.version }}" -R ${{ github.repository }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + release: + needs: check + runs-on: ubuntu-latest + if: needs.check.outputs.build == 1 + env: + version: ${{ needs.check.outputs.version }} + steps: + - name: Check Version + run: | + echo "Current Version: ${version}" + + - name: Checkout code + uses: actions/checkout@v4 + with: + repository: cli/cli + ref: ${{ env.version }} + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: 'stable' + + - name: Get File + run: | + wget -O ../goreleaser.yml https://github.com/${{ github.repository }}/raw/refs/heads/master/.goreleaser.yml + sudo apt-get install -y rpm reprepro + + - name: Build Binary + uses: goreleaser/goreleaser-action@v6 + with: + distribution: goreleaser + version: '~> v2' + args: release --config ../goreleaser.yml --skip=publish --clean + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Upgrade Release + run: | + gh release upload ${{ env.version }} dist/*.tar.gz dist/*.deb dist/*.rpm -R ${{ github.repository }} + gh release upload ${{ env.version }} dist/*.txt -R ${{ github.repository }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..045b327 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,70 @@ +version: 2 + +project_name: gh + +release: + prerelease: auto + draft: true # we only publish after the Windows MSI gets uploaded + name_template: "GitHub CLI {{.Version}}" + +before: + hooks: + - >- + {{ if eq .Runtime.Goos "windows" }}echo{{ end }} make manpages GH_VERSION={{.Version}} + - >- + {{ if ne .Runtime.Goos "linux" }}echo{{ end }} make completions + +builds: + - id: linux #build:linux + goos: + - linux + goarch: + - 386 + - amd64 + - arm + - arm64 + - mips64le + - ppc64le + - s390x + - riscv64 + - loong64 + goarm: + - 6 + - 7 + env: + - CGO_ENABLED=0 + binary: bin/gh + main: ./cmd/gh + ldflags: + - -s -w -X github.com/cli/cli/v2/internal/build.Version={{.Version}} -X github.com/cli/cli/v2/internal/build.Date={{time "2006-01-02"}} + +archives: + - id: linux-archive + builds: [linux] + name_template: "gh_{{ .Version }}_linux_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}" + wrap_in_directory: true + format: tar.gz + files: + - LICENSE + - ./share/man/man1/gh*.1 + +nfpms: #build:linux + - license: MIT + maintainer: GitHub + homepage: https://github.com/cli/cli + bindir: /usr + dependencies: + - git + description: GitHub’s official command line tool. + formats: + - deb + - rpm + contents: + - src: "./share/man/man1/gh*.1" + dst: "/usr/share/man/man1" + - src: "./share/bash-completion/completions/gh" + dst: "/usr/share/bash-completion/completions/gh" + - src: "./share/fish/vendor_completions.d/gh.fish" + dst: "/usr/share/fish/vendor_completions.d/gh.fish" + - src: "./share/zsh/site-functions/_gh" + dst: "/usr/share/zsh/site-functions/_gh" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b6a58a9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 GitHub Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..60ab7d6 --- /dev/null +++ b/README.md @@ -0,0 +1,185 @@ +# GitHub CLI + +`gh` is GitHub on the command line. It brings pull requests, issues, and other GitHub concepts to the terminal next to where you are already working with `git` and your code. + +![screenshot of gh pr status](https://user-images.githubusercontent.com/98482/84171218-327e7a80-aa40-11ea-8cd1-5177fc2d0e72.png) + +GitHub CLI is supported for users on GitHub.com, GitHub Enterprise Cloud, and GitHub Enterprise Server 2.20+ with support for macOS, Windows, and Linux. + +## Documentation + +For [installation options see below](#installation), for usage instructions [see the manual][manual]. + +## Contributing + +If anything feels off, or if you feel that some functionality is missing, please check out the [contributing page][contributing]. There you will find instructions for sharing your feedback, building the tool locally, and submitting pull requests to the project. + +If you are a hubber and are interested in shipping new commands for the CLI, check out our [doc on internal contributions][intake-doc]. + + +## Installation + +### macOS + +`gh` is available via [Homebrew][], [MacPorts][], [Conda][], [Spack][], [Webi][], and as a downloadable binary including Mac OS installer `.pkg` from the [releases page][]. + +> [!NOTE] +> As of May 29th, Mac OS installer `.pkg` are unsigned with efforts prioritized in [`cli/cli#9139`](https://github.com/cli/cli/issues/9139) to support signing them. + +#### Homebrew + +| Install: | Upgrade: | +| ----------------- | ----------------- | +| `brew install gh` | `brew upgrade gh` | + +#### MacPorts + +| Install: | Upgrade: | +| ---------------------- | ---------------------------------------------- | +| `sudo port install gh` | `sudo port selfupdate && sudo port upgrade gh` | + +#### Conda + +| Install: | Upgrade: | +|------------------------------------------|-----------------------------------------| +| `conda install gh --channel conda-forge` | `conda update gh --channel conda-forge` | + +Additional Conda installation options available on the [gh-feedstock page](https://github.com/conda-forge/gh-feedstock#installing-gh). + +#### Spack + +| Install: | Upgrade: | +| ------------------ | ---------------------------------------- | +| `spack install gh` | `spack uninstall gh && spack install gh` | + +#### Webi + +| Install: | Upgrade: | +| ----------------------------------- | ---------------- | +| `curl -sS https://webi.sh/gh \| sh` | `webi gh@stable` | + +For more information about the Webi installer see [its homepage](https://webinstall.dev/). + +#### Flox + +| Install: | Upgrade: | +| ----------------- | ----------------------- | +| `flox install gh` | `flox upgrade toplevel` | + +For more information about Flox, see [its homepage](https://flox.dev) + +### Linux & BSD + +`gh` is available via: +- [our Debian and RPM repositories](./docs/install_linux.md); +- community-maintained repositories in various Linux distros; +- OS-agnostic package managers such as [Homebrew](#homebrew), [Conda](#conda), [Spack](#spack), [Webi](#webi); and +- our [releases page][] as precompiled binaries. + +For more information, see [Linux & BSD installation](./docs/install_linux.md). + +### Windows + +`gh` is available via [WinGet][], [scoop][], [Chocolatey][], [Conda](#conda), [Webi](#webi), and as downloadable MSI. + +#### WinGet + +| Install: | Upgrade: | +| ------------------- | --------------------| +| `winget install --id GitHub.cli` | `winget upgrade --id GitHub.cli` | + +> [!NOTE] +> The Windows installer modifies your PATH. When using Windows Terminal, you will need to **open a new window** for the changes to take effect. (Simply opening a new tab will _not_ be sufficient.) + +#### scoop + +| Install: | Upgrade: | +| ------------------ | ------------------ | +| `scoop install gh` | `scoop update gh` | + +#### Chocolatey + +| Install: | Upgrade: | +| ------------------ | ------------------ | +| `choco install gh` | `choco upgrade gh` | + +#### Signed MSI + +MSI installers are available for download on the [releases page][]. + +### Codespaces + +To add GitHub CLI to your codespace, add the following to your [devcontainer file](https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/adding-features-to-a-devcontainer-file): + +```json +"features": { + "ghcr.io/devcontainers/features/github-cli:1": {} +} +``` + +### GitHub Actions + +GitHub CLI comes pre-installed in all [GitHub-Hosted Runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners). + +### Other platforms + +Download packaged binaries from the [releases page][]. + +#### Verification of binaries + +Since version 2.50.0 `gh` has been producing [Build Provenance Attestation](https://github.blog/changelog/2024-06-25-artifact-attestations-is-generally-available/) enabling a cryptographically verifiable paper-trail back to the origin GitHub repository, git revision and build instructions used. The build provenance attestations are signed and relies on Public Good [Sigstore](https://www.sigstore.dev/) for PKI. + +There are two common ways to verify a downloaded release, depending if `gh` is aready installed or not. If `gh` is installed, it's trivial to verify a new release: + +- **Option 1: Using `gh` if already installed:** + + ```shell + $ % gh at verify -R cli/cli gh_2.62.0_macOS_arm64.zip + Loaded digest sha256:fdb77f31b8a6dd23c3fd858758d692a45f7fc76383e37d475bdcae038df92afc for file://gh_2.62.0_macOS_arm64.zip + Loaded 1 attestation from GitHub API + ✓ Verification succeeded! + + sha256:fdb77f31b8a6dd23c3fd858758d692a45f7fc76383e37d475bdcae038df92afc was attested by: + REPO PREDICATE_TYPE WORKFLOW + cli/cli https://slsa.dev/provenance/v1 .github/workflows/deployment.yml@refs/heads/trunk + ``` + +- **Option 2: Using Sigstore [`cosign`](https://github.com/sigstore/cosign):** + + To perform this, download the [attestation](https://github.com/cli/cli/attestations) for the downloaded release and use cosign to verify the authenticity of the downloaded release: + + ```shell + $ cosign verify-blob-attestation --bundle cli-cli-attestation-3120304.sigstore.json \ + --new-bundle-format \ + --certificate-oidc-issuer="https://token.actions.githubusercontent.com" \ + --certificate-identity-regexp="^https://github.com/cli/cli/.github/workflows/deployment.yml@refs/heads/trunk$" \ + gh_2.62.0_macOS_arm64.zip + Verified OK + ``` + +### Build from source + +See here on how to [build GitHub CLI from source][build from source]. + +## Comparison with hub + +For many years, [hub][] was the unofficial GitHub CLI tool. `gh` is a new project that helps us explore +what an official GitHub CLI tool can look like with a fundamentally different design. While both +tools bring GitHub to the terminal, `hub` behaves as a proxy to `git`, and `gh` is a standalone +tool. Check out our [more detailed explanation][gh-vs-hub] to learn more. + +[manual]: https://cli.github.com/manual/ +[Homebrew]: https://brew.sh +[MacPorts]: https://www.macports.org +[winget]: https://github.com/microsoft/winget-cli +[scoop]: https://scoop.sh +[Chocolatey]: https://chocolatey.org +[Conda]: https://docs.conda.io/en/latest/ +[Spack]: https://spack.io +[Webi]: https://webinstall.dev +[releases page]: https://github.com/cli/cli/releases/latest +[hub]: https://github.com/github/hub +[contributing]: ./.github/CONTRIBUTING.md +[gh-vs-hub]: ./docs/gh-vs-hub.md +[build from source]: ./docs/source.md +[intake-doc]: ./docs/working-with-us.md