Skip to content

Commit 57531fa

Browse files
author
Danny McCormick
authored
Setup pipeline for courtesy push (#12346)
* Setup pipeline for courtesy push * Use whatsprintis.it * Feedback * Clean * env var capitalized * Username as variable
1 parent 2e6f045 commit 57531fa

File tree

9 files changed

+262
-1
lines changed

9 files changed

+262
-1
lines changed

azure-pipelines.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@ trigger:
22
- master
33
- releases/*
44

5+
resources:
6+
repositories:
7+
- repository: AzureDevOps
8+
type: git
9+
endpoint: AzureDevOps
10+
name: AzureDevOps/AzureDevOps
11+
512
jobs:
613

714
# All tasks on Windows
@@ -26,6 +33,21 @@ jobs:
2633
steps:
2734
- template: ci/publish-steps.yml
2835

36+
# Courtesy push on Windows
37+
- job: courtesy_push_windows
38+
displayName: Courtesy Push
39+
dependsOn:
40+
- publish_windows
41+
condition: and(succeeded(), in(variables['build.reason'], 'Schedule', 'Manual'), eq(variables['COURTESY_PUSH'], 'true'))
42+
pool:
43+
vmImage: vs2017-win2016
44+
steps:
45+
- checkout: AzureDevOps
46+
fetchDepth: 1
47+
persistCredentials: true
48+
- checkout: self
49+
- template: ci/courtesy-push.yml
50+
2951
# All tasks on Linux
3052
- job: build_all_linux
3153
displayName: Build all tasks (Linux)

ci/build-all-steps.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,13 @@ steps:
7272
- powershell: ./ci/stop-collect-diagnostics.ps1
7373
displayName: Stop collect diagnostics
7474
condition: and(always(), eq(variables.collect_diagnostics, 'true'), ne(variables['numTasks'], 0))
75+
76+
- powershell: |
77+
# Build the release branch name
78+
$currentSprint = (Invoke-WebRequest https://whatsprintis.it/sprint -Headers @{"Accept"= "application/json"} | ConvertFrom-Json).sprint
79+
$releaseBranch = "releases/m" + $currentSprint
80+
# Push branch to git
81+
git checkout -b $releaseBranch
82+
git push https://$(GitHubPAT)@github.com/microsoft/azure-pipelines-tasks $releaseBranch
83+
condition: and(succeeded(), in(variables['build.reason'], 'Schedule', 'Manual'), eq(variables['courtesyPush'], 'true'))
84+
displayName: Push release branch

ci/courtesy-push.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
steps:
2+
- task: NuGetToolInstaller@0
3+
inputs:
4+
versionSpec: '5.4.0'
5+
displayName: 'Install nuget'
6+
7+
- task: DownloadBuildArtifacts@0
8+
inputs:
9+
artifactName: IndividualNugetPackages
10+
downloadPath: 'IndividualNugetPackagesDownloaded'
11+
displayName: 'Download Artifact'
12+
13+
- script: node azure-pipelines-tasks\ci\courtesy-push\courtesy-push.js AzureDevOps\.nuget\externals\UnifiedDependencies.xml IndividualNugetPackagesDownloaded\IndividualNugetPackages\unified_deps.xml
14+
displayName: 'Update unified deps'
15+
16+
- task: NuGetAuthenticate@0
17+
inputs:
18+
nuGetServiceConnections: 'Codex-Deps'
19+
displayName: 'Authenticate with nuget'
20+
21+
# Everything until this point is idempotent (other than pushing tasks release branch which will get overwritten if we re-do this anyways).
22+
# Note: Pushing the tasks release branch has to happen in the first job in case commits are pushed between now and then.
23+
24+
- script: |
25+
cd IndividualNugetPackagesDownloaded
26+
cd IndividualNugetPackages
27+
push.cmd
28+
displayName: 'Push Nuget packages'
29+
30+
- powershell: |
31+
# Build the release branch name
32+
$currentSprint = (Invoke-WebRequest https://whatsprintis.it/sprint -Headers @{"Accept"= "application/json"} | ConvertFrom-Json).sprint
33+
$releaseBranch = "users/$(username)/m" + $currentSprint + "/courtesyPush"
34+
# Push branch to git
35+
Write-Host "Pushing branch to AzureDevOps"
36+
cd AzureDevOps
37+
git checkout -b $releaseBranch
38+
git config --global user.email "$(username)@microsoft.com"
39+
git config --global user.name "$(username)"
40+
git add .nuget\externals\UnifiedDependencies.xml
41+
git commit -m "Courtesy bump of tasks"
42+
git push origin $releaseBranch
43+
Write-Host "Creating Pull Request"
44+
cd ..\azure-pipelines-tasks\ci\courtesy-push
45+
npm install
46+
node open-courtesy-push-pull-request.js $releaseBranch
47+
displayName: Create PR in Azure DevOps
48+
env:
49+
TOKEN: $(Package.Token)

ci/courtesy-push/courtesy-push.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
const path = require('path');
2+
const fs = require('fs');
3+
4+
versionReplace = function(pathToUnifiedDeps, pathToNewUnifiedDeps, outputPath) {
5+
var currentDeps = fs.readFileSync(pathToUnifiedDeps, "utf8");
6+
var newDeps = fs.readFileSync(pathToNewUnifiedDeps, "utf8");
7+
8+
var currentDepsArr = currentDeps.split('\n');
9+
var newDepsArr = newDeps.split('\n');
10+
var newDepsDict = {};
11+
12+
newDepsArr.forEach(function (newDep) {
13+
// add to dictionary
14+
var depDetails = newDep.split("\"");
15+
console.log(JSON.stringify(depDetails));
16+
var name = depDetails[1];
17+
var version = depDetails[3];
18+
console.log(name + ' ' + version);
19+
newDepsDict[name] = version;
20+
});
21+
22+
var updatedDeps = [];
23+
24+
currentDepsArr.forEach(function (currentDep) {
25+
var depDetails = currentDep.split("\"");
26+
var name = depDetails[1];
27+
var version = depDetails[3];
28+
29+
// find if there is a match in new
30+
if (newDepsDict[name]) {
31+
// update the version
32+
depDetails[3] = newDepsDict[name];
33+
updatedDeps.push(depDetails.join('\"'));
34+
} else {
35+
if (currentDep.indexOf('</packages>') <= -1) {
36+
updatedDeps.push(currentDep);
37+
}
38+
console.log(`"${currentDep}"`);
39+
}
40+
});
41+
42+
// list new ones that arent in current
43+
newDepsArr.forEach(function (newDep) {
44+
// add to dictionary
45+
var depDetails = newDep.split("\"");
46+
console.log(JSON.stringify(depDetails));
47+
var name = depDetails[1];
48+
var version = depDetails[3];
49+
50+
var currentContainsNew = false;
51+
currentDepsArr.forEach(function (currentDep) {
52+
var depDetails = currentDep.split("\"");
53+
var currName = depDetails[1];
54+
55+
if (currName === name) {
56+
currentContainsNew = true;
57+
}
58+
});
59+
60+
if (!currentContainsNew) {
61+
console.log(name);
62+
updatedDeps.push(newDep);
63+
}
64+
});
65+
66+
updatedDeps.push('</packages>');
67+
68+
// write it as a new file where currentDeps is
69+
fs.writeFileSync(outputPath, updatedDeps.join("\n"));
70+
console.log('Done.');
71+
}
72+
73+
const unifiedDeps = process.argv[2];
74+
const newDeps = process.argv[3];
75+
76+
versionReplace(unifiedDeps, newDeps, unifiedDeps);
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
const azdev = require('azure-devops-node-api');
2+
3+
const orgUrl = "https://dev.azure.com/mseng";
4+
const token = process.env.TOKEN;
5+
if (!token) {
6+
throw new Exception('No token provided');
7+
}
8+
const releaseBranch = process.argv[2];
9+
if (!releaseBranch) {
10+
throw new Exception('No release branch provided');
11+
}
12+
const azureDevOpsRepoId = "fb240610-b309-4925-8502-65ff76312c40";
13+
const project = "AzureDevOps";
14+
15+
const pullRequestToCreate = {sourceRefName: `refs/heads/${releaseBranch}`,
16+
targetRefName: 'refs/heads/master',
17+
title: 'Courtesy Bump of Tasks',
18+
description: 'Autogenerated PR to bump the versions of our first party tasks'
19+
};
20+
21+
let authHandler = azdev.getPersonalAccessTokenHandler(token);
22+
23+
console.log('Getting connection');
24+
let connection = new azdev.WebApi(orgUrl, authHandler);
25+
26+
console.log('Getting api');
27+
connection.getGitApi().then(gitApi => {
28+
console.log('Creating PR');
29+
gitApi.createPullRequest(pullRequestToCreate, azureDevOpsRepoId, project).then(res => {
30+
console.log(`Created PR ${res}`);
31+
}).catch(err => {
32+
console.log(err);
33+
throw err;
34+
});
35+
}).catch(err => {
36+
console.log(err);
37+
throw err;
38+
});

ci/courtesy-push/package-lock.json

Lines changed: 44 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ci/courtesy-push/package.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "courtesy-push",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "open-courtesy-push-pull-request.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"author": "",
10+
"license": "ISC",
11+
"dependencies": {
12+
"azure-devops-node-api": "10.0.0"
13+
}
14+
}

ci/publish-steps.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ steps:
3838
# Stage per task NuGet package
3939
- script: npm run package
4040
displayName: npm run package
41+
env:
42+
COURTESY_PUSH: $(courtesyPush)
4143

4244
# Publish per task NuGet package artifact
4345
- task: PublishBuildArtifacts@1

make-util.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1442,7 +1442,13 @@ var createPushCmd = function (taskPublishFolder, fullTaskName, taskVersion) {
14421442
var taskFeedUrl = process.env.AGGREGATE_TASKS_FEED_URL;
14431443
var apiKey = 'Skyrise';
14441444

1445-
fs.writeFileSync(taskPushCmdPath, `nuget.exe push ${nupkgName} -source "${taskFeedUrl}" -apikey ${apiKey}`);
1445+
var pushCmd = `nuget.exe push ${nupkgName} -source "${taskFeedUrl}" -apikey ${apiKey}`;
1446+
1447+
if (process.env['COURTESY_PUSH']) {
1448+
pushCmd += ' -skipDuplicate'
1449+
}
1450+
1451+
fs.writeFileSync(taskPushCmdPath, pushCmd);
14461452
}
14471453

14481454
// Rename task folders that are created from the aggregate. Allows NuGet generation from aggregate using same process as normal.

0 commit comments

Comments
 (0)