Add ability to start vscode just to write out a blob of all config details - for Microsoft/vscode-bing#7

Upload configuration file during the build to the same azure storage account as sourcemaps
This commit is contained in:
Rob Lourens
2017-09-10 19:37:57 -07:00
parent 055825e9a5
commit 12c1ed6bcc
7 changed files with 152 additions and 8 deletions

View File

@@ -7,6 +7,8 @@
const gulp = require('gulp');
const fs = require('fs');
const os = require('os');
const cp = require('child_process');
const path = require('path');
const es = require('event-stream');
const azure = require('gulp-azure-storage');
@@ -443,3 +445,52 @@ gulp.task('upload-vscode-sourcemaps', ['minify-vscode'], () => {
prefix: commit + '/'
}));
});
const allConfigDetailsPath = path.join(os.tmpdir(), 'configuration.json');
gulp.task('upload-vscode-configuration', ['generate-vscode-configuration'], () => {
if (!fs.existsSync(allConfigDetailsPath)) {
console.error(`configuration file at ${allConfigDetailsPath} does not exist`);
return;
}
return gulp.src(allConfigDetailsPath)
.pipe(azure.upload({
account: process.env.AZURE_STORAGE_ACCOUNT,
key: process.env.AZURE_STORAGE_ACCESS_KEY,
container: 'configuration',
prefix: `${packageJson.version}/${commit}/`
}));
});
gulp.task('generate-vscode-configuration', () => {
return new Promise((resolve, reject) => {
const buildDir = process.env['AGENT_BUILDDIRECTORY'];
if (!buildDir) {
return reject(new Error('$AGENT_BUILDDIRECTORY not set'));
}
const appPath = path.join(buildDir, 'VSCode-darwin/Visual\\ Studio\\ Code\\ -\\ Insiders.app/Contents/Resources/app/bin/code');
const codeProc = cp.exec(`${appPath} --dump-default-configuration='${allConfigDetailsPath}' --wait`);
const timer = setTimeout(() => {
codeProc.kill();
reject(new Error('dump-default-configuration process timed out'));
}, 10 * 1000);
codeProc.stdout.on('data', d => console.log(d.toString()));
codeProc.stderr.on('data', d => console.log(d.toString()));
codeProc.on('exit', () => {
clearTimeout(timer);
resolve();
});
codeProc.on('error', err => {
clearTimeout(timer);
reject(err);
});
}).catch(e => {
// Don't fail the build
console.error(e.toString());
});
});

View File

@@ -28,14 +28,20 @@ step "Install distro dependencies" \
step "Build minified & upload source maps" \
npm run gulp -- vscode-darwin-min upload-vscode-sourcemaps
step "Generate and upload configuration.json" \
npm run gulp -- upload-vscode-configuration
# step "Create loader snapshot"
# node build/lib/snapshotLoader.js
step "Run unit tests" \
./scripts/test.sh --build --reporter dot
# step "Run unit tests" \
# ./scripts/test.sh --build --reporter dot
step "Run integration tests" \
./scripts/test-integration.sh
# step "Run integration tests" \
# ./scripts/test-integration.sh
step "Publish release" \
./build/tfs/darwin/release.sh
step "Generate and upload configuration.json" \
npm run gulp -- upload-vscode-configuration

View File

@@ -75,6 +75,7 @@
"gulp-buffer": "0.0.2",
"gulp-concat": "^2.6.0",
"gulp-cssnano": "^2.1.0",
"gulp-debug": "^3.1.0",
"gulp-eslint": "^3.0.1",
"gulp-filter": "^3.0.0",
"gulp-flatmap": "^1.0.0",
@@ -132,4 +133,4 @@
"windows-mutex": "^0.2.0",
"fsevents": "0.3.8"
}
}
}

View File

@@ -41,6 +41,7 @@ export interface ParsedArgs {
'open-url'?: string | string[];
'skip-getting-started'?: boolean;
'sticky-quickopen'?: boolean;
'dump-default-configuration'?: string;
}
export const IEnvironmentService = createDecorator<IEnvironmentService>('environmentService');

View File

@@ -26,7 +26,8 @@ const options: minimist.Opts = {
'debugSearch',
'debugBrkSearch',
'open-url',
'enable-proposed-api'
'enable-proposed-api',
'dump-default-configuration'
],
boolean: [
'help',

View File

@@ -46,7 +46,7 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag
import { ContextMenuService } from 'vs/workbench/services/contextview/electron-browser/contextmenuService';
import { WorkbenchKeybindingService } from 'vs/workbench/services/keybinding/electron-browser/keybindingService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { WorkspaceService } from 'vs/workbench/services/configuration/node/configuration';
import { WorkspaceService, DefaultConfigurationDumpHelper } from 'vs/workbench/services/configuration/node/configuration';
import { IConfigurationEditingService } from 'vs/workbench/services/configuration/common/configurationEditing';
import { ConfigurationEditingService } from 'vs/workbench/services/configuration/node/configurationEditingService';
import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing';
@@ -622,6 +622,8 @@ export class Workbench implements IPartService {
Registry.as<IActionBarRegistry>(ActionBarExtensions.Actionbar).setInstantiationService(this.instantiationService);
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).setInstantiationService(this.instantiationService);
Registry.as<IEditorRegistry>(EditorExtensions.Editors).setInstantiationService(this.instantiationService);
this.instantiationService.createInstance(DefaultConfigurationDumpHelper);
}
private initSettings(): void {

View File

@@ -15,7 +15,7 @@ import * as errors from 'vs/base/common/errors';
import * as collections from 'vs/base/common/collections';
import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
import { RunOnceScheduler } from 'vs/base/common/async';
import { readFile, stat } from 'vs/base/node/pfs';
import { readFile, stat, writeFile } from 'vs/base/node/pfs';
import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
import * as extfs from 'vs/base/node/extfs';
import { IWorkspaceContextService, IWorkspace, Workspace, WorkbenchState, WorkspaceFolder, toWorkspaceFolders } from 'vs/platform/workspace/common/workspace';
@@ -36,6 +36,10 @@ import { createHash } from 'crypto';
import { getWorkspaceLabel, IWorkspacesService, IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IWindowConfiguration } from 'vs/platform/windows/common/windows';
import { IJSONSchema } from 'vs/base/common/jsonSchema';
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
import { ICommandService } from 'vs/platform/commands/common/commands';
import product from 'vs/platform/node/product';
import pkg from 'vs/platform/node/package';
interface IStat {
resource: URI;
@@ -864,3 +868,81 @@ export class Configuration<T> extends BaseConfiguration<T> {
return true;
}
}
export class DefaultConfigurationDumpHelper {
constructor(
@IEnvironmentService environmentService: IEnvironmentService,
@IExtensionService private extensionService: IExtensionService,
@ICommandService private commandService: ICommandService) {
if (environmentService.args['dump-default-configuration']) {
this.writeConfigModelAndQuit(environmentService.args['dump-default-configuration']);
}
}
private writeConfigModelAndQuit(targetPath: string): TPromise<void> {
return this.extensionService.onReady()
.then(() => this.writeConfigModel(targetPath))
.then(() => this.commandService.executeCommand('workbench.action.quit'))
.then(() => { });
}
private writeConfigModel(targetPath: string): TPromise<void> {
const configurations = Registry.as<IConfigurationRegistry>(Extensions.Configuration).getConfigurations().slice();
const settings = [];
const processConfig = (config: IConfigurationNode) => {
if (config.properties) {
for (let name in config.properties) {
const prop = config.properties[name];
const propDetails: any = {
name,
title: prop.title,
description: prop.description,
default: prop.default,
type: prop.type
};
if (prop.enum) {
propDetails.enum = prop.enum;
}
if (prop.enumDescriptions) {
propDetails.enumDescriptions = prop.enumDescriptions;
}
settings.push(propDetails);
}
}
if (config.allOf) {
config.allOf.forEach(processConfig);
}
};
configurations.sort(this.compareConfigurationNodes)
.forEach(processConfig);
const result: any = { settings };
result.build_time = Date.now();
result.commit = product.commit;
result.version = pkg.version;
const resultString = JSON.stringify(result, undefined, ' ');
return writeFile(targetPath, resultString);
}
private compareConfigurationNodes(c1: IConfigurationNode, c2: IConfigurationNode): number {
if (typeof c1.order !== 'number') {
return 1;
}
if (typeof c2.order !== 'number') {
return -1;
}
if (c1.order === c2.order) {
const title1 = c1.title || '';
const title2 = c2.title || '';
return title1.localeCompare(title2);
}
return c1.order - c2.order;
}
}