Skip to content

Commit e4f6c61

Browse files
Merge pull request #186 from codecov/bb-support
feat: add bitbucket pipelines support
2 parents d22a6e6 + 0eb535b commit e4f6c61

File tree

7 files changed

+288
-15
lines changed

7 files changed

+288
-15
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ jobs:
100100
npm ci
101101
npm test
102102
mkdir -p coverage-alpine
103-
cp coverage/* coverage-alpine/
103+
cp -r coverage/* coverage-alpine/
104104
105105
- run:
106106
name: Build uploader binary on alpine

package.json

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,6 @@
4343
"testdouble": "3.16.1",
4444
"testdouble-jest": "2.0.0"
4545
},
46-
"nyc": {
47-
"all": true,
48-
"reporter": [
49-
"text",
50-
"cobertura"
51-
],
52-
"exclude": [
53-
"src/ci_providers/provider_template.js",
54-
"rollup.config.js",
55-
"test/**/*"
56-
]
57-
},
5846
"jest": {
5947
"collectCoverage": true,
6048
"collectCoverageFrom": [
@@ -65,7 +53,8 @@
6553
],
6654
"coverageReporters": [
6755
"text",
68-
"cobertura"
56+
"cobertura",
57+
"html"
6958
],
7059
"setupFilesAfterEnv": [
7160
"<rootDir>/test/test_helpers.js"

src/ci_providers/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const providerAppveyorci = require('./provider_appveyorci')
22
const providerAzurepipelines = require('./provider_azurepipelines')
3+
const providerBitbucket = require('./provider_bitbucket')
34
const providerBuildkite = require('./provider_buildkite')
45
const providerCircleci = require('./provider_circleci')
56
const providerDrone = require('./provider_drone')
@@ -13,6 +14,7 @@ const providerTravisci = require('./provider_travisci')
1314
const providers = [
1415
providerAppveyorci,
1516
providerAzurepipelines,
17+
providerBitbucket,
1618
providerBuildkite,
1719
providerCircleci,
1820
providerDrone,
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
const childProcess = require('child_process')
2+
const { validateSHA } = require('../helpers/validate.js')
3+
4+
function detect(envs) {
5+
return envs.CI && envs.BITBUCKET_BUILD_NUMBER
6+
}
7+
8+
function _getBuild(inputs) {
9+
const { args, envs } = inputs
10+
return args.build || envs.BITBUCKET_BUILD_NUMBER
11+
}
12+
13+
// eslint-disable-next-line no-unused-vars
14+
function _getBuildURL(inputs) {
15+
return ''
16+
}
17+
18+
function _getBranch(inputs) {
19+
const { args, envs } = inputs
20+
return args.branch || envs.BITBUCKET_BRANCH || ''
21+
}
22+
23+
function _getJob(envs) {
24+
return envs.BITBUCKET_BUILD_NUMBER
25+
}
26+
27+
function _getPR(inputs) {
28+
const { args, envs } = inputs
29+
return args.pr || envs.BITBUCKET_PR_ID || ''
30+
}
31+
32+
function _getService() {
33+
return 'bitbucket'
34+
}
35+
36+
function getServiceName() {
37+
return 'Bitbucket'
38+
}
39+
40+
function _getSHA(inputs) {
41+
const { args, envs } = inputs
42+
let commit = envs.BITBUCKET_COMMIT
43+
44+
if (commit && validateSHA(commit, 12)) {
45+
commit = childProcess.execFileSync('git', ['rev-parse', commit])
46+
}
47+
48+
return args.sha || commit
49+
}
50+
51+
function _getSlug(inputs) {
52+
const { args, envs } = inputs
53+
54+
let slug = ''
55+
if (envs.BITBUCKET_REPO_OWNER && envs.BITBUCKET_REPO_SLUG) {
56+
slug = `${envs.BITBUCKET_REPO_OWNER}/${envs.BITBUCKET_REPO_SLUG}`
57+
}
58+
return args.slug || slug
59+
}
60+
61+
function getServiceParams(inputs) {
62+
return {
63+
branch: _getBranch(inputs),
64+
build: _getBuild(inputs),
65+
buildURL: _getBuildURL(inputs),
66+
commit: _getSHA(inputs),
67+
job: _getJob(inputs.envs),
68+
pr: _getPR(inputs),
69+
service: _getService(),
70+
slug: _getSlug(inputs),
71+
}
72+
}
73+
74+
module.exports = {
75+
detect,
76+
getServiceName,
77+
getServiceParams,
78+
}

src/helpers/validate.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ function validateURL(url) {
99
}
1010

1111
function validateFlags(flags) {
12+
// eslint-disable-next-line no-useless-escape
1213
const mask = /^[\w\.\-]{1,45}$/
1314
return mask.test(flags)
1415
}
@@ -18,9 +19,24 @@ function validateFileNamePath(path) {
1819
return mask.test(path)
1920
}
2021

22+
/**
23+
* Validate that a SHA is the correct length and content
24+
* @param {string} commitSHA
25+
* @param {number} requestedLength
26+
* @returns {boolean}
27+
*/
28+
const GIT_SHA_LENGTH = 40;
29+
30+
function validateSHA(commitSHA, requestedLength = GIT_SHA_LENGTH) {
31+
return (
32+
commitSHA.length === requestedLength && validator.isAlphanumeric(commitSHA)
33+
)
34+
}
35+
2136
module.exports = {
2237
validateToken,
2338
validateURL,
2439
validateFlags,
2540
validateFileNamePath,
41+
validateSHA,
2642
}

test/helpers/validate.test.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ describe('Input Validators', () => {
3333
it('Should pass with a period in the middle', () => {
3434
expect(validate.validateFlags('moo.foor')).toBe(true)
3535
})
36-
36+
3737
it('Should pass with a dash at the start', () => {
3838
expect(validate.validateFlags('-moo-foor')).toBe(true)
3939
})
@@ -54,4 +54,16 @@ describe('Input Validators', () => {
5454
expect(validate.validateFileNamePath('/path{}to/file')).toBe(false)
5555
})
5656
})
57+
58+
describe('validateSHA()', () => {
59+
it('should fail with invalid characters', () => {
60+
expect(validate.validateSHA('abc 123', 7)).toBe(false)
61+
})
62+
it('should fail with incorrect length', () => {
63+
expect(validate.validateSHA('abc123', 7)).toBe(false)
64+
})
65+
it('should pass with correct content and length', () => {
66+
expect(validate.validateSHA('abc123', 6)).toBe(true)
67+
})
68+
})
5769
})
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
const td = require('testdouble')
2+
const childProcess = require('child_process')
3+
4+
const providerBitbucket = require('../../src/ci_providers//provider_bitbucket')
5+
6+
describe('Bitbucket Params', () => {
7+
afterEach(() => {
8+
td.reset()
9+
})
10+
11+
describe('detect()', () => {
12+
it('does not run without Bitbucket env variable', () => {
13+
const inputs = {
14+
args: {},
15+
envs: {},
16+
}
17+
let detected = providerBitbucket.detect(inputs.envs)
18+
expect(detected).toBeFalsy()
19+
20+
inputs.envs['CI'] = true
21+
detected = providerBitbucket.detect(inputs.envs)
22+
expect(detected).toBeFalsy()
23+
})
24+
25+
it('does not run without Bitbucket env variable', () => {
26+
const inputs = {
27+
args: {},
28+
envs: {
29+
BITBUCKET_BUILD_NUMBER: 1,
30+
CI: true,
31+
},
32+
}
33+
const detected = providerBitbucket.detect(inputs.envs)
34+
expect(detected).toBeTruthy()
35+
})
36+
})
37+
38+
it('gets the correct params on no env variables', () => {
39+
const inputs = {
40+
args: {},
41+
envs: {
42+
BITBUCKET_BUILD_NUMBER: 1,
43+
CI: true,
44+
},
45+
}
46+
const expected = {
47+
branch: '',
48+
build: 1,
49+
buildURL: '',
50+
commit: undefined,
51+
job: 1,
52+
pr: '',
53+
service: 'bitbucket',
54+
slug: '',
55+
}
56+
const params = providerBitbucket.getServiceParams(inputs)
57+
expect(params).toMatchObject(expected)
58+
})
59+
60+
it('gets the correct params on pr', () => {
61+
const inputs = {
62+
args: {},
63+
envs: {
64+
BITBUCKET_BRANCH: 'main',
65+
BITBUCKET_BUILD_NUMBER: 1,
66+
BITBUCKET_COMMIT: 'testingsha',
67+
BITBUCKET_PR_ID: 2,
68+
BITBUCKET_REPO_OWNER: 'testOwner',
69+
BITBUCKET_REPO_SLUG: 'testSlug',
70+
CI: true,
71+
},
72+
}
73+
const expected = {
74+
branch: 'main',
75+
build: 1,
76+
buildURL: '',
77+
commit: 'testingsha',
78+
job: 1,
79+
pr: 2,
80+
service: 'bitbucket',
81+
slug: 'testOwner/testSlug',
82+
}
83+
const params = providerBitbucket.getServiceParams(inputs)
84+
expect(params).toMatchObject(expected)
85+
})
86+
87+
it('gets the correct params on push', () => {
88+
const inputs = {
89+
args: {},
90+
envs: {
91+
BITBUCKET_BRANCH: 'main',
92+
BITBUCKET_BUILD_NUMBER: 1,
93+
BITBUCKET_COMMIT: 'testingsha',
94+
BITBUCKET_REPO_OWNER: 'testOwner',
95+
BITBUCKET_REPO_SLUG: 'testSlug',
96+
CI: true,
97+
},
98+
}
99+
const expected = {
100+
branch: 'main',
101+
build: 1,
102+
buildURL: '',
103+
commit: 'testingsha',
104+
job: 1,
105+
pr: '',
106+
service: 'bitbucket',
107+
slug: 'testOwner/testSlug',
108+
}
109+
const params = providerBitbucket.getServiceParams(inputs)
110+
expect(params).toMatchObject(expected)
111+
})
112+
113+
it('gets the correct params with short SHA', () => {
114+
const inputs = {
115+
args: {},
116+
envs: {
117+
BITBUCKET_BRANCH: 'main',
118+
BITBUCKET_BUILD_NUMBER: 1,
119+
BITBUCKET_COMMIT: 'testingsha12',
120+
BITBUCKET_REPO_OWNER: 'testOwner',
121+
BITBUCKET_REPO_SLUG: 'testSlug',
122+
CI: true,
123+
},
124+
}
125+
const expected = {
126+
branch: 'main',
127+
build: 1,
128+
buildURL: '',
129+
commit: 'newtestsha',
130+
job: 1,
131+
pr: '',
132+
service: 'bitbucket',
133+
slug: 'testOwner/testSlug',
134+
}
135+
136+
const execFileSync = td.replace(childProcess, 'execFileSync')
137+
td.when(execFileSync('git', ['rev-parse', 'testingsha12'])).thenReturn(
138+
'newtestsha',
139+
)
140+
const params = providerBitbucket.getServiceParams(inputs)
141+
expect(params).toMatchObject(expected)
142+
})
143+
144+
it('gets the correct params on overrides', () => {
145+
const inputs = {
146+
args: {
147+
branch: 'feature',
148+
build: 3,
149+
pr: 4,
150+
sha: 'overwriteSha',
151+
slug: 'overwriteOwner/overwriteRepo',
152+
},
153+
envs: {
154+
BITBUCKET_BRANCH: 'main',
155+
BITBUCKET_BUILD_NUMBER: 1,
156+
BITBUCKET_COMMIT: 'testingsha',
157+
BITBUCKET_PR_ID: 2,
158+
BITBUCKET_REPO_OWNER: 'testOwner',
159+
BITBUCKET_REPO_SLUG: 'testSlug',
160+
CI: true,
161+
},
162+
}
163+
const expected = {
164+
branch: 'feature',
165+
build: 3,
166+
buildURL: '',
167+
commit: 'overwriteSha',
168+
job: 1,
169+
pr: 4,
170+
service: 'bitbucket',
171+
slug: 'overwriteOwner/overwriteRepo',
172+
}
173+
const params = providerBitbucket.getServiceParams(inputs)
174+
expect(params).toMatchObject(expected)
175+
})
176+
})

0 commit comments

Comments
 (0)