Skip to content

Commit

Permalink
Enable TS strict mode (#553)
Browse files Browse the repository at this point in the history
* Clear some of the easier errors

* Major improvements in nullability

* Redo telemetry a bit

* Fix the last nullability error

* Trim tsconfig a bit

* New nullability fixes

* Fix some errors and logic flaws

* Handle filtered sessions correctly

* Handle no suitable app service

* Better service connection progress notification

* Fix always cancelling after checking in

* Fix getting commit

* Move updateScmType to bottom

* Consistency

* Remove duplicate repositoryName

* Formatting

* Rethrow errors

* Add separate notification for pushing

* Fetch commit from a fresh HEAD

* Add quick pick to create new project

* Fix GitHub integration

* Get tests working again

* Actually compile the tests ✌️

* deepStrictEqual
  • Loading branch information
winstliu authored Nov 18, 2023
1 parent 772fe42 commit ffb2060
Show file tree
Hide file tree
Showing 49 changed files with 987 additions and 1,035 deletions.
5 changes: 1 addition & 4 deletions .azure-pipelines/common-steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,11 @@ steps:
# echo no-op
# displayName: Generate service-schema.json

- script: npm run unittest
displayName: Run unit tests

- script: Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
displayName: Start xvfb

- script: npm run test
displayName: Run integration tests
displayName: Run tests
env:
DISPLAY: ':99.0'

Expand Down
40 changes: 8 additions & 32 deletions package-lock.json

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

8 changes: 3 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,9 @@
"vscode:prepublish": "npm run compile",
"compile": "webpack --mode production --progress --color",
"compile:dev": "webpack --mode development --progress --color",
"compile:test": "tsc --project ./tsconfig.test.json",
"watch": "webpack --mode development --progress --color --watch",
"compile:test": "npm run compile:dev && tsc -p ./",
"test": "npm run compile:test && node ./out/test/runTest.js",
"unittest": "npm run compile:test && mocha -u tdd out/unittest/**/*.js"
"test": "npm run compile:test && node ./out/test/runTest.js"
},
"devDependencies": {
"@types/fs-extra": "4.0.5",
Expand All @@ -157,13 +156,12 @@
"ts-loader": "^8.0.14",
"ts-node": "7.0.1",
"tslint": "5.8.0",
"typescript": "^4.1.0",
"typescript": "~5.2.2",
"webpack": "^5.76.0",
"webpack-cli": "^4.4.0"
},
"dependencies": {
"@azure/arm-appservice": "^6.1.0",
"@azure/arm-resources": "^4.0.0",
"@azure/arm-subscriptions": "^3.0.0",
"@azure/ms-rest-azure-env": "^2.0.0",
"@azure/ms-rest-nodeauth": "^3.0.6",
Expand Down
3 changes: 1 addition & 2 deletions src/configure/activate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import { telemetryHelper } from '../helpers/telemetryHelper';

export async function activateConfigurePipeline(): Promise<void> {
vscode.commands.registerCommand('azure-pipelines.configure-pipeline', async () => {
telemetryHelper.initialize('configure-pipeline');
await telemetryHelper.callWithTelemetryAndErrorHandling(async () => {
await telemetryHelper.callWithTelemetryAndErrorHandling('azurePipelines.configure-pipeline', async () => {
await configurePipeline();
});
});
Expand Down
80 changes: 30 additions & 50 deletions src/configure/clients/azure/appServiceClient.ts
Original file line number Diff line number Diff line change
@@ -1,101 +1,81 @@
import { v4 as uuid } from 'uuid';
import { ResourceManagementModels } from '@azure/arm-resources';
import { WebSiteManagementClient, WebSiteManagementModels } from '@azure/arm-appservice';
import { TokenCredentialsBase } from '@azure/ms-rest-nodeauth';

import { AzureResourceClient } from './azureResourceClient';
import { WebAppKind, ParsedAzureResourceId } from '../../model/models';
import { WebAppKind, ValidatedSite } from '../../model/models';
import { Messages } from '../../../messages';

export class AppServiceClient extends AzureResourceClient {
export class AppServiceClient {

private static resourceType = 'Microsoft.Web/sites';
private webSiteManagementClient: WebSiteManagementClient;
private tenantId: string;
private portalUrl: string;

constructor(credentials: TokenCredentialsBase, tenantId: string, portalUrl: string, subscriptionId: string) {
super(credentials, subscriptionId);
this.webSiteManagementClient = new WebSiteManagementClient(credentials, subscriptionId);
this.tenantId = tenantId;
this.portalUrl = portalUrl;
}

public async getAppServiceResource(resourceId: string): Promise<ResourceManagementModels.GenericResource> {
let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId);
return await this.webSiteManagementClient.webApps.get(parsedResourceId.resourceGroup, parsedResourceId.resourceName);
}

public async GetAppServices(filterForResourceKind: WebAppKind): Promise<ResourceManagementModels.ResourceListResult> {
let resourceList = await this.getResourceList(AppServiceClient.resourceType);
if (!!filterForResourceKind) {
resourceList = resourceList.filter(resource => resource.kind === filterForResourceKind);
}

return resourceList;
public async getAppServices(filterForResourceKind: WebAppKind): Promise<WebSiteManagementModels.Site[]> {
const sites = await this.webSiteManagementClient.webApps.list();
return sites.filter(site => site.kind === filterForResourceKind);
}

public async getDeploymentCenterUrl(resourceId: string): Promise<string> {
return `${this.portalUrl}/#@${this.tenantId}/resource/${resourceId}/vstscd`;
}

public async getAzurePipelineUrl(resourceId: string): Promise<string> {
let metadata = await this.getAppServiceMetadata(resourceId);
if (metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl']) {
public async getAzurePipelineUrl(site: ValidatedSite): Promise<string> {
const metadata = await this.getAppServiceMetadata(site);
if (metadata.properties?.['VSTSRM_BuildDefinitionWebAccessUrl']) {
return metadata.properties['VSTSRM_BuildDefinitionWebAccessUrl'];
}

throw new Error(Messages.cannotFindPipelineUrlInMetaDataException);
}

public async getAppServiceConfig(resourceId: string): Promise<WebSiteManagementModels.SiteConfigResource> {
let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId);
return this.webSiteManagementClient.webApps.getConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName);
public async getAppServiceConfig(site: ValidatedSite): Promise<WebSiteManagementModels.SiteConfigResource> {
return this.webSiteManagementClient.webApps.getConfiguration(site.resourceGroup, site.name);
}

public async updateScmType(resourceId: string): Promise<WebSiteManagementModels.SiteConfigResource> {
let siteConfig = await this.getAppServiceConfig(resourceId);
public async updateScmType(site: ValidatedSite): Promise<WebSiteManagementModels.SiteConfigResource> {
const siteConfig = await this.getAppServiceConfig(site);
siteConfig.scmType = ScmType.VSTSRM;
let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId);
return this.webSiteManagementClient.webApps.updateConfiguration(parsedResourceId.resourceGroup, parsedResourceId.resourceName, siteConfig);
return this.webSiteManagementClient.webApps.updateConfiguration(site.resourceGroup, site.name, siteConfig);
}

public async getAppServiceMetadata(resourceId: string): Promise<WebSiteManagementModels.StringDictionary> {
let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId);
return this.webSiteManagementClient.webApps.listMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName);
public async getAppServiceMetadata(site: ValidatedSite): Promise<WebSiteManagementModels.StringDictionary> {
return this.webSiteManagementClient.webApps.listMetadata(site.resourceGroup, site.name);
}

public async updateAppServiceMetadata(resourceId: string, metadata: WebSiteManagementModels.StringDictionary): Promise<WebSiteManagementModels.StringDictionary> {
let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId);
return this.webSiteManagementClient.webApps.updateMetadata(parsedResourceId.resourceGroup, parsedResourceId.resourceName, metadata);
public async updateAppServiceMetadata(site: ValidatedSite, metadata: WebSiteManagementModels.StringDictionary): Promise<WebSiteManagementModels.StringDictionary> {
return this.webSiteManagementClient.webApps.updateMetadata(site.resourceGroup, site.name, metadata);
}

public async publishDeploymentToAppService(resourceId: string, buildDefinitionUrl: string, releaseDefinitionUrl: string, triggeredBuildUrl: string): Promise<WebSiteManagementModels.Deployment> {
let parsedResourceId: ParsedAzureResourceId = new ParsedAzureResourceId(resourceId);

public async publishDeploymentToAppService(site: ValidatedSite, buildDefinitionUrl: string, releaseDefinitionUrl: string, triggeredBuildUrl: string): Promise<WebSiteManagementModels.Deployment> {
// create deployment object
let deploymentId = uuid();
let deployment = this.createDeploymentObject(deploymentId, buildDefinitionUrl, releaseDefinitionUrl, triggeredBuildUrl);
return this.webSiteManagementClient.webApps.createDeployment(parsedResourceId.resourceGroup, parsedResourceId.resourceName, deploymentId, deployment);
const deploymentId = uuid();
const deployment = this.createDeploymentObject(deploymentId, buildDefinitionUrl, releaseDefinitionUrl, triggeredBuildUrl);
return this.webSiteManagementClient.webApps.createDeployment(site.resourceGroup, site.name, deploymentId, deployment);
}

private createDeploymentObject(deploymentId: string, buildDefinitionUrl: string, releaseDefinitionUrl: string, triggeredBuildUrl: string): WebSiteManagementModels.Deployment {
let deployment: WebSiteManagementModels.Deployment = {
id: deploymentId,
status: 4,
author: 'VSTS',
deployer: 'VSTS'
};

let deploymentMessage: DeploymentMessage = {
const message: DeploymentMessage = {
type: "CDDeploymentConfiguration",
message: "Successfully set up continuous delivery from VS Code and triggered deployment to Azure Web App.",
VSTSRM_BuildDefinitionWebAccessUrl: `${buildDefinitionUrl}`,
VSTSRM_ConfiguredCDEndPoint: '',
VSTSRM_BuildWebAccessUrl: `${triggeredBuildUrl}`,
};
deployment.message = JSON.stringify(deploymentMessage);
return deployment;

return {
id: deploymentId,
status: 4,
author: 'VSTS',
deployer: 'VSTS',
message: JSON.stringify(message),
};
}
}

Expand Down
31 changes: 0 additions & 31 deletions src/configure/clients/azure/azureResourceClient.ts

This file was deleted.

4 changes: 2 additions & 2 deletions src/configure/clients/devOps/operationsClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ export class OperationsClient {
}

const operation = response.result;
if (operation.status === OperationStatus.Succeeded) {
if (operation?.status === OperationStatus.Succeeded) {
return;
}

if (operation.status === OperationStatus.Failed) {
if (operation?.status === OperationStatus.Failed) {
// OperationReference is missing some properties so cast it to any
throw new Error(util.format(Messages.failedToCreateAzureDevOpsProject, (operation as any).detailedMessage));
}
Expand Down
Loading

0 comments on commit ffb2060

Please sign in to comment.