Skip to content

gitsudo-io/ghctl

Repository files navigation

ghctl - A GitHub utility

Tests

ghctl is both a command-line utility for GitHub, and a GitHub Action that allows you to use the utility in your GitHub Actions workflows.

NOTE: ghctl is in early development and is not quite ready for production use. However, please feel free to try it out and provide feedback!

ghctl CLI

ghctl currently requires a GitHub Personal Access Token (PAT) with at least the following scopes:

  • read:org
  • repo (full control)
  • read:user

You can provide the access token to ghctl in one of the following ways:

  • set the $GITHUB_TOKEN environment variable
  • explicitly pass it using the --access-token option

Download the latest release binary

You can download the latest release binary (built for Debian Bookworm / Ubuntu 22.04 ) from the Releases page, using the GitHub CLI (gh) or just curl:

gh release download -R gitsudo-io/ghctl --pattern ghctl
curl -L https://github.com/gitsudo-io/ghctl/releases/download/v0.3.1/ghctl > ghctl

Then make the file executable (chmod u+x ghctl) and place it in your $PATH.

Install using Cargo

To install the ghctl binary using Cargo, you will need to have Rust 1.66.0 or later installed (rustup).

cargo install ghctl

Local Development / Installation from source

To build and install the ghctl binary locally, you will need to have Rust 1.66.0 or later installed (rustup).

Clone this repository

git clone https://github.com/gitsudo-io/ghctl.git

Build and install the ghctl binary

cargo install --path ghctl

Usage

Retrieve GitHub repository information

ghctl repo get "{owner}/{repo}" will retrieve information about the specified GitHub repository and output it as JSON.

$ ghctl repo get gitsudo-io/ghctl --access-token $GITHUB_TOKEN
ghctl repo get gitsudo-io/ghctl
{
  "id": 647928865,
  "node_id": "R_kgDOJp6cIQ",
  "name": "ghctl",
  "full_name": "gitsudo-io/ghctl",
  "owner": {
    "login": "gitsudo-io",
    "id": 121780924,
...

Retrieve a GitHub repository's configuration

ghctl repo config get "{owner}/{repo}" will retrieve the configuration for the specified GitHub repository and output it as YAML.

For example:

ghctl repo config get gitsudo-io/ghctl

Will output something like:

teams:
  a-team: maintain
environments:
  gigalixir:
    reviewers:
    - aisrael
    - gitsudo-io/a-team
branch_protection_rules:
  main:
    require_pull_request:
      required_approving_review_count: 1
      dismiss_stale_reviews: false
      require_code_owner_reviews: false
    required_status_checks:
      strict: false
      contexts:
      - mix/test
    enforce_admins: false

The output of ghctl repo config get is suitable for use with ghctl repo config apply (see below).

Apply a GitHub repository configuration to a repository

ghctl repo apply "{owner}/{repo}" --config-file {config_file} will read the specified YAML configuration file and apply it to the specified GitHub repository.

The configuration file should be a YAML file and currently supports the following sections:

Repository team permissions

teams:
  {team-slug}: {permission}

Where {team-slug} is the team slug on GitHub, and {permission} is one of pull, triage, push, maintain, or admin.

Example:

teams:
  a-team: maintain

When applied to a repository, will grant the a-team team maintain permissions on the repository.

Repository collaborators

collaborators:
  {username}: {permission}

Where {username} is the GitHub username, and {permission} is one of pull, triage, push, maintain, or admin.

Example:

collaborators:
  aisrael: admin

Deployment Environments

environments:
  {environment}:
    reviewers:
      - {username}, or
      - {org}/{team-slug}

Where {environment} is the name of the deployment environment, {username} is the GitHub username, or, if {org}/{team-slug} is given, then it references a GitHub organization and team.

Example:

environments:
  gigalixir:
    reviewers:
      - aisrael
      - gitsudo-io/a-team

When applied to a repository, will create the deployment environment and configure its reviewers accordingly.

Branch Protection Rules

branch_protection_rules:
  {branch name}:
    required_status_checks:
      contexts:
        - {status check name}
        - ...
    require_pull_request: true

Where {branch name} is the name of the branch to protect.

The required_status_checks is optional, and if given, will require the specified status checks to pass before allowing a branch to be merged. Specify any required status checks by name in the contexts list.

The require_pull_request is optional, and if given, will require all commits to be made via a pull request.

Example:

branch_protection_rules:
  main:
    required_status_checks:
      contexts:
        - "mix/test"
        - "mix/credo"
    require_pull_request: true

When applied to a repositody, will protect the main branch and require a pull request before merging, and require the mix/test and mix/credo status checks to pass before allowing a branch to be merged.

Full example

Given a gitsudo.yaml file containing:

teams:
  a-team: maintain
collaborators:
  aisrael: admin
environments:
  gigalixir:
    reviewers:
      - aisrael
      - gitsudo-io/a-team
branch_protection_rules:
  main:
    required_status_checks:
      contexts:
        - "mix/test"
    require_pull_request: true

When we execute:

ghctl repo config apply gitsudo-io/gitsudo --access-token ${GHCTL_ACCESS_TOKEN} -F gitsudo.yaml

Then we should see output similar to the following:

[2023-06-16T18:33:34Z INFO ] Added team a-team with permission Maintain to repository gitsudo-io/gitsudo
[2023-06-16T18:33:34Z INFO ] Updated collaborator aisrael with permission admin to repository gitsudo-io/gitsudo
[2023-06-16T18:33:34Z INFO ] Created deployment environment gigalixir in repository gitsudo-io/gitsudo
[2023-06-16T18:33:35Z INFO ] Applied branch protection rules to branch main in repository gitsudo-io/gitsudo
[2023-06-16T18:33:35Z INFO ] Applied configuration to gitsudo-io/gitsudo

ghctl GitHub Action

GitHub Action for ghctl

Inputs

Name Description Required Default
args Program arguments Required

gitsudo-io/ghctl is also a GitHub Action that allows you to use the ghctl utility in your GitHub Actions workflows.

For example, given the following workflow:

name: Configure ghctl repository
on: 
  push:
  workflow_dispatch:

jobs:
  ghctl-repo-config-apply:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: gitsudo-io/ghctl@main
        with:
            args: repo config apply gitsudo-io/gitsudo --access-token ${{ secrets.GHCTL_ACCESS_TOKEN }} -F gitsudo.yaml

Then executing the workflow above will perform the equivalent of the earlier command.