Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App Service Deploy 4.* Task Version (Preview) #6422

Merged
merged 20 commits into from
Mar 5, 2018
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"loc.input.help.Action": "Action to be performed on the App Service. You can Start, Stop, Restart, Slot swap, Install site extensions or enable Continuous Monitoring for an Azure App Service",
"loc.input.label.WebAppName": "App Service name",
"loc.input.help.WebAppName": "Enter or select the name of an existing Azure App Service",
"loc.input.label.SpecifySlot": "Specify Slot",
"loc.input.label.SpecifySlot": "Specify Slot or App Service Environment",
"loc.input.label.ResourceGroupName": "Resource group",
"loc.input.help.ResourceGroupName": "Enter or Select the Azure Resource Group that contains the Azure App Service specified above",
"loc.input.label.SourceSlot": "Source Slot",
Expand Down
7 changes: 4 additions & 3 deletions Tasks/AzureAppServiceManage/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"version": {
"Major": 0,
"Minor": 2,
"Patch": 24
"Patch": 25
},
"minimumAgentVersion": "1.102.0",
"instanceNameFormat": "$(Action): $(WebAppName)",
Expand Down Expand Up @@ -63,8 +63,9 @@
},
{
"name": "SpecifySlot",
"aliases": ["SpecifySlotOrASE"],
"type": "boolean",
"label": "Specify Slot",
"label": "Specify Slot or App Service Environment",
"defaultValue": "false",
"required": false,
"visibleRule": "Action != Swap Slots"
Expand Down Expand Up @@ -127,7 +128,7 @@
"name": "Slot",
"type": "pickList",
"label": "Slot",
"defaultValue": "",
"defaultValue": "production",
"properties": {
"EditableOptions": "True"
},
Expand Down
7 changes: 5 additions & 2 deletions Tasks/AzureAppServiceManage/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"version": {
"Major": 0,
"Minor": 2,
"Patch": 24
"Patch": 25
},
"minimumAgentVersion": "1.102.0",
"instanceNameFormat": "ms-resource:loc.instanceNameFormat",
Expand Down Expand Up @@ -65,6 +65,9 @@
},
{
"name": "SpecifySlot",
"aliases": [
"SpecifySlotOrASE"
],
"type": "boolean",
"label": "ms-resource:loc.input.label.SpecifySlot",
"defaultValue": "false",
Expand Down Expand Up @@ -129,7 +132,7 @@
"name": "Slot",
"type": "pickList",
"label": "ms-resource:loc.input.label.Slot",
"defaultValue": "",
"defaultValue": "production",
"properties": {
"EditableOptions": "True"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,23 @@
"loc.helpMarkDown": "[More Information](https://aka.ms/azurermwebdeployreadme)",
"loc.description": "Update Azure WebApp Services On Windows, Web App On Linux with built-in images or docker containers, ASP.NET, .NET Core, PHP, Python or Node based Web applications, Function Apps, Mobile Apps, Api applications, Web Jobs using Web Deploy / Kudu REST APIs",
"loc.instanceNameFormat": "Azure App Service Deploy: $(WebAppName)",
"loc.releaseNotes": "What's new in Version 3.0: <br/>&nbsp;&nbsp;Supports File Transformations (XDT) <br/>&nbsp;&nbsp;Supports Variable Substitutions(XML, JSON) <br/>Click [here](https://aka.ms/azurermwebdeployreadme) for more Information.",
"loc.releaseNotes": "What's new in version 4.* (preview)<br />Supports Kudu Zip Deploy<br />Supports App Service Environments<br />Improved UI for discovering different App service types supported by the task<br/>Click [here](https://aka.ms/azurermwebdeployreadme) for more Information.",
"loc.group.displayName.FileTransformsAndVariableSubstitution": "File Transforms & Variable Substitution Options",
"loc.group.displayName.AdditionalDeploymentOptions": "Additional Deployment Options",
"loc.group.displayName.PostDeploymentAction": "Post Deployment Action",
"loc.group.displayName.ApplicationAndConfigurationSettings": "Application and Configuration Settings",
"loc.group.displayName.output": "Output",
"loc.input.label.ConnectedServiceName": "Azure subscription",
"loc.input.help.ConnectedServiceName": "Select the Azure Resource Manager subscription for the deployment.",
"loc.input.label.WebAppKind": "App type",
"loc.input.help.WebAppKind": "Select type of web app to deploy. <br/> Note: Select Linux Web App for built-in platform images or custom container image deployments.",
"loc.input.label.WebAppKind": "App Service type",
"loc.input.help.WebAppKind": "Choose from Web App On Windows, Web App On Linux, Web App for Containers, Function App and Mobile App.",
"loc.input.label.WebAppName": "App Service name",
"loc.input.help.WebAppName": "Enter or Select the name of an existing Azure App Service. App services based on selected app type will only be listed.",
"loc.input.label.DeployToSlotFlag": "Deploy to slot",
"loc.input.help.DeployToSlotFlag": "Select the option to deploy to an existing slot other than the Production slot. If this option is not selected, then the Azure App Service will be deployed to the Production slot.",
"loc.input.label.DeployToSlotOrASEFlag": "Deploy to Slot or App Service Environment",
"loc.input.help.DeployToSlotOrASEFlag": "Select the option to deploy to an existing deployment slot or Azure App Service Environment.<br />For both the targets, the task needs Resource group name.<br />In case the deployment target is a slot, by default the deployment is done to the production slot. Any other existing slot name can also be provided.<br />In case the deployment target is an Azure App Service environment, leave the slot name as ‘production’ and just specify the Resource group name.",
"loc.input.label.ResourceGroupName": "Resource group",
"loc.input.help.ResourceGroupName": "Enter or Select the Azure Resource group that contains the Azure App Service specified above.",
"loc.input.help.ResourceGroupName": "The Resource group name is required when the deployment target is either a deployment slot or an App Service Environment.<br />Enter or Select the Azure Resource group that contains the Azure App Service specified above.",
"loc.input.label.SlotName": "Slot",
"loc.input.help.SlotName": "Enter or Select an existing Slot other than the Production slot.",
"loc.input.label.ImageSource": "Image Source",
"loc.input.help.ImageSource": "App Service on Linux offers two different options to publish your application <br/> Custom image deployment or App deployment with a built-in platform image. [Learn More](https://go.microsoft.com/fwlink/?linkid=862490)",
"loc.input.label.AzureContainerRegistry": "Registry",
"loc.input.help.AzureContainerRegistry": "A globally unique top-level domain name for your specific registry.<br/> Note: Fully qualified image name will be of the format: '<b>`<registry`></b>/`<repository`>:`<tag`>'. For example, '<b>myregistry.azurecr.io</b>/nginx:latest'.",
"loc.input.label.AzureContainerRegistryLoginServer": "Registry Login Server Name",
"loc.input.help.AzureContainerRegistryLoginServer": "Enter or Select an Azure container registry login server name.",
"loc.input.label.AzureContainerRegistryImage": "Image",
"loc.input.help.AzureContainerRegistryImage": "Name of the repository where the container images are stored.<br/> Note: Fully qualified image name will be of the format: '`<registry`>/<b>`<repository`></b>:`<tag`>'. For example, 'myregistry.azurecr.io/<b>nginx</b>:latest'.",
"loc.input.label.AzureContainerRegistryTag": "Tag",
"loc.input.help.AzureContainerRegistryTag": "Tags are optional, it is the mechanism that registries use to give Docker images a version.<br/> Note: Fully qualified image name will be of the format: '`<registry`>/`<repository`>:<b>`<tag`></b>'. For example, 'myregistry.azurecr.io/nginx:<b>latest</b>'.",
"loc.input.label.DockerRepositoryAccess": "Repository Access",
"loc.input.help.DockerRepositoryAccess": "Select the Docker repository access.",
"loc.input.label.RegistryConnectedServiceName": "Registry Connection",
"loc.input.help.RegistryConnectedServiceName": "Select the registry connection.",
"loc.input.label.PrivateRegistryImage": "Image",
"loc.input.help.PrivateRegistryImage": "Name of the repository where the container images are stored.<br/> Note: Fully qualified image name will be of the format: '`<registry`>/<b>`<repository`></b>:`<tag`>'. For example, 'myregistry.azurecr.io/<b>nginx</b>:latest'.",
"loc.input.label.PrivateRegistryTag": "Tag",
"loc.input.help.PrivateRegistryTag": "Tags are optional, it is the mechanism that registries use to give Docker images a version.<br/> Note: Fully qualified image name will be of the format: '`<registry`>/`<repository`>:<b>`<tag`></b>'. For example, 'myregistry.azurecr.io/nginx:<b>latest</b>'.",
"loc.input.label.DockerNamespace": "Registry or Namespace",
"loc.input.help.DockerNamespace": "A globally unique top-level domain name for your specific registry or namespace.<br/> Note: Fully qualified image name will be of the format: '<b>`<registry or namespace`></b>/`<repository`>:`<tag`>'. For example, '<b>myregistry.azurecr.io</b>/nginx:latest'.",
"loc.input.label.DockerRepository": "Image",
Expand All @@ -49,22 +30,16 @@
"loc.input.help.VirtualApplication": "Specify the name of the Virtual application that has been configured in the Azure portal. The option is not required for deployments to the App Service root.",
"loc.input.label.Package": "Package or folder",
"loc.input.help.Package": "File path to the package or a folder containing app service contents generated by MSBuild or a compressed zip or war file.<br />Variables ( [Build](https://www.visualstudio.com/docs/build/define/variables) | [Release](https://www.visualstudio.com/docs/release/author-release-definition/understanding-tasks#predefvariables)), wild cards are supported. <br/> For example, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip or $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.",
"loc.input.label.BuiltinLinuxPackage": "Package or folder",
"loc.input.help.BuiltinLinuxPackage": "File path to the package or a folder containing app service contents generated by MSBuild or a compressed zip or war file.<br />Variables ( [Build](https://www.visualstudio.com/docs/build/define/variables) | [Release](https://www.visualstudio.com/docs/release/author-release-definition/understanding-tasks#predefvariables)), wild cards are supported. <br/> For example, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip or $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.",
"loc.input.label.RuntimeStack": "Runtime Stack",
"loc.input.help.RuntimeStack": "Select the framework and version.",
"loc.input.label.StartupCommand": "Startup command ",
"loc.input.help.StartupCommand": "Enter the start up command.",
"loc.input.label.WebAppUri": "App Service URL",
"loc.input.help.WebAppUri": "Specify a name for the output variable that is generated for the URL of the Azure App Service. The variable can be consumed in subsequent tasks.",
"loc.input.label.ScriptType": "Deployment script type",
"loc.input.help.ScriptType": "Customize the deployment by providing a script that will run on the Azure App service once the task has completed the deployment successfully . For example restore packages for Node, PHP, Python applications. [Learn more](https://go.microsoft.com/fwlink/?linkid=843471).",
"loc.input.label.InlineScript": "Inline Script",
"loc.input.label.ScriptPath": "Deployment script path",
"loc.input.label.GenerateWebConfig": "Generate Web.config",
"loc.input.help.GenerateWebConfig": "A standard Web.config will be generated and deployed to Azure App Service if the application does not have one. The values in web.config can be edited and vary based on the application framework. For example for node.js application, web.config will have startup file and iis_node module values. [Learn more](https://go.microsoft.com/fwlink/?linkid=843469).",
"loc.input.label.WebConfigParameters": "Web.config parameters",
"loc.input.help.WebConfigParameters": "Edit values like startup file in the generated web.config file. This edit feature is only for the generated web.config. [Learn more](https://go.microsoft.com/fwlink/?linkid=843469).",
"loc.input.label.WebConfigParameters": "Generate web.config paramters for Python and Node.js apps",
"loc.input.help.WebConfigParameters": "A standard Web.config will be generated and deployed to Azure App Service if the application does not have one. The values in web.config can be edited and vary based on the application framework. For example for node.js application, web.config will have startup file and iis_node module values. This edit feature is only for the generated web.config. [Learn more](https://go.microsoft.com/fwlink/?linkid=843469).",
"loc.input.label.AppSettings": "App settings",
"loc.input.help.AppSettings": "Edit web app application settings following the syntax -key value . Value containing spaces should be enclosed in double quotes.<br /> <b>Example</b> : -Port 5000 -RequestTimeout 5000 <br /> -WEBSITE_TIME_ZONE \"Eastern Standard Time\"",
"loc.input.label.ConfigurationSettings": "Configuration settings",
Expand Down
37 changes: 16 additions & 21 deletions Tasks/AzureRmWebAppDeployment/azurermwebappdeployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ async function main() {
var azureEndpoint: AzureEndpoint = await new AzureRMEndpoint(taskParams.connectedServiceName).getEndpoint();
var virtualApplicationPath: string;
console.log(tl.loc('GotconnectiondetailsforazureRMWebApp0', taskParams.WebAppName));
if(!taskParams.DeployToSlotFlag) {
if(!taskParams.DeployToSlotOrASEFlag) {
taskParams.ResourceGroupName = await AzureResourceFilterUtility.getResourceGroupName(azureEndpoint, taskParams.WebAppName);
}

Expand All @@ -42,28 +42,23 @@ async function main() {
await appServiceUtility.pingApplication();
let kuduService: Kudu = await appServiceUtility.getKuduService();
kuduServiceUtility = new KuduServiceUtility(kuduService);
if(taskParams.WebAppUri) {
tl.setVariable(taskParams.WebAppUri, await appServiceUtility.getApplicationURL());
}
tl.setVariable('AppServiceApplicationUrl', await appServiceUtility.getApplicationURL());

if(taskParams.isLinuxApp) {
switch(taskParams.ImageSource) {
case 'Builtin': {
var webPackage = packageUtility.PackageUtility.getPackagePath(taskParams.Package);
tl.debug('Performing Linux built-in package deployment');
zipDeploymentID = await kuduServiceUtility.zipDeploy(webPackage, taskParams.TakeAppOfflineFlag, { slotName: appService.getSlot() });
await appServiceUtility.updateStartupCommandAndRuntimeStack(taskParams.RuntimeStack, taskParams.StartupCommand);
break;
}
case 'Registry': {
tl.debug("Performing container based deployment.");
let containerDeploymentUtility: ContainerBasedDeploymentUtility = new ContainerBasedDeploymentUtility(appService);
await containerDeploymentUtility.deployWebAppImage(taskParams);
break;
}
default: {
throw new Error('Invalid Image source Type');
}

if(taskParams.isBuiltinLinuxWebApp) {
var webPackage = packageUtility.PackageUtility.getPackagePath(taskParams.Package);
tl.debug('Performing Linux built-in package deployment');
zipDeploymentID = await kuduServiceUtility.zipDeploy(webPackage, taskParams.TakeAppOfflineFlag, { slotName: appService.getSlot() });
await appServiceUtility.updateStartupCommandAndRuntimeStack(taskParams.RuntimeStack, taskParams.StartupCommand);
}
else if(taskParams.isContainerWebApp) {
tl.debug("Performing container based deployment.");
let containerDeploymentUtility: ContainerBasedDeploymentUtility = new ContainerBasedDeploymentUtility(appService);
await containerDeploymentUtility.deployWebAppImage(taskParams);
}
else {
throw new Error('Invalid Image source Type');
}
}
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class ContainerBasedDeploymentUtility {
}

public async deployWebAppImage(taskParameters: TaskParameters): Promise<void> {
var imageName = this._getImageName();
let imageName: string = this._getDockerHubImageName();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jikuma - Can you review the changes related container deployment.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we are jumping task major version here. There is an opportunity for us to bring docker tasks and azure web app task in sync with how they take image name as input. in Docker tasks there is only one input image name which includes repository name and tag while azure weapp task takes them separately.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought the reason these are separate is because at some point we want to enable drop down for each of these inputs, which will not be possible if we take them as a single input.

tl.debug("Deploying an image " + imageName + " to the webapp " + this._appService.getName());

tl.debug("Updating the webapp configuration.");
Expand Down Expand Up @@ -154,7 +154,7 @@ export class ContainerBasedDeploymentUtility {
}

private async _getContainerRegistrySettings(imageName, endPoint): Promise<string> {
var containerRegistryType: string = tl.getInput('ImageSource', true);
var containerRegistryType: string = 'Registry';
var containerRegistrySettings: string = "-DOCKER_CUSTOM_IMAGE_NAME " + imageName;
var containerRegistryAuthParamsFormatString: string = "-DOCKER_REGISTRY_SERVER_URL %s -DOCKER_REGISTRY_SERVER_USERNAME %s -DOCKER_REGISTRY_SERVER_PASSWORD %s";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ export class FileTransformsUtility {

public static async applyTransformations(webPackage: string, taskParams: TaskParameters): Promise<string> {
var applyFileTransformFlag = taskParams.JSONFiles.length != 0 || taskParams.XmlTransformation || taskParams.XmlVariableSubstitution;
if (applyFileTransformFlag || taskParams.GenerateWebConfig) {
if (applyFileTransformFlag || taskParams.WebConfigParameters) {
var isFolderBasedDeployment: boolean = tl.stats(webPackage).isDirectory();
var folderPath = await deployUtility.generateTemporaryFolderForDeployment(isFolderBasedDeployment, webPackage);
if (taskParams.GenerateWebConfig) {
if (taskParams.WebConfigParameters) {
tl.debug('parsing web.config parameters');
var webConfigParameters = parse(taskParams.WebConfigParameters);
generateWebConfigUtil.addWebConfigFile(folderPath, webConfigParameters, this.rootDirectoryPath);
Expand Down
Loading