Skip to content

pvdb/git-semaphore

Repository files navigation

Git::Semaphore

Build Status

Travis CI

Integrate git repositories with their corresponding project on semaphoreci.com (via the Semaphore API)

Features

  • highly opiniated
  • integrated with git
  • caching of API results
  • pagination of API calls
  • enrichment of API data
  • extensive API feature support
  • support for multiple Semaphore accounts

Semaphore API support

The following sections of the Semaphore API are fully or partially supported by git semaphore:

API section summary
authentication API authentication
projects listing projects
branches and builds querying branches and managing builds
servers and deploys querying servers and managing deploys
webhooks listing and managing webhooks

The following Semaphore API features are supported by git semaphore:

API feature command summary
authentication provide user authentication via an authentication token
projects git semaphore --projects list all projects and their current status
project branches git semaphore --branches list all branches for the current project
branch status git semaphore --status list the build status for the current branch
branch history git semaphore --history list the build history for the current branch
build information git semaphore --information detailed information for a given build number (ie. all commits)
build log git semaphore --log execution logs for a given build number (per thread and command)
rebuild git semaphore --rebuild rebuild last revision for the current branch
launch build launch a build for the given commit SHA
stop stop an in-progress build
deploy run a deploy from a given build

Installation

Install the gem:

gem install git-semaphore

And execute it as a git subcommand:

git semaphore <options>

To get an overview of the available options, use:

git-semaphore --help

API authentication

Log into semaphoreci.com and find your authentication token at the bottom of your account settings page... this is also explained in the Semaphore API documentation.

Next, choose one of the following mechanisms to make your API authentication token available to git semaphore...

via local git config (in a git working dir)

git config --local --replace-all semaphore.authtoken "Yds3w6o26FLfJTnVK2y9"

via global git config

git config --global --replace-all semaphore.authtoken "Yds3w6o26FLfJTnVK2y9"

via an environment variable

export SEMAPHORE_AUTH_TOKEN="Yds3w6o26FLfJTnVK2y9"

This is also the order in which tokens are searched for - and hence their precedence - meaning that if you have different Semaphore accounts for different projects (e.g. work and personal projects) then you can configure your respective git repos with the authentication token of the corresponding Semaphore account.

API result caching

For performance reasons (especially for Semaphore API calls that are paginated), to enable offline use of the Semaphore API data, as well as to support interactive use of the data in e.g. irb or pry sessions, git semaphore transparently caches the results of all API calls in the ${HOME}/.git/semaphore/ directory.

This means that running git semaphore commands may return stale data, in cases where things have changed on semaphoreci.com since the last time git semaphore was run.

To update the cached results, the following commands support the --refresh flag:

  • --projects
  • --branches
  • --status
  • --history
  • --information
  • --log

Without the -refresh flag, these options will always return cached - and possibly stale - results (if they were invoked previously, that is, in which case the cache was populated), but when the --refresh flag is used, they will all make a new API call and return the most up-to-date SemaphoreCI data (and update the cached data as a side effect).

Integration with git

When used inside a git repository, git semaphore uses convention over configuration to figure out the relevant settings it needs in order to make valid Semaphore API requests:

setting inside git repo pseudo-code override
owner & name based on ${PWD} Dir.pwd.split('/').last(2) ENV['SEMAPHORE_PROJECT_NAME']
branch name current git branch git symbolic-ref --short HEAD ENV['SEMAPHORE_BRANCH_NAME']
commit SHA current git head git rev-parse HEAD ENV['SEMAPHORE_COMMIT_SHA']
build number last branch build N/A ENV['SEMAPHORE_BUILD_NUMBER']

However, each of these defaults can be overridden by setting the corresponding environment variable, as documented in the above table. The same ENV-based override mechanism can be leveraged to use git semaphore outside of a git repository.

Using the "full name" convention

On your local filesystem, git repositories need to use paths that follow the "full name" convention in use on github.com and semaphoreci.com, ie. the last two path components for the pvdb/git-semaphore repository should be pvdb and git-semaphore respectively, as illustrated on this table:

full name owner name URL / path
pvdb/git-semaphore pvdb git-semaphore
GitHub https://github.com/pvdb/git-semaphore
Semaphore https://semaphoreci.com/pvdb/git-semaphore
filesytem ${HOME}/Projects/pvdb/git-semaphore

Put differently: if you typically create your git repositories in ${HOME}/Projects, and you have the following three git repos...

pvdb/git-meta
pvdb/git-semaphore
pvdb/git-switcher

... then the directory tree should be as follows:

${HOME}/Projects
└── pvdb
    ├── git-meta
    │   └── .git
    ├── git-semaphore
    │   └── .git
    └── git-switcher
        └── .git

So first you have a directory corresponding to the repository owner (pvdb) and one level down you have a directory corresponding to the repository name (git-meta, git-semaphore and git-switcher respectively).

A look behind the scences

The git semaphore --settings command can be used to print out the values for the most relevant settings:

$ git semaphore --settings | jq '.'
{
  "auth_token": "Yds3w6o26FLfJTnVK2y9",
  "project_name": "pvdb/git-semaphore",
  "branch_name": "master",
  "commit_sha": "4b59c3e41ca4592dfb01f77f2163154f3d3532fe",
  "build_number": "35"
}
$ _

The git semaphore --internals command adds all internal settings to the above settings hash.

Available commands

⚠️ all of the below examples need to be run from within a git repository that follows the "full name" convention documented above ⚠️

list the Semaphore settings

git semaphore --settings

(lists things like project name, branch name, commit SHA, etc.)

open the Semaphore page for the project's current branch

git semaphore --browse

(the project and branch names are derived from the current git repository and the current git head)

### delete the local Semapore API cache

git semaphore --clean

(this ensures the Semaphore data is refreshed for the subsequent API calls)

list all Semaphore projects

git semaphore --projects

(for the Semaphore user account corresponding to the authentication token)

list all of the project's branches

git semaphore --branches

(the project name is derived from the current git directory)

build status of the project's current branch

git semaphore --status

(the project and branch names are derived from the current git repository and the current git head)

build history of a project's branch

git semaphore --history

(the project and branch names are derived from the current git repository and the current git head)

commit information for the last build of a project's branch

git semaphore --information

(the project and branch names are derived from the current git repository and the current git head)

build command and logs for the last build of a project's branch

git semaphore --log

Formatting the raw git semaphore JSON output

After installing the indispensable jq utility (brew install jq), the raw JSON output generated by the various git semaphore commands can be formatted and queried as follows:

# pretty-print the git semaphore settings
git semaphore --settings | jq '.'

# pretty-print the git semaphore internals
git semaphore --internals | jq '.'

# list the full name of all Semaphore projects
git semaphore --projects | jq -r '.[] | .full_name'

# get the status of the last build for the current branch
git semaphore --status | jq -r '.result'

# list the build duration (in minutes) for all "passed" builds of the current branch
git semaphore --history | jq -r '.builds | .[] | select(.result == "passed") | (.build_number|tostring) + "\t" + (.duration.minutes|tostring)'

# list all commit SHAs that triggered the latest build
git semaphore --information | jq -r '.commits | .[] | .id'

# list the various thread commands for the latest build
git semaphore --log | jq '.threads | .[] | .commands | .[] | .name'

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake test to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/pvdb/git-semaphore. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

The gem is available as open source under the terms of the MIT License.