Skip to content

[ci-app][CIAPP-936] Add More Git Metadata to Tests #1254

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Mar 25, 2021
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
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ node_modules
protobuf
versions
acmeair-nodejs
vendor
1 change: 1 addition & 0 deletions LICENSE-3rdparty.csv
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,4 @@ dev,tape,MIT,Copyright James Halliday
dev,wait-on,MIT,Copyright 2015 Jeff Barczewski
file,profile.proto,Apache license 2.0,Copyright 2016 Google Inc.
file,TDigest.h,Apache license 2.0,Copyright Derrick R. Burns
file,git-repo-info.js,MIT,Copyright Robert Jackson and Contributors
8 changes: 7 additions & 1 deletion packages/dd-trace/src/plugins/util/ci-app-spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"test.framework",
"test.suite",
"test.name",
"resource.name",
"ci.pipeline.id",
"ci.pipeline.name",
"ci.pipeline.number",
Expand All @@ -18,6 +17,13 @@
"git.commit.sha",
"git.branch",
"git.tag",
"git.commit.message",
"git.commit.committer.date",
"git.commit.committer.email",
"git.commit.committer.name",
"git.commit.author.date",
"git.commit.author.email",
"git.commit.author.name",
"os.platform",
"os.version",
"os.architecture",
Expand Down
76 changes: 67 additions & 9 deletions packages/dd-trace/src/plugins/util/git.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,80 @@
const coalesce = require('koalas')
const getRepoInfo = require('../../../../../vendor/git-repo-info')

const { sanitizedExec } = require('./exec')

const GIT_COMMIT_SHA = 'git.commit.sha'
const GIT_BRANCH = 'git.branch'
const GIT_REPOSITORY_URL = 'git.repository_url'
const GIT_TAG = 'git.tag'
const GIT_COMMIT_MESSAGE = 'git.commit.message'
const GIT_COMMIT_COMMITTER_DATE = 'git.commit.committer.date'
const GIT_COMMIT_COMMITTER_EMAIL = 'git.commit.committer.email'
const GIT_COMMIT_COMMITTER_NAME = 'git.commit.committer.name'
const GIT_COMMIT_AUTHOR_DATE = 'git.commit.author.date'
const GIT_COMMIT_AUTHOR_EMAIL = 'git.commit.author.email'
const GIT_COMMIT_AUTHOR_NAME = 'git.commit.author.name'

// Receives a string with the form 'John Doe <[email protected]>'
// and returns { name: 'John Doe', email: '[email protected]' }
function parseUser (user) {
if (!user) {
return { name: '', email: '' }
}
let email = ''
const matchEmail = user.match(/[^@<\s]+@[^@\s>]+/g)
if (matchEmail) {
email = matchEmail[0]
}
return { name: user.replace(`<${email}>`, '').trim(), email }
}

// If there is ciMetadata, it takes precedence.
function getGitMetadata (ciMetadata) {
const { commitSHA, branch, repositoryUrl } = ciMetadata
// With stdio: 'pipe', errors in this command will not be output to the parent process,
// so if `git` is not present in the env, we'll just fallback to the default
// and not show a warning to the user.
const execOptions = { stdio: 'pipe' }
const { commitSHA, branch, repositoryUrl, tag } = ciMetadata

const {
author,
committer,
authorDate,
committerDate,
commitMessage,
branch: gitBranch,
tag: gitTag,
sha: gitCommitSHA
} = getRepoInfo(process.cwd())

const { name: authorName, email: authorEmail } = parseUser(author)
const { name: committerName, email: committerEmail } = parseUser(committer)

return {
[GIT_REPOSITORY_URL]: repositoryUrl || sanitizedExec('git ls-remote --get-url', execOptions),
[GIT_BRANCH]: branch || sanitizedExec('git rev-parse --abbrev-ref HEAD', execOptions),
[GIT_COMMIT_SHA]: commitSHA || sanitizedExec('git rev-parse HEAD', execOptions)
// With stdio: 'pipe', errors in this command will not be output to the parent process,
// so if `git` is not present in the env, we won't show a warning to the user.
[GIT_REPOSITORY_URL]: repositoryUrl || sanitizedExec('git ls-remote --get-url', { stdio: 'pipe' }),
[GIT_BRANCH]: coalesce(branch, gitBranch),
[GIT_COMMIT_SHA]: coalesce(commitSHA, gitCommitSHA),
[GIT_TAG]: coalesce(tag, gitTag),
[GIT_COMMIT_MESSAGE]: commitMessage,
[GIT_COMMIT_AUTHOR_DATE]: authorDate,
[GIT_COMMIT_AUTHOR_NAME]: authorName,
[GIT_COMMIT_AUTHOR_EMAIL]: authorEmail,
[GIT_COMMIT_COMMITTER_DATE]: committerDate,
[GIT_COMMIT_COMMITTER_NAME]: committerName,
[GIT_COMMIT_COMMITTER_EMAIL]: committerEmail
}
}

module.exports = { getGitMetadata, GIT_COMMIT_SHA, GIT_BRANCH, GIT_REPOSITORY_URL, GIT_TAG }
module.exports = {
getGitMetadata,
GIT_COMMIT_SHA,
GIT_BRANCH,
GIT_REPOSITORY_URL,
GIT_TAG,
GIT_COMMIT_MESSAGE,
GIT_COMMIT_COMMITTER_DATE,
GIT_COMMIT_COMMITTER_EMAIL,
GIT_COMMIT_COMMITTER_NAME,
GIT_COMMIT_AUTHOR_DATE,
GIT_COMMIT_AUTHOR_EMAIL,
GIT_COMMIT_AUTHOR_NAME
}
7 changes: 4 additions & 3 deletions packages/dd-trace/src/plugins/util/test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { getGitMetadata, GIT_BRANCH, GIT_COMMIT_SHA, GIT_REPOSITORY_URL } = require('./git')
const { getGitMetadata, GIT_BRANCH, GIT_COMMIT_SHA, GIT_REPOSITORY_URL, GIT_TAG } = require('./git')
const { getCIMetadata } = require('./ci')
const { getRuntimeAndOSMetadata } = require('./env')

Expand All @@ -23,10 +23,11 @@ function getTestEnvironmentMetadata (testFramework) {
const {
[GIT_COMMIT_SHA]: commitSHA,
[GIT_BRANCH]: branch,
[GIT_REPOSITORY_URL]: repositoryUrl
[GIT_REPOSITORY_URL]: repositoryUrl,
[GIT_TAG]: tag
} = ciMetadata

const gitMetadata = getGitMetadata({ commitSHA, branch, repositoryUrl })
const gitMetadata = getGitMetadata({ commitSHA, branch, repositoryUrl, tag })

const runtimeAndOSMetadata = getRuntimeAndOSMetadata()

Expand Down
88 changes: 80 additions & 8 deletions packages/dd-trace/test/plugins/util/git.spec.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,111 @@
const proxyquire = require('proxyquire')

const sanitizedExecStub = sinon.stub()
const gitRepoInfoStub = sinon.stub().returns({
author: 'author <[email protected]>',
committer: 'committer <[email protected]>',
authorDate: '1970',
committerDate: '1971',
commitMessage: 'commit message',
branch: 'gitBranch',
tag: 'gitTag',
sha: 'gitSha'
})

const {
getGitMetadata,
GIT_COMMIT_SHA,
GIT_BRANCH,
GIT_REPOSITORY_URL
} = proxyquire('../../../src/plugins/util/git', { './exec': {
'sanitizedExec': sanitizedExecStub
} })
GIT_TAG,
GIT_REPOSITORY_URL,
GIT_COMMIT_MESSAGE,
GIT_COMMIT_COMMITTER_DATE,
GIT_COMMIT_COMMITTER_EMAIL,
GIT_COMMIT_COMMITTER_NAME,
GIT_COMMIT_AUTHOR_DATE,
GIT_COMMIT_AUTHOR_EMAIL,
GIT_COMMIT_AUTHOR_NAME
} = proxyquire('../../../src/plugins/util/git',
{
'./exec': {
'sanitizedExec': sanitizedExecStub
},
'../../../../../vendor/git-repo-info': gitRepoInfoStub
}
)

describe('git', () => {
afterEach(() => {
sanitizedExecStub.reset()
})
const commonGitMetadata = {
[GIT_COMMIT_MESSAGE]: 'commit message',
[GIT_COMMIT_COMMITTER_DATE]: '1971',
[GIT_COMMIT_COMMITTER_EMAIL]: '[email protected]',
[GIT_COMMIT_COMMITTER_NAME]: 'committer',
[GIT_COMMIT_AUTHOR_DATE]: '1970',
[GIT_COMMIT_AUTHOR_EMAIL]: '[email protected]',
[GIT_COMMIT_AUTHOR_NAME]: 'author',
[GIT_TAG]: 'gitTag',
[GIT_BRANCH]: 'gitBranch'
}
it('calls git when some ci metadata is not present', () => {
const ciMetadata = { commitSHA: 'ciSHA', branch: 'ciBranch' }
const ciMetadata = { commitSHA: 'ciSHA' }
const metadata = getGitMetadata(ciMetadata)

expect(metadata).to.include(
{
[GIT_COMMIT_SHA]: 'ciSHA',
[GIT_BRANCH]: 'ciBranch'
...commonGitMetadata
}
)
expect(metadata[GIT_REPOSITORY_URL]).not.to.equal('ciRepositoryUrl')
expect(sanitizedExecStub).to.have.been.calledWith('git ls-remote --get-url', { stdio: 'pipe' })
expect(gitRepoInfoStub).to.have.been.called
})
it('returns ci metadata if present and does not call git', () => {
const ciMetadata = { commitSHA: 'ciSHA', branch: 'ciBranch', repositoryUrl: 'ciRepositoryUrl' }
const ciMetadata = { commitSHA: 'ciSHA', branch: 'ciBranch', repositoryUrl: 'ciRepositoryUrl', tag: 'tag' }
const metadata = getGitMetadata(ciMetadata)

expect(metadata).to.eql(
{ [GIT_COMMIT_SHA]: 'ciSHA', [GIT_BRANCH]: 'ciBranch', [GIT_REPOSITORY_URL]: 'ciRepositoryUrl' }
{
...commonGitMetadata,
[GIT_COMMIT_SHA]: 'ciSHA',
[GIT_BRANCH]: 'ciBranch',
[GIT_REPOSITORY_URL]: 'ciRepositoryUrl',
[GIT_TAG]: 'tag'
}
)
expect(sanitizedExecStub).not.to.have.been.called
})
it('does not crash with empty or badly shapen author or committer', () => {
gitRepoInfoStub.returns({
author: 'author <>',
committer: undefined,
authorDate: '1970',
committerDate: '1971',
commitMessage: 'commit message',
branch: 'gitBranch',
tag: 'gitTag',
sha: 'gitSha'
})
const ciMetadata = { repositoryUrl: 'ciRepositoryUrl' }
const metadata = getGitMetadata(ciMetadata)

expect(metadata).to.eql(
{
[GIT_COMMIT_MESSAGE]: 'commit message',
[GIT_COMMIT_COMMITTER_DATE]: '1971',
[GIT_COMMIT_COMMITTER_EMAIL]: '',
[GIT_COMMIT_COMMITTER_NAME]: '',
[GIT_COMMIT_AUTHOR_DATE]: '1970',
[GIT_COMMIT_AUTHOR_EMAIL]: '',
[GIT_COMMIT_AUTHOR_NAME]: 'author',
[GIT_TAG]: 'gitTag',
[GIT_BRANCH]: 'gitBranch',
[GIT_COMMIT_SHA]: 'gitSha',
[GIT_REPOSITORY_URL]: 'ciRepositoryUrl'
}
)
})
})
Loading