Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"vsix/": true
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
},
"csharp.suppressDotnetRestoreNotification": true,
"typescript.tsdk": "./node_modules/typescript/lib",
Expand Down
21 changes: 19 additions & 2 deletions azure-pipelines/publish-roslyn-copilot.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
trigger: none
pr: none

variables:
# Variable group contains PAT for bot account.
- group: dotnet-vscode-insertion-variables

resources:
repositories:
- repository: 1ESPipelineTemplates
Expand Down Expand Up @@ -29,7 +33,6 @@ extends:
image: 1ESPT-Windows2022
os: windows
templateContext:
type: releaseJob
isProduction: false #change this
inputs:
- input: pipelineArtifact
Expand All @@ -38,7 +41,11 @@ extends:
destinationPath: $(Pipeline.Workspace)/artifacts

steps:
- checkout: none
- checkout: self
clean: true
submodules: true
fetchTags: false
fetchDepth: 0

- task: CopyFiles@2
displayName: 'Copy files from Zip folder to staging directory'
Expand All @@ -56,3 +63,13 @@ extends:
Destination: "AzureBlob"
storage: "$(AzStorage)"
ContainerName: "$(AzContainerName)"

- pwsh: |
npm install
npm install -g gulp
displayName: 'Install tools'

- pwsh: gulp 'publish roslyn copilot' --userName dotnet-maestro-bot --email [email protected] --stagingDirectory '$(Build.ArtifactStagingDirectory)/staging'
displayName: 'Create component update PR'
env:
GitHubPAT: $(BotAccount-dotnet-maestro-bot-PAT)
1 change: 1 addition & 0 deletions gulpfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ require('./tasks/debuggerTasks');
require('./tasks/snapTasks');
require('./tasks/signingTasks');
require('./tasks/profilingTasks');
require('./tasks/componentUpdateTasks');
30 changes: 0 additions & 30 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@
{
"id": "RoslynCopilot",
"description": "Language server for Roslyn Copilot integration",
"url": "https://roslyn.blob.core.windows.net/releases/Microsoft.VisualStudio.Copilot.Roslyn.LanguageServer-18.0.479-alpha.zip",
"url": "https://roslyn.blob.core.windows.net/releases/Microsoft.VisualStudio.Copilot.Roslyn.LanguageServer-18.0.701-alpha.zip",
"installPath": ".roslynCopilot",
"platforms": [
"neutral"
Expand All @@ -414,7 +414,7 @@
"neutral"
],
"installTestPath": "./.roslynCopilot/Microsoft.VisualStudio.Copilot.Roslyn.LanguageServer.dll",
"integrity": "1D16E555AEFB581F6090D66A20FA5B3DD367EFA0D33BC97EF176285F60E02FEF"
"integrity": "4609A58D1BA337B4917391FFEF70FEF7DD04EF97F1B0A72B4F73114635A54918"
},
{
"id": "Debugger",
Expand Down
6 changes: 6 additions & 0 deletions src/tools/updatePackageDependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,12 @@ function getLowercaseFileNameFromUrl(url: string): string {
const secondToLastDash = fileName.lastIndexOf('-', fileName.lastIndexOf('-') - 1);
fileName = fileName.substr(0, secondToLastDash);
return fileName;
} else if (fileName.startsWith('microsoft.visualstudio.copilot.roslyn.languageserver')) {
// Copilot versions are everything after the second to last dash.
// e.g. we want microsoft.visualstudio.copilot.roslyn.languageserver from microsoft.visualstudio.copilot.roslyn.languageserver-18.0.479-alpha.zip
const secondToLastDash = fileName.lastIndexOf('-', fileName.lastIndexOf('-') - 1);
fileName = fileName.substr(0, secondToLastDash);
return fileName;
} else {
throw new Error(`Unexpected dependency file name '${fileName}'`);
}
Expand Down
112 changes: 112 additions & 0 deletions tasks/componentUpdateTasks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*---------------------------------------------------------------------------------------------
* 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 process from 'node:process';
import * as fs from 'fs';
import * as path from 'path';
import minimist from 'minimist';
import {
configureGitUser,
createCommit,
pushBranch,
createPullRequest,
doesBranchExist,
findPRByTitle,
} from './gitTasks';
import { updatePackageDependencies } from '../src/tools/updatePackageDependencies';

type Options = {
userName?: string;
email?: string;
};

/**
* Extract version from file name using a provided regex pattern
* @param fileName - The file name to extract version from
* @param pattern - The regex pattern to match and extract version (should have a capture group)
* @returns The extracted version string or null if not found
*/
function extractVersion(fileName: string, pattern: RegExp): string | null {
const match = fileName.match(pattern);
return match && match[1] ? match[1] : null;
}

gulp.task('publish roslyn copilot', async () => {
const parsedArgs = minimist<Options>(process.argv.slice(2));

if (!parsedArgs.stagingDirectory || !fs.existsSync(parsedArgs.stagingDirectory)) {
throw new Error(`Staging directory not found at ${parsedArgs.stagingDirectory}; skipping package.json update.`);
}

// Find the Roslyn zip file in the staging directory (we know it was copied here)
const files = fs.readdirSync(parsedArgs.stagingDirectory);
const zipFile = files.find((file) => /Roslyn\.LanguageServer.*\.zip$/i.test(file));

if (!zipFile) {
throw new Error(`
No Roslyn LanguageServer zip file found in ${parsedArgs.stagingDirectory}; skipping package.json update.`);
}

const zipPath = path.join(parsedArgs.stagingDirectory, zipFile);
console.log(`Using zip file: ${zipPath}`);
const zipName = zipFile;

// Extract version from file name
const version = extractVersion(zipName, /Microsoft\.VisualStudio\.Copilot\.Roslyn\.LanguageServer-(.+)\.zip$/i);

if (!version) {
throw new Error(`Could not extract version from file name ${zipName}; skipping.`);
}

console.log(`Extracted version: ${version}`);

const safeVersion = version.replace(/[^A-Za-z0-9_.-]/g, '-');
const branch = `update/roslyn-copilot-${safeVersion}`;

const pat = process.env['GitHubPAT'];
if (!pat) {
throw 'No GitHub PAT found.';
}

const owner = 'dotnet';
const repo = 'vscode-csharp';
const title = `Update RoslynCopilot url to ${version}`;
const body = `Automated update of RoslynCopilot url to ${version}`;

// Bail out if a branch with the same name already exists or PR already exists for the insertion.
if (await doesBranchExist('origin', branch)) {
console.log(`##vso[task.logissue type=warning]${branch} already exists in origin. Skip pushing.`);
return;
}
const existingPRUrl = await findPRByTitle(pat, owner, repo, title);
if (existingPRUrl) {
console.log(
`##vso[task.logissue type=warning] Pull request with the same name already exists: ${existingPRUrl}`
);
return;
}

// Set environment variables for updatePackageDependencies
process.env['NEW_DEPS_ID'] = 'RoslynCopilot';
process.env['NEW_DEPS_VERSION'] = version;
process.env[
'NEW_DEPS_URLS'
] = `https://roslyn.blob.core.windows.net/releases/Microsoft.VisualStudio.Copilot.Roslyn.LanguageServer-${version}.zip`;

// Update package dependencies using the extracted utility
await updatePackageDependencies();
console.log(`Updated RoslynCopilot dependency to version ${version}`);

// Configure git user if provided
await configureGitUser(parsedArgs.userName, parsedArgs.email);

// Create commit with changes
await createCommit(branch, ['package.json'], `Update RoslynCopilot version to ${version}`);

// Push branch and create PR
await pushBranch(branch, pat, owner, repo);
await createPullRequest(pat, owner, repo, branch, title, body);
});
Loading
Loading