Git::Semaphore
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.