Release using GitHub CLI and consume it from another repository

Create a release using GitHub CLI and consume the release binaries from another repository


Releases on GitHub streamline the process of packaging and distributing project artifacts. In this post, I’ll demonstrate how to create a release using the GitHub CLI (gh) and consume the release binaries from another repository. This approach is particularly useful in CI/CD pipelines for automating the creation and usage of release artifacts.

Prerequisites

  1. GitHub CLI Installed: Ensure the gh command-line tool is installed. You can download it here. (pre-insntalled in GitHub Hosted Runners)
  2. Repository Setup: You need access to a GitHub repository where the release will be created.
  3. GitHub Token: A GitHub token with sufficient permissions to authenticate and perform actions on the repository.

Using GitHub Enterprise Server

By default, the gh CLI targets the github.com API. If you’re using GitHub Enterprise Server, you’ll need to explicitly specify the hostname with the –hostname flag when authenticating.

gh auth login --hostname <your-enterprise-server-hostname>

Workflow Overview

Here’s a GitHub Actions workflow that:

  1. Authenticates the gh CLI with a GitHub token.
  2. Creates a release in a repository.
  3. Consumes binaries from the release for further use.
name: Create a binary and create a release

on:
  workflow_dispatch: # Trigger the workflow manually.

permissions:
  contents: write # Required for creating releases.

jobs:
  create-release:
    env:
      ZIP: my-zip.zip
      HOST: my-github-enterprise-server.com
    
    runs-on: ubuntu-latest

    steps:
      # Step 1: Check out the repository
      - name: Checkout
        uses: actions/checkout@v4

      # Step 2: Authenticate the gh CLI
      - name: Authenticate gh CLI
        run: |
          echo "${{ github.token }}" | gh auth login --with-token --hostname ${{ env.HOST }}

      # Alternative authentication method
      - name: Authenticate gh CLI (Alternative)
        run: gh auth login --with-token <<< '${{ secrets.GITHUB_TOKEN }}'

      # Step 3: Prepare directories
      - name: Create required directories
        run: |
          mkdir -p ./downloads
          mkdir -p ./report-data

      # Step 4: Unzip binaries
      - name: Extract binaries
        run: unzip -o ./downloads/${{ env.ZIP }} -d ./
        continue-on-error: true

      # Step 5: Repackage binaries
      - name: Package binaries
        run: zip -r ${{ env.ZIP }} ./report-data

      # Step 6: Create a release
      - name: Create GitHub Release
        run: gh release create $(date +'%Y-%m-%d') ${{ env.ZIP }} \
          --title "Updated Binaries" \
          --notes "This release contains the binaries."

Explanation of Key Steps

  1. Authenticating the gh CLI: Authentication is performed using the gh auth login command. For GitHub Enterprise Server, include the –hostname parameter to specify your server’s API endpoint.

  2. Directory Setup: The workflow creates two directories: • downloads: For downloading binaries. • report-data: For storing the extracted or generated data.

  3. Handling Binaries: The workflow unzips the binaries into the workspace and repackages them after making modifications (if any).

  4. Creating a Release: The gh release create command automates the release creation. The release tag is dynamically set to the current date, and the binaries are attached to the release.

Consuming the release binaries

Releases are a powerful way to share compiled binaries or other artifacts across repositories. Depending on your use case, you can consume release binaries from the same repository or an external repository. When working in GitHub Enterprise Server (GHES), additional flags such as –host (to specify the GitHub instance) and –repo (to identify the source repository) are required. For github.com, the --host flag is optional, as default is already configured.

Below is a workflow example that demonstrates how to authenticate the gh CLI, fetch the latest release from a repository, and download specific files based on a pattern.

name: Consume Release binary from same or another repo

on: 
  workflow_dispatch:
    inputs:
      host:
        description: 'GitHub Host'
        required: true
        default: 'github.com'
      repository:
        description: 'Repository to get release from'
        default: "${{ github.repository }}"
        required: false
      file-pattern:
        description: 'Pattern to match files'
        required: true
      download-path:
        description: 'Path to download files'
        required: true

jobs: 
  consume:
    runs-on: ubuntu-latest
    steps:
      # Step 1: Authenticate with the GitHub CLI
      - name: Auth gh cli
        run: |
          echo "${{ secrets.MY_PAT }}" | gh auth login --with-token --hostname ${{inputs.host}}
        shell: bash

      # Step 2: Create a temporary directory for downloads
      - name: Create temp download folder
        run: mkdir -p ${{ inputs.download-path }}
        shell: bash

      # Step 3: Fetch the latest release tag from the target repository
      - name: Get latest release tag from another repo
        id: get_latest_release_other_repo
        run: |
          latest_release_tag=$(gh release view --repo ${{inputs.host}}/${{ inputs.repository }} --json tagName -q '.tagName')
          echo "latest_release_tag=$latest_release_tag" >> $GITHUB_ENV
        shell: bash

      # Step 4: Download files matching the specified pattern
      - name: Download latest release files from different repo
        run: |
          gh release download ${{ env.latest_release_tag }} --repo ${{inputs.host}}/${{ inputs.repository }} --pattern ${{ inputs.file-pattern }} --dir ${{ inputs.download-path }}
        continue-on-error: true
        shell: bash

Key Steps in the Workflow

  1. Authentication: The gh auth login command is used to authenticate the GitHub CLI using the provided token and host. This ensures access to the desired repository.
  2. Directory Setup: A temporary directory is created for downloading files.
  3. Fetching the Release Tag: The gh release view command retrieves the latest release tag from the specified repository.
  4. Downloading Files: The gh release download command fetches files matching the provided pattern from the release and saves them in the specified directory.

Use Case Scenarios

•	Same Repository: If consuming binaries from the same repository, the default values for repository and host will suffice.
•	Another Repository: For binaries in an external repository, specify the --repo flag with the target repository’s path (e.g., owner/repo).

This workflow simplifies integrating release binaries into your workflows, making it easier to share and reuse artifacts across projects.

Benefits of This Approach

  1. Automation: Streamlines binary packaging and release processes.
  2. Reusability: Facilitates consuming release artifacts in other workflows or repositories.
  3. Flexibility: Works with GitHub Enterprise Server as well as github.com.

Conclusion

Automating releases using the GitHub CLI within workflows can significantly improve productivity and ensure consistency. By leveraging GitHub Actions and the gh CLI, you can efficiently manage and utilize release binaries across projects.

Feel free to adapt the workflow to your specific needs and extend it with additional steps for testing, deployment, or other tasks.

Happy coding! 🚀