Home

Awesome

<!--- This README file is generated. Changes will be overwritten. -->

A GitHub API client library written in POSIX sh

https://github.com/whiteinge/ok.sh BSD licensed.

Requirements

Optional requirements

Setup

Authentication credentials are read from a $HOME/.netrc file on UNIX machines or a _netrc file in %HOME% for UNIX environments under Windows. Generate the token on GitHub under "Account Settings -> Applications". Restrict permissions on that file with chmod 600 ~/.netrc!

machine api.github.com
    login <username>
    password <token>

machine uploads.github.com
    login <username>
    password <token>

Or set an environment GITHUB_TOKEN=token

Configuration

The following environment variables may be set to customize ok.sh.

Usage

ok.sh [<flags>] (command [<arg>, <name=value>...])

ok.sh -h              # Short, usage help text.
ok.sh help            # All help text. Warning: long!
ok.sh help command    # Command-specific help text.
ok.sh command         # Run a command with and without args.
ok.sh command foo bar baz=Baz qux='Qux arg here'
FlagDescription
-VShow version.
-hShow this screen.
-jOutput raw JSON; don't process with jq.
-qQuiet; don't print to stdout.
-rPrint current GitHub API rate limit to stderr.
-vLogging output; specify multiple times: info, debug, trace.
-xEnable xtrace debug logging.
-yAnswer 'yes' to any prompts.

Flags must be the first argument to ok.sh, before command.

Table of Contents

Utility and request/response commands

GitHub commands

Commands

_all_funcs

List all functions found in the current file in the order they appear

Keyword arguments

_log

A lightweight logging system based on file descriptors

Usage:

_log debug 'Starting the combobulator!'

Positional arguments

_helptext

Extract contiguous lines of comments and function params as help text

Indentation will be ignored. She-bangs will be ignored. Local variable declarations and their default values can also be pulled in as documentation. Exits upon encountering the first blank line.

Exported environment variables can be used for string interpolation in the extracted commented text.

Input

_format_json

Create formatted JSON from name=value pairs

Usage:

ok.sh _format_json foo=Foo bar=123 baz=true qux=Qux=Qux quux='Multi-line
string' quuz=\'5.20170918\' \
  corge="$(ok.sh _format_json grault=Grault)" \
  garply="$(ok.sh _format_json -a waldo true 3)"

Return:

{
  "garply": [
    "waldo",
    true,
    3
  ],
  "foo": "Foo",
  "corge": {
    "grault": "Grault"
  },
  "baz": true,
  "qux": "Qux=Qux",
  "quux": "Multi-line\nstring",
  "quuz": "5.20170918",
  "bar": 123
}

Tries not to quote numbers, booleans, nulls, or nested structures. Note, nested structures must be quoted since the output contains spaces.

The -a option will create an array instead of an object. This option must come directly after the _format_json command and before any operands. E.g., _format_json -a foo bar baz.

If jq is installed it will also validate the output.

Positional arguments

_format_urlencode

URL encode and join name=value pairs

Usage:

_format_urlencode foo='Foo Foo' bar='<Bar>&/Bar/'

Return:

foo=Foo%20Foo&bar=%3CBar%3E%26%2FBar%2F

Ignores pairs if the value begins with an underscore.

_filter_json

Filter JSON input using jq; outputs raw JSON if jq is not installed

Usage:

printf '[{"foo": "One"}, {"foo": "Two"}]' | \
    ok.sh _filter_json '.[] | "\(.foo)"'

_get_mime_type

Guess the mime type for a file based on the file extension

Usage:

local mime_type
_get_mime_type "foo.tar"; printf 'mime is: %s' "$mime_type"

Sets the global variable mime_type with the result. (If this function is called from within a function that has declared a local variable of that name it will update the local copy and not set a global.)

Positional arguments

_get_confirm

Prompt the user for confirmation

Usage:

local confirm; _get_confirm
[ "$confirm" -eq 1 ] && printf 'Good to go!\n'

If global confirmation is set via $OK_SH_DESTRUCTIVE then the user is not prompted. Assigns the user's confirmation to the confirm global variable. (If this function is called within a function that has a local variable of that name, the local variable will be updated instead.)

Positional arguments

_opts_filter

Extract common jq filter keyword options and assign to vars

Usage:

local filter
_opts_filter "$@"

_opts_pagination

Extract common pagination keyword options and assign to vars

Usage:

local _follow_next
_opts_pagination "$@"

_opts_qs

Extract common query string keyword options and assign to vars

Usage:

local qs
_opts_qs "$@"
_get "/some/path"

_request

A wrapper around making HTTP requests with curl

Usage:

# Get JSON for all issues:
_request /repos/saltstack/salt/issues

# Send a POST request; parse response using jq:
printf '{"title": "%s", "body": "%s"}\n' "Stuff" "Things" \
  | _request /some/path | jq -r '.[url]'

# Send a PUT request; parse response using jq:
printf '{"title": "%s", "body": "%s"}\n' "Stuff" "Things" \
  | _request /repos/:owner/:repo/issues method=PUT | jq -r '.[url]'

# Send a conditional-GET request:
_request /users etag=edd3a0d38d8c329d3ccc6575f17a76bb

Input

Positional arguments

Keyword arguments

_response

Process an HTTP response from curl

Output only headers of interest followed by the response body. Additional processing is performed on select headers to make them easier to parse using shell tools.

Usage:

# Send a request; output the response and only select response headers:
_request /some/path | _response status_code ETag Link_next

# Make request using curl; output response with select response headers;
# assign response headers to local variables:
curl -isS example.com/some/path | _response status_code status_text | {
  local status_code status_text
  read -r status_code
  read -r status_text
}

Header reformatting

Positional arguments

_get

A wrapper around _request() for common GET patterns

Will automatically follow 'next' pagination URLs in the Link header.

Usage:

_get /some/path
_get /some/path _follow_next=0
_get /some/path _follow_next_limit=200 | jq -c .

Positional arguments

Keyword arguments

_post

A wrapper around _request() for common POST / PUT patterns

Usage:

_format_json foo=Foo bar=Bar | _post /some/path
_format_json foo=Foo bar=Bar | _post /some/path method='PUT'
_post /some/path filename=somearchive.tar
_post /some/path filename=somearchive.tar mime_type=application/x-tar
_post /some/path filename=somearchive.tar \
  mime_type=$(file -b --mime-type somearchive.tar)

Input

Positional arguments

Keyword arguments

_delete

A wrapper around _request() for common DELETE patterns

Usage:

_delete '/some/url'

Return: 0 for success; 1 for failure.

Positional arguments

help

Output the help text for a command

Usage:

help commandname

Positional arguments

show_scopes

Show the permission scopes for the currently authenticated user

Usage:

show_scopes

org_repos

List organization repositories

Usage:

org_repos myorg
org_repos myorg type=private per_page=10
org_repos myorg _filter='.[] | "\(.name)\t\(.owner.login)"'

Positional arguments

Keyword arguments

Querystring arguments may also be passed as keyword arguments:

org_teams

List teams

Usage:

org_teams org

Positional arguments

Keyword arguments

org_members

List organization members

Usage:

org_members org

Positional arguments

Keyword arguments

org_collaborators

List organization outside collaborators

Usage:

org_collaborators org

Positional arguments

Keyword arguments

org_auditlog

Interact with the Github Audit Log

Usage:

org_auditlog org

Positional arguments

Keyword arguments

team_members

List team members

Usage:

team_members team_id

Positional arguments

Keyword arguments

list_repos

List user repositories

Usage:

list_repos
list_repos user

Positional arguments

Keyword arguments

Querystring arguments may also be passed as keyword arguments:

list_branches

List branches of a specified repository. ( https://developer.github.com/v3/repos/#list_branches )

Usage:

list_branches user repo

Positional arguments

GitHub user login or id for which to list branches Name of the repo for which to list branches

Keyword arguments

Querystring arguments may also be passed as keyword arguments:

list_commits

List commits of a specified repository. ( https://developer.github.com/v3/repos/commits/#list-commits-on-a-repository )

Usage:

list_commits user repo

Positional arguments

GitHub user login or id for which to list branches Name of the repo for which to list branches

list_contributors

List contributors to the specified repository, sorted by the number of commits per contributor in descending order. ( https://developer.github.com/v3/repos/#list-contributors )

Usage:

list_contributors user repo

Positional arguments

Keyword arguments

Querystring arguments may also be passed as keyword arguments:

list_collaborators

List collaborators to the specified repository, sorted by the number of commits per collaborator in descending order. ( https://developer.github.com/v3/repos/#list-collaborators )

Usage:

list_collaborators someuser/somerepo

Positional arguments GitHub user login or id for which to list collaborators Name of the repo for which to list collaborators

Keyword arguments

Querystring arguments may also be passed as keyword arguments:

list_hooks

List webhooks from the specified repository. ( https://developer.github.com/v3/repos/hooks/#list-hooks )

Usage:

list_hooks owner/repo

Positional arguments

list_gists

List gists for the current authenticated user or a specific user

https://developer.github.com/v3/gists/#list-a-users-gists

Usage:

list_gists
list_gists <username>

Positional arguments

Keyword arguments

public_gists

List public gists

https://developer.github.com/v3/gists/#list-all-public-gists

Usage:

public_gists

Keyword arguments

gist

Get a single gist

https://developer.github.com/v3/gists/#get-a-single-gist

Usage:

get_gist

Positional arguments

Keyword arguments

add_collaborator

Add a collaborator to a repository

Usage:

add_collaborator someuser/somerepo collaboratoruser permission

Positional arguments

Keyword arguments

delete_collaborator

Delete a collaborator to a repository

Usage:

delete_collaborator someuser/somerepo collaboratoruser permission

Positional arguments

create_repo

Create a repository for a user or organization

Usage:

create_repo foo
create_repo bar description='Stuff and things' homepage='example.com'
create_repo baz organization=myorg

Positional arguments

Keyword arguments

POST data may also be passed as keyword arguments:

delete_repo

Delete a repository for a user or organization

Usage:

delete_repo owner repo

The currently authenticated user must have the delete_repo scope. View current scopes with the show_scopes() function.

Positional arguments

fork_repo

Fork a repository from a user or organization to own account or organization

Usage:

fork_repo owner repo

Positional arguments

Keyword arguments

POST data may also be passed as keyword arguments:

list_releases

List releases for a repository

https://developer.github.com/v3/repos/releases/#list-releases-for-a-repository

Usage:

list_releases org repo '\(.assets[0].name)\t\(.name.id)'

Positional arguments

Keyword arguments

release

Get a release

https://developer.github.com/v3/repos/releases/#get-a-single-release

Usage:

release user repo 1087855

Positional arguments

Keyword arguments

create_release

Create a release

https://developer.github.com/v3/repos/releases/#create-a-release

Usage:

create_release org repo v1.2.3
create_release user repo v3.2.1 draft=true

Positional arguments

Keyword arguments

POST data may also be passed as keyword arguments:

edit_release

Edit a release

https://developer.github.com/v3/repos/releases/#edit-a-release

Usage:

edit_release org repo 1087855 name='Foo Bar 1.4.6'
edit_release user repo 1087855 draft=false

Positional arguments

Keyword arguments

POST data may also be passed as keyword arguments:

delete_release

Delete a release

https://developer.github.com/v3/repos/releases/#delete-a-release

Usage:

delete_release org repo 1087855

Return: 0 for success; 1 for failure.

Positional arguments

release_assets

List release assets

https://developer.github.com/v3/repos/releases/#list-assets-for-a-release

Usage:

release_assets user repo 1087855

Example of downloading release assets:

ok.sh release_assets <user> <repo> <release_id> \
        _filter='.[] | .browser_download_url' \
    | xargs -L1 curl -L -O

Example of the multi-step process for grabbing the release ID for a specific version, then grabbing the release asset IDs, and then downloading all the release assets (whew!):

username='myuser'
repo='myrepo'
release_tag='v1.2.3'
ok.sh list_releases "$myuser" "$myrepo" \
    | awk -F'\t' -v tag="$release_tag" '$2 == tag { print $3 }' \
    | xargs -I{} ./ok.sh release_assets "$myuser" "$myrepo" {} \
        _filter='.[] | .browser_download_url' \
    | xargs -L1 curl -n -L -O

Positional arguments

Keyword arguments

upload_asset

Upload a release asset

https://developer.github.com/v3/repos/releases/#upload-a-release-asset

Usage:

upload_asset https://<upload-url> /path/to/file.zip

The upload URL can be gotten from release(). There are multiple steps required to upload a file: get the release ID, get the upload URL, parse the upload URL, then finally upload the file. For example:

USER="someuser"
REPO="somerepo"
TAG="1.2.3"
FILE_NAME="foo.zip"
FILE_PATH="/path/to/foo.zip"

# Create a release then upload a file:
ok.sh create_release "$USER" "$REPO" "$TAG" _filter='.upload_url' \
    | sed 's/{.*$/?name='"$FILE_NAME"'/' \
    | xargs -I@ ok.sh upload_asset @ "$FILE_PATH"

# Find a release by tag then upload a file:
ok.sh list_releases "$USER" "$REPO" \
    | awk -v "tag=$TAG" -F'\t' '$2 == tag { print $3 }' \
    | xargs -I@ ok.sh release "$USER" "$REPO" @ _filter='.upload_url' \
    | sed 's/{.*$/?name='"$FILE_NAME"'/' \
    | xargs -I@ ok.sh upload_asset @ "$FILE_PATH"

Positional arguments

The parsed upload_url returned from GitHub.

Keyword arguments

Also any other keyword arguments accepted by _post().

delete_asset

Delete a release asset

https://docs.github.com/en/rest/reference/releases#delete-a-release-asset

Usage:

delete_asset user repo 51955388

Example of deleting release assets:

ok.sh release_assets <user> <repo> <release_id> \
        _filter='.[] | .id' \
    | xargs -L1 ./ok.sh delete_asset "$myuser" "$myrepo"

Example of the multi-step process for grabbing the release ID for a specific version, then grabbing the release asset IDs, and then deleting all the release assets (whew!):

username='myuser'
repo='myrepo'
release_tag='v1.2.3'
ok.sh list_releases "$myuser" "$myrepo" \
    | awk -F'\t' -v tag="$release_tag" '$2 == tag { print $3 }' \
    | xargs -I{} ./ok.sh release_assets "$myuser" "$myrepo" {} \
        _filter='.[] | .id' \
    | xargs -L1 ./ok.sh -y delete_asset "$myuser" "$myrepo"

Positional arguments

list_milestones

List milestones for a repository

Usage:

list_milestones someuser/somerepo
list_milestones someuser/somerepo state=closed

Positional arguments

Keyword arguments

GitHub querystring arguments may also be passed as keyword arguments:

create_milestone

Create a milestone for a repository

Usage:

create_milestone someuser/somerepo MyMilestone

create_milestone someuser/somerepo MyMilestone \
    due_on=2015-06-16T16:54:00Z \
    description='Long description here
that spans multiple lines.'

Positional arguments

Keyword arguments

Milestone options may also be passed as keyword arguments:

list_issue_comments

List comments of a specified issue. ( https://developer.github.com/v3/issues/comments/#list-issue-comments )

Usage:

list_issue_comments someuser/somerepo number

Positional arguments

GitHub owner login or id for which to list branches Name of the repo for which to list branches Issue number

add_comment

Add a comment to an issue

Usage:

add_comment someuser/somerepo 123 'This is a comment'

Positional arguments

Keyword arguments

list_commit_comments

List comments of a specified commit. ( https://developer.github.com/v3/repos/comments/#list-commit-comments )

Usage:

list_commit_comments someuser/somerepo sha

Positional arguments

GitHub owner login or id for which to list branches Name of the repo for which to list branches Commit SHA

add_commit_comment

Add a comment to a commit

Usage:

add_commit_comment someuser/somerepo 123 'This is a comment'

Positional arguments

Keyword arguments

close_issue

Close an issue

Usage:

close_issue someuser/somerepo 123

Positional arguments

Keyword arguments

POST data may also be passed as keyword arguments:

list_issues

List issues for the authenticated user or repository

Usage:

list_issues
list_issues someuser/somerepo
list_issues <any of the above> state=closed labels=foo,bar

Positional arguments

user or user/repository

Keyword arguments

GitHub querystring arguments may also be passed as keyword arguments:

user_issues

List all issues across owned and member repositories for the authenticated user

Usage:

user_issues
user_issues since=2015-60-11T00:09:00Z

Keyword arguments

GitHub querystring arguments may also be passed as keyword arguments:

create_issue

Create an issue

Usage:

create_issue owner repo 'Issue title' body='Add multiline body
content here' labels="$(./ok.sh _format_json -a foo bar)"

Positional arguments

Keyword arguments

Additional issue fields may be passed as keyword arguments:

org_issues

List all issues for a given organization for the authenticated user

Usage:

org_issues someorg

Positional arguments

Keyword arguments

GitHub querystring arguments may also be passed as keyword arguments:

list_starred

List starred repositories

Usage:

list_starred
list_starred user

Positional arguments

Keyword arguments

Querystring arguments may also be passed as keyword arguments:

list_my_orgs

List your organizations

Usage:

list_my_orgs

Keyword arguments

list_orgs

List all organizations

Usage:

list_orgs

Keyword arguments

list_users

List all users

Usage:

list_users

Keyword arguments

labels

List available labels for a repository

Usage:

labels someuser/somerepo

Positional arguments

Keyword arguments

add_label

Add a label to a repository

Usage:

add_label someuser/somerepo LabelName color

Positional arguments

Keyword arguments

update_label

Update a label

Usage:

update_label someuser/somerepo OldLabelName \
    label=NewLabel color=newcolor

Positional arguments

Keyword arguments

Label options may also be passed as keyword arguments, these will update the existing values:

add_team_repo

Add a team repository

Usage:

add_team_repo team_id organization repository_name permission

Positional arguments

list_pulls

Lists the pull requests for a repository

Usage:

list_pulls user repo

Positional arguments

Keyword arguments

create_pull_request

Create a pull request for a repository

Usage:

create_pull_request someuser/somerepo title head base

create_pull_request someuser/somerepo title head base body='Description here.'

Positional arguments

Keyword arguments

Pull request options may also be passed as keyword arguments:

update_pull_request

Update a pull request for a repository

Usage:

update_pull_request someuser/somerepo number title='New title' body='New body'

Positional arguments

Keyword arguments

Pull request options may also be passed as keyword arguments:

transfer_repo

Transfer a repository to a user or organization

Usage:

transfer_repo owner repo new_owner
transfer_repo owner repo new_owner team_ids='[ 12, 345 ]'

Positional arguments

Keyword arguments

POST data may also be passed as keyword arguments:

archive_repo

Archive a repo

Usage:

archive_repo owner/repo

Positional arguments