Skip to content

Repository files navigation

@currents/commit-info

Collects Git commit info from git CLI

Install

Requires Node version 8 or above.

npm install --save @currents/commit-info

Use

const {commitInfo} = require('@currents/commit-info')
// default folder is current working directory
commitInfo(folder)
  .then(info => {
    // info object will have properties
    // branch
    // message
    // email
    // author
    // sha
    // timestamp (in seconds since epoch)
    // remote (without credentials)
    // ghaEventData (GitHub Actions pull request events only)
  })

Each property comes from the first of these that has a value, or is null:

  1. the COMMIT_INFO_* environment variable, see Fallback environment variables
  2. git, see src/git-api.js
  3. the CI provider's environment variables, see CI provider variables

The remote is the exception: the CI provider's value comes before git. COMMIT_INFO_REMOTE still comes first. On Azure Pipelines, for example, the clone often has an SSH remote, and BUILD_REPOSITORY_URI has the HTTPS URL. The CI providers that set a remote are AWS CodeBuild, Azure Pipelines, Bamboo, Buildkite, CircleCI, Drone, GitLab, Semaphore and Netlify, see src/ci.js.

Notes:

  • git reports no branch for a detached checkout (HEAD), so the branch comes from the CI provider. Branch values from COMMIT_INFO_BRANCH and the CI provider are reported as they are.
  • remote never contains a user name or password, wherever it came from. GitLab's CI_REPOSITORY_URL, for example, holds a job token.
  • Resolves with a Bluebird promise.
  • If you need to debug, run with DEBUG=commit-info environment variable. The debug output does not contain the remote's credentials.
  • When git fails and fields are still empty after the CI provider's variables, commitInfo prints one warning with the git error and the COMMIT_INFO_* variables to set. No warning when there is no repository and the CI provider's variables fill the fields, or when there is no repository and no CI provider.
  • When git is not installed or not in PATH, all the git values are empty and the warning says that git was not found in PATH. Install git or set the COMMIT_INFO_* variables.

CI provider variables

When git does not return a value, it comes from the variables of the CI provider the process runs on. The remote comes from these variables first. The branch comes from:

Provider Branch
GitHub Actions GH_BRANCH, GITHUB_HEAD_REF (pull requests), GITHUB_REF_NAME, or GITHUB_REF without refs/heads/ or refs/tags/
GitLab CI_COMMIT_REF_NAME
CircleCI CIRCLE_BRANCH
Jenkins CHANGE_BRANCH (multibranch pull requests), or GIT_BRANCH without origin/, refs/remotes/origin/ or refs/heads/
Azure Pipelines SYSTEM_PULLREQUEST_SOURCEBRANCH without refs/heads/ (pull requests), or BUILD_SOURCEBRANCHNAME, which is only the last segment: x for feature/x
Bitbucket Pipelines BITBUCKET_BRANCH
Buildkite BUILDKITE_BRANCH

AWS CodeBuild gives no branch. The other properties and providers are in src/ci.js. getCiCommitInfo() returns these values and the provider name.

Containers

git 2.35.2 and later refuse to read a repository owned by another user, with fatal: unsafe repository (2.35.2 to 2.37.x) or fatal: detected dubious ownership in repository (2.38.0 and later). This is common when a container runs as root on a checkout made by another user. On CI, the read-only git commands then run again with -c safe.directory=*. CI means that the CI variable is set to a value other than false or 0, or that one of the CI providers in src/ci-provider.js is detected; Jenkins, for example, does not set CI. GOOGLE_CLOUD_PROJECT, GCP_PROJECT, GCLOUD_PROJECT and JENKINS_HOME do not count, because developers often have them set in their shell. * because the folder can be a subfolder of the repository.

git 2.35.2 to 2.37.x ignore safe.directory on the command line, so there commitInfo prints the warning (git 2.38.0 and later respect it); run git config --global --add safe.directory '*' in the container or set the COMMIT_INFO_* variables.

Pull request builds

On pull request builds many CI providers check out a commit that merges the pull request into its target branch. GitHub Actions, for example, checks out refs/pull/<number>/merge, whose message is Merge <sha> into <sha>.

When the checked-out commit is such a merge, commitInfo reports the pull request's last commit instead: its sha, message, email, author and timestamp. It finds that commit in:

  • GitHub Actions: pull_request.head.sha in the event file (GITHUB_EVENT_PATH)
  • GitLab merged results pipelines: CI_MERGE_REQUEST_SOURCE_BRANCH_SHA
  • Azure Pipelines: SYSTEM_PULLREQUEST_SOURCECOMMITID
  • Travis CI: TRAVIS_PULL_REQUEST_SHA
  • Semaphore: SEMAPHORE_GIT_PR_SHA
  • Buildkite: BUILDKITE_PULL_REQUEST_HEAD_COMMIT
  • Bitbucket Pipelines: BITBUCKET_COMMIT

The commit is used only when the checked-out commit is a merge and the commit is one of its parents. If a shallow clone does not contain it (for example actions/checkout with the default fetch-depth: 1), it is fetched with git fetch --depth=1 origin <sha>, with a 3 second timeout. If the fetch fails, the checked-out commit is reported. The fetch does not use the safe.directory retry. Set CURRENTS_DISABLE_HEAD_COMMIT_FETCH=true to skip the fetch.

The COMMIT_INFO_* variables below still take priority. When COMMIT_INFO_SHA is set, the pull request's commit is not looked up.

Fallback environment variables

You can provide the commit information by setting these environment variables. They take priority over git and the CI provider's variables.

branch: COMMIT_INFO_BRANCH
message: COMMIT_INFO_MESSAGE
email: COMMIT_INFO_EMAIL
author: COMMIT_INFO_AUTHOR
sha: COMMIT_INFO_SHA
timestamp: COMMIT_INFO_TIMESTAMP
remote: COMMIT_INFO_REMOTE

For Docker containers

When running your application inside a Docker container, you should set these environment variables using -e syntax.

$ docker run \
  -e COMMIT_INFO_BRANCH=develop \
  -e COMMIT_INFO_SHA=e5d9eb66474bc0b681da9240aa5a457fe17bc8f3 \
  <container name>

See docker-example for a full example.

Individual methods

In addition to commitInfo this module also exposes individual promise-returning methods getBranch, getMessage, getEmail, getAuthor, getSha, getTimestamp, getRemoteOrigin. These methods use git only, not the environment variables. getRemoteOrigin returns the remote without credentials.

Other exports:

  • getCiCommitInfo(env = process.env): the CI provider's values, see CI provider variables. The remote has no credentials.
  • detectCiProvider(env = process.env): the CI provider name, such as githubActions, or null.
  • removeCredentials(url): removes the user name and password from a URL, keeping the port. Returns other values, such as git@github.com:o/r.git, as they are.

For example

const {getAuthor} = require('@currents/commit-info')
getAuthor('path/to/repo')
  .then(name => ...)

getBranch

Resolves with the current git branch name or null.

const {getBranch} = require('@currents/commit-info')
getBranch()
  .then(branch => ...)
  • If this is detached commit (reporting HEAD), returns null

Small print

License: MIT - do anything with the code, but don't blame me if it does not work.

Support: if you find any problems with this module, email / tweet / open issue on Github

MIT License

Copyright (c) 2017 Cypress.io

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages