forked from dotnet/vscode-csharp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
createTagsTasks.ts
146 lines (126 loc) · 4.65 KB
/
createTagsTasks.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as gulp from 'gulp';
import * as fs from 'fs';
import * as minimist from 'minimist';
import { Octokit } from '@octokit/rest';
interface Options {
releaseVersion: string;
releaseCommit: string;
// Even it is specified as boolean, it would still be parsed as string in compiled js.
dryRun: string;
}
gulp.task('createTags', async (): Promise<void> => {
const options = minimist<Options>(process.argv.slice(2));
console.log(`releaseVersion: ${options.releaseVersion}`);
console.log(`releaseCommit: ${options.releaseCommit}`);
const dryRun = options.dryRun.toLocaleLowerCase() === 'true';
console.log(`dry run: ${dryRun}`);
const roslynCommit = await findRoslynCommitAsync();
if (!roslynCommit) {
logError('Failed to find roslyn commit.');
return;
}
// The compiled option value in js type is 'any' type.
if (dryRun) {
console.log('Tagging is skipped in dry run mode.');
return;
} else {
const tagCreatedInRoslyn = await tagRepoAsync(
'dotnet',
'roslyn',
roslynCommit,
`VSCode-CSharp-${options.releaseVersion}`,
`${options.releaseVersion} VSCode C# extension release`
);
if (!tagCreatedInRoslyn) {
logError('Failed to tag roslyn');
return;
}
console.log('tag created in roslyn');
const tagCreatedInVsCodeCsharp = await tagRepoAsync(
'dotnet',
'vscode-csharp',
options.releaseCommit,
`v${options.releaseVersion}`,
options.releaseVersion
);
if (!tagCreatedInVsCodeCsharp) {
logError('Failed to tag vscode-csharp');
return;
}
console.log('tag created in vscode-csharp');
}
});
async function findRoslynCommitAsync(): Promise<string | null> {
const packageJsonString = fs.readFileSync('./package.json').toString();
const packageJson = JSON.parse(packageJsonString);
const roslynVersion = packageJson['defaults']['roslyn'];
if (!roslynVersion) {
logError("Can't find roslyn version in package.json");
return null;
}
console.log(`Roslyn version is ${roslynVersion}`);
// Nuget package should exist under out/.nuget/ since we have run the install dependencies task.
const nuspecFile = fs
.readFileSync(
`out/.nuget/microsoft.codeanalysis.languageserver.linux-x64/${roslynVersion}/microsoft.codeanalysis.languageserver.linux-x64.nuspec`
)
.toString();
const results = /commit="(.*)"/.exec(nuspecFile);
if (results == null || results.length == 0) {
logError('Failed to find commit number from nuspec file');
return null;
}
if (results.length != 2) {
logError('Unexpected regex match result from nuspec file.');
return null;
}
const commitNumber = results[1];
console.log(`commitNumber is ${commitNumber}`);
return commitNumber;
}
async function tagRepoAsync(
owner: string,
repo: string,
commit: string,
releaseTag: string,
tagMessage: string
): Promise<boolean> {
const pat = process.env['GitHubPAT'];
if (!pat) {
throw 'No GitHub Pat found.';
}
console.log(`Start to tag ${owner}/${repo}. Commit: ${commit}, tag: ${releaseTag}, message: ${tagMessage}`);
const octokit = new Octokit({ auth: pat });
await octokit.auth();
const createTagResponse = await octokit.request(`POST /repos/${owner}/${repo}/git/tags`, {
owner: owner,
repo: repo,
tag: releaseTag,
message: tagMessage,
object: commit,
type: 'commit',
});
if (createTagResponse.status !== 201) {
logError(`Failed to create tag for ${commit} in ${owner}/${repo}.`);
return false;
}
const refCreationResponse = await octokit.request(`Post /repos/${owner}/${repo}/git/refs`, {
owner: owner,
repo: repo,
ref: `refs/tags/${releaseTag}`,
sha: commit,
});
if (refCreationResponse.status !== 201) {
logError(`Failed to create reference for ${commit} in ${owner}/${repo}.`);
return false;
}
console.log(`Tag is created.`);
return true;
}
function logError(message: string): void {
console.log(`##vso[task.logissue type=error]${message}`);
}