Skip to content

Commit 2b56e6f

Browse files
feat: addded azure devops pr info
1 parent 80ffa78 commit 2b56e6f

9 files changed

Lines changed: 457 additions & 34 deletions

File tree

__snapshots__/commit-info-spec.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ exports['commit-info no environment variables has certain api 1'] = [
88
"getRemoteOrigin",
99
"getSubject",
1010
"getTimestamp",
11-
"getBody"
11+
"getBody",
12+
"resolvePullRequestCi",
13+
"PROVIDER_GITHUB_ACTIONS",
14+
"PROVIDER_AZURE_PIPELINES"
1215
]
1316

1417
exports['commit-info no environment variables returns information 1'] = {
@@ -41,7 +44,10 @@ exports['commit-info combination with environment variables has certain api 1']
4144
"getRemoteOrigin",
4245
"getSubject",
4346
"getTimestamp",
44-
"getBody"
47+
"getBody",
48+
"resolvePullRequestCi",
49+
"PROVIDER_GITHUB_ACTIONS",
50+
"PROVIDER_AZURE_PIPELINES"
4551
]
4652

4753
exports['commit-info combination with environment variables returns information 1'] = {

azure-pipelines.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Azure Pipelines — GitHub-hosted repo
2+
#
3+
# First-time setup in Azure DevOps:
4+
# 1. Project Settings → Pipelines → Create pipeline (or New pipeline)
5+
# 2. GitHub → authorize → select this repository
6+
# 3. Existing Azure Pipelines YAML file → branch → /azure-pipelines.yml
7+
#
8+
# PR validation: open a PR targeting main (or master). BUILD_REASON will be
9+
# PullRequest and npm run ado-pr-verify will assert adoEventData is populated.
10+
11+
trigger:
12+
branches:
13+
include:
14+
- main
15+
- master
16+
17+
pr:
18+
branches:
19+
include:
20+
- main
21+
- master
22+
23+
pool:
24+
vmImage: ubuntu-latest
25+
26+
steps:
27+
- task: NodeTool@0
28+
displayName: Use Node.js 18
29+
inputs:
30+
versionSpec: 18.x
31+
32+
- script: npm ci
33+
displayName: npm ci
34+
35+
- script: npm test
36+
displayName: Unit tests
37+
38+
- script: npm run ado-pr-verify
39+
displayName: Verify Azure PR → commit-info adoEventData

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
"size": "t=\"$(npm pack .)\"; wc -c \"${t}\"; tar tvf \"${t}\"; rm \"${t}\";",
6464
"test": "npm run unit",
6565
"unit": "mocha src/*-spec.js",
66+
"ado-pr-verify": "node scripts/verify-ado-pr-info.js",
6667
"gha-e2e": "mocha src/utils-e2e.js",
6768
"semantic-release": "semantic-release pre && npm publish --access public && semantic-release post"
6869
},

scripts/verify-ado-pr-info.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
'use strict'
2+
3+
/**
4+
* Run in Azure Pipelines on PR builds to ensure commit-info reads
5+
* SYSTEM_PULLREQUEST_* variables into adoEventData.
6+
*
7+
* Non-PR runs (push to main, manual) skip with a log line.
8+
*/
9+
10+
const la = require('lazy-ass')
11+
const { commitInfo } = require('../src')
12+
13+
const reason = process.env.BUILD_REASON || ''
14+
15+
if (reason !== 'PullRequest') {
16+
console.log(
17+
'ado-pr-verify: skip (BUILD_REASON=%s; only PullRequest runs assertions)',
18+
reason || '(empty)'
19+
)
20+
process.exit(0)
21+
}
22+
23+
commitInfo(process.cwd(), { pullRequestProvider: 'azure-pipelines' })
24+
.then(info => {
25+
const ado = info.adoEventData
26+
console.log('ado-pr-verify: adoEventData =', JSON.stringify(ado, null, 2))
27+
la(
28+
ado,
29+
'expected adoEventData on Azure PR build; is SYSTEM_PULLREQUEST_PULLREQUESTID set?'
30+
)
31+
la(
32+
ado.pullRequestId,
33+
'expected pullRequestId from SYSTEM_PULLREQUEST_PULLREQUESTID'
34+
)
35+
})
36+
.catch(err => {
37+
console.error(err)
38+
process.exit(1)
39+
})

src/index.js

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,26 @@ const {
1111
getTimestamp,
1212
getRemoteOrigin
1313
} = require('./git-api')
14+
const { getBranch, getCommitInfoFromEnvironment } = require('./utils')
1415
const {
15-
getBranch,
16-
getCommitInfoFromEnvironment,
17-
getGhaEventData
18-
} = require('./utils')
16+
resolvePullRequestCi,
17+
PROVIDER_GITHUB_ACTIONS,
18+
PROVIDER_AZURE_PIPELINES,
19+
withoutProvider
20+
} = require('./pull-request-ci')
1921
const Promise = require('bluebird')
2022
const { mergeWith, or } = require('ramda')
2123

22-
function commitInfo (folder) {
24+
function commitInfo (folder, options = {}) {
2325
folder = folder || process.cwd()
26+
const { pullRequestProvider = 'auto' } = options
2427
debug('commit-info in folder', folder)
2528

29+
const pullRequestCi = resolvePullRequestCi({
30+
env: process.env,
31+
provider: pullRequestProvider
32+
})
33+
2634
return Promise.props({
2735
branch: getBranch(folder),
2836
message: getMessage(folder),
@@ -31,10 +39,15 @@ function commitInfo (folder) {
3139
sha: getSha(folder),
3240
timestamp: getTimestamp(folder),
3341
remote: getRemoteOrigin(folder),
34-
ghaEventData: getGhaEventData(
35-
process.env.GITHUB_EVENT_PATH,
36-
process.env.GITHUB_ACTIONS
37-
)
42+
pullRequestCi,
43+
ghaEventData:
44+
pullRequestCi && pullRequestCi.provider === PROVIDER_GITHUB_ACTIONS
45+
? withoutProvider(pullRequestCi)
46+
: undefined,
47+
adoEventData:
48+
pullRequestCi && pullRequestCi.provider === PROVIDER_AZURE_PIPELINES
49+
? withoutProvider(pullRequestCi)
50+
: undefined
3851
}).then(info => {
3952
const envVariables = getCommitInfoFromEnvironment()
4053
debug('git commit: %o', info)
@@ -53,5 +66,8 @@ module.exports = {
5366
getRemoteOrigin,
5467
getSubject,
5568
getTimestamp,
56-
getBody
69+
getBody,
70+
resolvePullRequestCi,
71+
PROVIDER_GITHUB_ACTIONS,
72+
PROVIDER_AZURE_PIPELINES
5773
}

src/pull-request-ci-spec.js

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
'use strict'
2+
3+
/* eslint-env mocha */
4+
const la = require('lazy-ass')
5+
const sinon = require('sinon')
6+
const fs = require('fs')
7+
const {
8+
resolvePullRequestCi,
9+
PROVIDER_GITHUB_ACTIONS,
10+
PROVIDER_AZURE_PIPELINES,
11+
readGithubActionsPullRequest
12+
} = require('./pull-request-ci')
13+
14+
describe('pull-request-ci', () => {
15+
const githubEvent = {
16+
pull_request: {
17+
head: { ref: 'head-ref', sha: 'head-sha' },
18+
base: { ref: 'base-ref', sha: 'base-sha' },
19+
issue_url: 'issue',
20+
html_url: 'html',
21+
title: 'title'
22+
},
23+
sender: {
24+
avatar_url: 'av',
25+
html_url: 'sender'
26+
}
27+
}
28+
29+
describe('resolvePullRequestCi', () => {
30+
let readStub
31+
32+
beforeEach(() => {
33+
readStub = sinon
34+
.stub(fs, 'readFileSync')
35+
.returns(JSON.stringify(githubEvent))
36+
})
37+
38+
afterEach(() => {
39+
readStub.restore()
40+
})
41+
42+
it('auto prefers GitHub Actions when event file is present', () => {
43+
const r = resolvePullRequestCi({
44+
env: {
45+
GITHUB_ACTIONS: 'true',
46+
GITHUB_EVENT_PATH: '/tmp/event.json',
47+
BUILD_REASON: 'PullRequest',
48+
SYSTEM_PULLREQUEST_PULLREQUESTID: '99'
49+
},
50+
fs,
51+
provider: 'auto'
52+
})
53+
54+
la(r.provider === PROVIDER_GITHUB_ACTIONS, r)
55+
la(r.headRef === 'head-ref', r)
56+
})
57+
58+
it('auto falls back to Azure when GitHub is not active', () => {
59+
const r = resolvePullRequestCi({
60+
env: {
61+
BUILD_REASON: 'PullRequest',
62+
SYSTEM_PULLREQUEST_PULLREQUESTID: '7',
63+
SYSTEM_PULLREQUEST_SOURCEBRANCH: 'refs/heads/f'
64+
},
65+
fs,
66+
provider: 'auto'
67+
})
68+
69+
la(r.provider === PROVIDER_AZURE_PIPELINES, r)
70+
la(r.pullRequestId === '7', r)
71+
})
72+
73+
it('github-actions skips Azure even if ADO vars are set', () => {
74+
const r = resolvePullRequestCi({
75+
env: {
76+
GITHUB_ACTIONS: 'true',
77+
GITHUB_EVENT_PATH: '/tmp/event.json',
78+
BUILD_REASON: 'PullRequest',
79+
SYSTEM_PULLREQUEST_PULLREQUESTID: '99'
80+
},
81+
fs,
82+
provider: PROVIDER_GITHUB_ACTIONS
83+
})
84+
85+
la(r.provider === PROVIDER_GITHUB_ACTIONS, r)
86+
})
87+
88+
it('azure-pipelines ignores GitHub event file', () => {
89+
const r = resolvePullRequestCi({
90+
env: {
91+
GITHUB_ACTIONS: 'true',
92+
GITHUB_EVENT_PATH: '/tmp/event.json',
93+
BUILD_REASON: 'PullRequest',
94+
SYSTEM_PULLREQUEST_PULLREQUESTID: '3'
95+
},
96+
fs,
97+
provider: PROVIDER_AZURE_PIPELINES
98+
})
99+
100+
la(r.provider === PROVIDER_AZURE_PIPELINES, r)
101+
la(r.pullRequestId === '3', r)
102+
la(readStub.called === false, 'should not read GitHub event JSON')
103+
})
104+
105+
it('github-actions returns undefined when not a GHA run', () => {
106+
const r = resolvePullRequestCi({
107+
env: {},
108+
fs,
109+
provider: PROVIDER_GITHUB_ACTIONS
110+
})
111+
112+
la(r === undefined, r)
113+
})
114+
})
115+
116+
describe('readGithubActionsPullRequest', () => {
117+
it('injects fs for tests without stubbing global fs', () => {
118+
const fakeFs = {
119+
readFileSync: () => JSON.stringify(githubEvent)
120+
}
121+
const r = readGithubActionsPullRequest(
122+
'/x',
123+
'true',
124+
/** @type {any} */ (fakeFs)
125+
)
126+
127+
la(r.provider === PROVIDER_GITHUB_ACTIONS, r)
128+
})
129+
})
130+
})

0 commit comments

Comments
 (0)