├── .github ├── dependabot.yml └── workflows │ ├── pr.yml │ └── schedule.yml ├── .gitignore ├── README.md ├── debian └── Dockerfile └── get-version.sh /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | 4 | # Maintain dependencies for GitHub Actions 5 | - package-ecosystem: "github-actions" 6 | directory: "/" 7 | schedule: 8 | interval: "daily" 9 | -------------------------------------------------------------------------------- /.github/workflows/pr.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | jobs: 8 | test: 9 | runs-on: ubuntu-latest 10 | 11 | name: Build 12 | 13 | steps: 14 | - name: Checkout code 15 | uses: actions/checkout@v4 16 | 17 | - name: Build Docker Image 18 | uses: docker/build-push-action@v6.18.0 19 | with: 20 | context: . 21 | file: ./debian/Dockerfile 22 | -------------------------------------------------------------------------------- /.github/workflows/schedule.yml: -------------------------------------------------------------------------------- 1 | name: update-version 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | - cron: '0 0 * * *' # Midnight - every night 7 | 8 | jobs: 9 | get_version: 10 | runs-on: ubuntu-latest 11 | 12 | name: Get next GITHUB_CLI_VERSION 13 | 14 | # https://stackoverflow.com/a/61236803 15 | outputs: 16 | gh_version: ${{ steps.gh_version.outputs.gh_version }} 17 | 18 | steps: 19 | - name: Checkout code 20 | uses: actions/checkout@v4 21 | with: 22 | ref: ${{ github.head_ref }} 23 | 24 | - name: Get next gh version 25 | id: gh_version 26 | run: | 27 | next_version="$(bash get-version.sh ${{ secrets.GITHUB_TOKEN }})" 28 | echo "$next_version" 29 | echo "gh_version=${next_version}" >> $GITHUB_OUTPUT 30 | 31 | update: 32 | runs-on: ubuntu-latest 33 | 34 | name: Update GITHUB_CLI_VERSION 35 | 36 | needs: get_version 37 | 38 | if: ${{ needs.get_version.outputs.gh_version != '' }} 39 | 40 | steps: 41 | - name: Checkout code 42 | uses: actions/checkout@v4 43 | with: 44 | ref: ${{ github.head_ref }} 45 | 46 | - name: Write gh version to env 47 | run: | 48 | echo "gh_version=${{needs.get_version.outputs.gh_version}}" >> $GITHUB_ENV 49 | 50 | - name: Update GITHUB_CLI_VERSION 51 | run: | 52 | echo "${{ env.gh_version }}" | grep -Pq "^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$" 53 | find . -name Dockerfile -print0 | xargs -0 sed -i -E "s/^(ENV GITHUB_CLI_VERSION\s*).*$/\1${{ env.gh_version }}/g" 54 | 55 | - name: Login to GitHub Container Registry 56 | uses: docker/login-action@v3.4.0 57 | with: 58 | registry: ghcr.io 59 | username: ${{ github.actor }} 60 | password: ${{ secrets.GITHUB_TOKEN }} 61 | 62 | - name: Commit changes 63 | uses: stefanzweifel/git-auto-commit-action@v5.2.0 64 | id: "commit" 65 | with: 66 | commit_message: "Update GITHUB_CLI_VERSION to ${{ env.gh_version }}" 67 | commit_user_name: actions-user 68 | commit_user_email: actions@github.com 69 | commit_author: GitHub Actions 70 | 71 | - name: Push Docker Image 72 | if: steps.commit.outputs.changes_detected == 'true' 73 | uses: docker/build-push-action@v6.18.0 74 | with: 75 | push: true 76 | context: . 77 | file: ./debian/Dockerfile 78 | tags: | 79 | ghcr.io/${{ github.repository }}:${{ env.gh_version }} 80 | ghcr.io/${{ github.repository }}:latest 81 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker Image for GitHub CLI 2 | 3 | This repository provides a Docker image for [GitHub CLI](https://github.com/cli/cli/). 4 | 5 | ## Container Registry 6 | 7 | See [ghcr.io](https://ghcr.io/supportpal/github-gh-cli) 8 | 9 | ## Usage 10 | 11 | ```bash 12 | docker run --rm -it ghcr.io/supportpal/github-gh-cli gh --version 13 | ``` 14 | -------------------------------------------------------------------------------- /debian/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:bookworm-slim 2 | 3 | RUN set -ex; \ 4 | apt-get update ; \ 5 | apt-get install -y --no-install-recommends \ 6 | ca-certificates \ 7 | curl \ 8 | git; \ 9 | rm -rf /var/lib/apt/lists/* 10 | 11 | ENV GITHUB_CLI_VERSION 2.74.0 12 | 13 | RUN set -ex; \ 14 | curl -L "https://github.com/cli/cli/releases/download/v${GITHUB_CLI_VERSION}/gh_${GITHUB_CLI_VERSION}_checksums.txt" -o checksums.txt; \ 15 | curl -OL "https://github.com/cli/cli/releases/download/v${GITHUB_CLI_VERSION}/gh_${GITHUB_CLI_VERSION}_linux_amd64.deb"; \ 16 | shasum --ignore-missing -a 512 -c checksums.txt; \ 17 | dpkg -i "gh_${GITHUB_CLI_VERSION}_linux_amd64.deb"; \ 18 | rm -rf "gh_${GITHUB_CLI_VERSION}_linux_amd64.deb"; \ 19 | # verify gh binary works 20 | gh --version; 21 | 22 | CMD ["gh"] 23 | -------------------------------------------------------------------------------- /get-version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euxo pipefail # Ensures the script exits on errors and unset variables 4 | 5 | # Function to parse JSON data using jq 6 | parseData() { 7 | local jsonData="$1" 8 | if echo "$jsonData" | jq . >/dev/null 2>&1; then 9 | echo "$jsonData" | jq -c '[.[] | select(.prerelease == false) | {published_at, tag_name}]' 10 | else 11 | echo "Error: Failed to parse JSON data." >&2 12 | exit 1 13 | fi 14 | } 15 | 16 | # Function to get paginated data 17 | getPaginatedData() { 18 | local url=$1 19 | local token=$2 20 | local data='[]' 21 | 22 | while :; do 23 | # Fetch data using curl 24 | response=$(curl -s -w "%{http_code}" -H "Authorization: Bearer $token" \ 25 | -H "X-GitHub-Api-Version: 2022-11-28" \ 26 | -H "Accept: application/vnd.github.v3+json" "$url") 27 | 28 | http_code="${response: -3}" # Extract HTTP status code 29 | response_body="${response%???}" # Extract body 30 | 31 | if [[ "$http_code" != "200" ]]; then 32 | echo "Error: Failed to fetch data from GitHub API (HTTP status: $http_code)." >&2 33 | echo "Response: $response_body" >&2 34 | exit 1 35 | fi 36 | 37 | # Parse the JSON data 38 | parsedData=$(parseData "$response_body") 39 | 40 | # Append parsed data to the data array 41 | data=$(echo "$data" "$parsedData" | jq -s 'add') 42 | 43 | # Check the link header for pagination 44 | linkHeader=$(curl -s -I -H "Authorization: Bearer $token" \ 45 | -H "X-GitHub-Api-Version: 2022-11-28" \ 46 | -H "Accept: application/vnd.github.v3+json" "$url" | grep -i 'link:') 47 | 48 | if [[ $linkHeader == *'rel="next"'* ]]; then 49 | # Extract the next URL from the link header using regex 50 | nextUrl=$(echo "$linkHeader" | grep -o '<[^>]*>; rel="next"' | sed 's/<\(.*\)>; rel="next"/\1/') 51 | url=$nextUrl 52 | else 53 | break 54 | fi 55 | done 56 | 57 | # Output the collected data 58 | echo "$data" 59 | } 60 | 61 | if [ "$#" -lt 1 ]; then 62 | echo "Usage: $0 GITHUB_TOKEN" 63 | exit 1 64 | fi 65 | 66 | # Initial URL 67 | initialUrl="https://api.github.com/repos/cli/cli/releases?per_page=100" 68 | token="$1" 69 | current_version="$(grep -Eo "ENV GITHUB_CLI_VERSION .+" debian/Dockerfile | cut -d' ' -f3)" 70 | 71 | # Get the paginated data 72 | data=$(getPaginatedData "$initialUrl" "$token") 73 | 74 | # Sort the data by the published_at attribute in descending order 75 | sortedData=$(echo "$data" | jq 'sort_by(.published_at) | reverse') 76 | 77 | # Determine the next version. 78 | tags=$(echo "$sortedData" | jq -r '.[] | .tag_name' | tr '\n' ' ') 79 | next_version="$(echo "$tags" | (grep -Eo "(.*?) v$current_version( |$)" || true) | awk '{print $(NF-1)}' | cut -c2-)" 80 | 81 | echo "$next_version" 82 | --------------------------------------------------------------------------------