Skip to content

Commit

Permalink
feat: Azure Provider
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasrockhu committed Jun 5, 2021
1 parent 9e67223 commit 4255fe9
Show file tree
Hide file tree
Showing 6 changed files with 285 additions and 7 deletions.
2 changes: 2 additions & 0 deletions src/ci_providers/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const providerAppveyorci = require('./provider_appveyorci')
const providerAzurepipelines = require('./provider_azurepipelines')
const providerCircleci = require('./provider_circleci')
const providerGitHubactions = require('./provider_githubactions')
const providerGitLabci = require('./provider_gitlabci')
Expand All @@ -9,6 +10,7 @@ const providerTravisci = require('./provider_travisci')
// Please make sure provider_local is last
const providers = [
providerAppveyorci,
providerAzurepipelines,
providerCircleci,
providerGitHubactions,
providerGitLabci,
Expand Down
105 changes: 105 additions & 0 deletions src/ci_providers/provider_azurepipelines.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
var childProcess = require('child_process')
var { log } = require('../helpers/logger')

function detect (envs) {
return !!envs.SYSTEM_TEAMFOUNDATIONSERVERURI
}

function _getBuild (inputs) {
const { args, envs } = inputs
return args.build || envs.BUILD_BUILDNUMBER || ''
}

function _getBuildURL (inputs) {
const { args, envs } = inputs
if (envs.SYSTEM_TEAMPROJECT && envs.BUILD_BUILDID) {
return encodeURIComponent(`${envs.SYSTEM_TEAMFOUNDATIONSERVERURI}${envs.SYSTEM_TEAMPROJECT}/_build/results?buildId=${envs.BUILD_BUILDID}`)
}
return ''
}

function _getBranch (inputs) {
const { args, envs } = inputs
let branch = ''
if (envs.BUILD_SOURCEBRANCH) {
branch = envs.BUILD_SOURCEBRANCH.replace('refs/heads/', '')
}
return args.branch || branch
}

function _getJob (envs) {
return envs.BUILD_BUILDID || ''
}

function _getPR (inputs) {
const { args, envs } = inputs
return args.pr || envs.SYSTEM_PULLREQUEST_PULLREQUESTNUMBER || envs.SYSTEM_PULLREQUEST_PULLREQUESTID || ''
}

function _getService () {
return 'azure_pipelines'
}

function getServiceName () {
return 'Azure Pipelines'
}

function _getSHA (inputs) {
const { args, envs } = inputs
let commit = envs.BUILD_SOURCEVERSION

if (_getPR(inputs)) {
const mergeCommitRegex = /^[a-z0-9]{40} [a-z0-9]{40}$/
const mergeCommitMessage = childProcess.execSync(
`git show --no-patch --format="%P"`
)
if (mergeCommitRegex.exec(mergeCommitMessage)) {
const mergeCommit = mergeCommitMessage.split(" ")[1]
log(` Fixing merge commit SHA ${commit} -> ${mergeCommit}`)
commit = mergeCommit
}
}

return args.sha || commit || ''
}

function _getProject (inputs) {
const { envs } = inputs
return envs.SYSTEM_TEAMPROJECT || ''
}

function _getServerURI (inputs) {
const { envs } = inputs
return envs.SYSTEM_TEAMFOUNDATIONSERVERURI
}

function _getSlug (inputs) {
const { args } = inputs
return args.slug || ''
}
/**
* Generates and return the serviceParams object
*
* @param {args: {}, envs: {}} inputs an object of arguments and enviromental variable key/value pairs
* @returns { branch: String, build: String, buildURL: String, commit: String, job: String, pr: String, service: String, slug: String}
*/
function getServiceParams (inputs) {
return {
branch: _getBranch(inputs),
build: _getBuild(inputs),
buildURL: _getBuildURL(inputs),
commit: _getSHA(inputs),
job: _getJob(inputs.envs),
pr: _getPR(inputs),
project: _getProject(inputs),
server_uri: _getServerURI(inputs),
service: _getService(),
slug: _getSlug(inputs)
}
}

module.exports = {
detect,
getServiceName,
getServiceParams
}
30 changes: 23 additions & 7 deletions test/helpers/validate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ describe('Input Validators', function () {
})
})

describe('URLs', function () {
it('Returns true with a valid URL', function () {
expect(validate.validateURL('https://codecov.io')).toBe(true)
})
it('Returns false with an invalid URL', function () {
expect(validate.validateURL('not.a.URL.com')).toBe(false)
})
it('Returns false with an empty URL', function () {
expect(validate.validateURL('')).toBe(false)
})
})

describe('Flags', function () {
it('Should pass without a dash', function () {
expect(validate.validateFlags('moo')).toBe(true)
Expand All @@ -23,15 +35,19 @@ describe('Input Validators', function () {
})
})

describe('URLs', function () {
it('Returns true with a valid URL', function () {
expect(validate.validateURL('https://codecov.io')).toBe(true)
describe('FileNamePath', function () {
it('Should pass with an absolute path', function () {
expect(validate.validateFileNamePath('/path/to/file/1.txt')).toBe(true)
})
it('Returns false with an invalid URL', function () {
expect(validate.validateURL('not.a.URL.com')).toBe(false)
it('Should pass with a relative path', function () {
expect(validate.validateFileNamePath('./path/to/file/1.txt')).toBe(true)
})
it('Returns false with an empty URL', function () {
expect(validate.validateURL('')).toBe(false)

it('Should fail with spaces', function () {
expect(validate.validateFileNamePath('/path to/file')).toBe(false)
})
it('Should fail with other characters', function () {
expect(validate.validateFileNamePath('/path{}to/file')).toBe(false)
})
})
})
1 change: 1 addition & 0 deletions test/providers/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ describe('CI Providers', () => {
GITLAB_CI: true,
JENKINS_URL: 'https://example.com',
SHIPPABLE: true,
SYSTEM_TEAMFOUNDATIONSERVERURI: 'https://example.azure.com',
TRAVIS: true,
TRAVIS_REPO_SLUG: 'testOrg/testRepo',
}
Expand Down
143 changes: 143 additions & 0 deletions test/providers/provider_azurepipelines.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
const td = require('testdouble')
const childProcess = require('child_process')

const providerAzurepipelines = require('../../src/ci_providers//provider_azurepipelines')

describe('Jenkins CI Params', () => {
afterEach(function () {
td.reset()
})

it('does not run without AzurePipelines env variable', () => {
const inputs = {
args: {},
envs: {}
}
detected = providerAzurepipelines.detect(inputs.envs)
expect(detected).toBeFalsy()
})

it('gets correct params on pr number', () => {
const inputs = {
args: {},
envs: {
BUILD_BUILDNUMBER: 1,
BUILD_BUILDID: 2,
BUILD_SOURCEBRANCH: 'refs/heads/main',
BUILD_SOURCEVERSION: 'testingsha',
SYSTEM_BUILD_BUILDID: 1,
SYSTEM_PULLREQUEST_PULLREQUESTNUMBER: 3,
SYSTEM_TEAMFOUNDATIONSERVERURI: 'https://example.azure.com',
SYSTEM_TEAMPROJECT: 'testOrg',
}
}
const expected = {
branch: 'main',
build: 1,
buildURL: 'https%3A%2F%2Fexample.azure.comtestOrg%2F_build%2Fresults%3FbuildId%3D2',
commit: 'testingsha',
job: 2,
pr: 3,
project: 'testOrg',
server_uri: 'https://example.azure.com',
service: 'azure_pipelines',
slug: ''
}
const params = providerAzurepipelines.getServiceParams(inputs)
expect(params).toMatchObject(expected)
})

it('gets correct params on pr id', () => {
const inputs = {
args: {},
envs: {
BUILD_BUILDNUMBER: 1,
BUILD_BUILDID: 2,
BUILD_SOURCEBRANCH: 'refs/heads/main',
BUILD_SOURCEVERSION: 'testingsha',
SYSTEM_BUILD_BUILDID: 1,
SYSTEM_PULLREQUEST_PULLREQUESTID: 3,
SYSTEM_TEAMFOUNDATIONSERVERURI: 'https://example.azure.com',
SYSTEM_TEAMPROJECT: 'testOrg',
}
}
const expected = {
branch: 'main',
build: 1,
buildURL: 'https%3A%2F%2Fexample.azure.comtestOrg%2F_build%2Fresults%3FbuildId%3D2',
commit: 'testingsha',
job: 2,
pr: 3,
project: 'testOrg',
server_uri: 'https://example.azure.com',
service: 'azure_pipelines',
slug: ''
}
const params = providerAzurepipelines.getServiceParams(inputs)
expect(params).toMatchObject(expected)
})

it('gets correct params on merge', () => {
const inputs = {
args: {},
envs: {
BUILD_BUILDNUMBER: 1,
BUILD_BUILDID: 2,
BUILD_SOURCEBRANCH: 'refs/heads/main',
BUILD_SOURCEVERSION: 'testingsha',
SYSTEM_BUILD_BUILDID: 1,
SYSTEM_PULLREQUEST_PULLREQUESTID: 3,
SYSTEM_TEAMFOUNDATIONSERVERURI: 'https://example.azure.com',
SYSTEM_TEAMPROJECT: 'testOrg',
}
}
const expected = {
branch: 'main',
build: 1,
buildURL: 'https%3A%2F%2Fexample.azure.comtestOrg%2F_build%2Fresults%3FbuildId%3D2',
commit: 'testingmergecommitsha2345678901234567890',
job: 2,
pr: 3,
project: 'testOrg',
server_uri: 'https://example.azure.com',
service: 'azure_pipelines',
slug: ''
}
const execSync = td.replace(childProcess, 'execSync')
td.when(execSync(
`git show --no-patch --format="%P"`
)).thenReturn("testingsha123456789012345678901234567890 testingmergecommitsha2345678901234567890")
const params = providerAzurepipelines.getServiceParams(inputs)
expect(params).toMatchObject(expected)
})

it('gets correct params for overrides', () => {
const inputs = {
args: {
branch: 'branch',
build: 3,
pr: '2',
sha: 'testsha',
slug: 'testOrg/testRepo'
},
envs: {
SYSTEM_TEAMFOUNDATIONSERVERURI: 'https://example.azure.com',
}
}
const expected = {
branch: 'branch',
build: 3,
buildURL: '',
commit: 'testsha',
job: '',
pr: '2',
project: '',
server_uri: 'https://example.azure.com',
service: 'azure_pipelines',
slug: 'testOrg/testRepo'
}

const params = providerAzurepipelines.getServiceParams(inputs)
expect(params).toMatchObject(expected)
})
})
11 changes: 11 additions & 0 deletions test/providers/provider_gitlabci.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,17 @@ describe('GitLabCI Params', () => {
const params = providerGitLabci.getServiceParams(inputs)
expect(params.slug).toBe('')
})

it('can handle no remote origin url', () => {
inputs.envs['CI_BUILD_REPO'] = ''
const execSync = td.replace(childProcess, 'execSync')
td.when(execSync(
`git config --get remote.origin.url || hg paths default || echo ''`
)).thenReturn("")

const params = providerGitLabci.getServiceParams(inputs)
expect(params.slug).toBe('')
})
})

it('gets correct params for overrides', () => {
Expand Down

0 comments on commit 4255fe9

Please sign in to comment.