Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/scripts/check-pull-request-commit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use strict'

// Runs commitInfo on the checkout that actions/checkout makes for a
// pull_request event: GitHub's merge commit refs/pull/N/merge.
//
// EXPECTED_COMMIT=head: commitInfo reports the pull request's last commit
// EXPECTED_COMMIT=checkout: commitInfo reports the merge commit, as before

const assert = require('assert')
const { execFileSync } = require('child_process')
const { commitInfo } = require('../../src')

const headSha = process.env.HEAD_SHA
const expected = process.env.EXPECTED_COMMIT || 'head'

const git = (...args) =>
execFileSync('git', args, { encoding: 'utf8' }).replace(/\n$/, '')

const checkoutSha = git('rev-parse', 'HEAD')
assert.notStrictEqual(checkoutSha, headSha, 'expected the merge commit')

commitInfo()
.then(info => {
console.log(info)
const sha = expected === 'head' ? headSha : checkoutSha
assert.strictEqual(info.sha, sha)
assert.strictEqual(info.message, git('show', '-s', '--pretty=%B', sha))
assert.strictEqual(info.author, git('show', '-s', '--pretty=%an', sha))
assert.strictEqual(info.email, git('show', '-s', '--pretty=%ae', sha))
console.log(`commitInfo reported ${expected} commit ${sha}`)
})
.catch(e => {
console.error(e)
process.exit(1)
})
48 changes: 48 additions & 0 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Pull request commit
on: pull_request

# the job runs code from the pull request
permissions:
contents: read

jobs:
commit-info:
name: commitInfo (${{ matrix.name }})
runs-on: ubuntu-latest
container: ${{ matrix.container }}
strategy:
fail-fast: false
matrix:
include:
- name: default checkout
fetch-depth: 1
expected: head
- name: full clone
fetch-depth: 0
expected: head
- name: git 2.25
fetch-depth: 1
expected: head
container: mcr.microsoft.com/playwright:v1.28.1-focal
- name: fetch disabled
fetch-depth: 1
expected: checkout
disable-fetch: 'true'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: ${{ matrix.fetch-depth }}
Comment thread
agoldis marked this conversation as resolved.
- uses: actions/setup-node@v4
if: ${{ !matrix.container }}
with:
node-version: 16
# the checkout belongs to another user than the container's root
- if: ${{ matrix.container }}
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- run: git --version && node --version
- run: npm ci --ignore-scripts
- run: node .github/scripts/check-pull-request-commit.js
env:
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
EXPECTED_COMMIT: ${{ matrix.expected }}
CURRENTS_DISABLE_HEAD_COMMIT_FETCH: ${{ matrix.disable-fetch }}
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Collects Git commit info from git CLI

## Install

Requires [Node](https://nodejs.org/en/) version 6 or above.
Requires [Node](https://nodejs.org/en/) version 8 or above.

```sh
npm install --save @currents-dev/commit-info
Expand Down Expand Up @@ -37,6 +37,24 @@ Notes:
- If a command fails, returns `null` for each property
- If you need to debug, run with `DEBUG=commit-info` environment variable.

## 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. 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

If getting the commit information using `git` fails for some reason, you can provide the commit information by setting the environment variables. This module will look at the following environment variables as a fallback
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@currents/commit-info",
"description": "Collects Git commit info from CI or from CLI",
"version": "1.0.1-beta.0",
"version": "1.1.0-beta.0",
"author": "Gleb Bahmutov <gleb.bahmutov@gmail.com>",
"contributors": [
"Gleb Bahmutov <gleb.bahmutov@gmail.com>",
Expand All @@ -28,7 +28,7 @@
}
},
"engines": {
"node": ">=6"
"node": ">=8"
},
"files": [
"src/*.js",
Expand Down
21 changes: 16 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const {
getCommitInfoFromEnvironment,
getGhaEventData
} = require('./utils')
const { getPullRequestHeadCommit } = require('./pull-request-head')
const Promise = require('bluebird')
const { mergeWith, or } = require('ramda')

Expand All @@ -35,12 +36,22 @@ function commitInfo (folder) {
process.env.GITHUB_EVENT_PATH,
process.env.GITHUB_ACTIONS
)
}).then(info => {
const envVariables = getCommitInfoFromEnvironment()
debug('git commit: %o', info)
debug('env commit: %o', envVariables)
return mergeWith(or, envVariables, info)
})
.then(info => {
// COMMIT_INFO_SHA names the commit to report, so it is used as is
if (process.env.COMMIT_INFO_SHA) {
return info
}
return getPullRequestHeadCommit(folder, info.sha, info.ghaEventData).then(
head => Object.assign({}, info, head)
)
})
.then(info => {
const envVariables = getCommitInfoFromEnvironment()
debug('git commit: %o', info)
debug('env commit: %o', envVariables)
return mergeWith(or, envVariables, info)
})
}

module.exports = {
Expand Down
Loading
Loading