diff --git a/Tasks/AzurePowerShellV3/Strings/resources.resjson/en-US/resources.resjson b/Tasks/AzurePowerShellV3/Strings/resources.resjson/en-US/resources.resjson index d3ac96623405..0d15767fafaa 100644 --- a/Tasks/AzurePowerShellV3/Strings/resources.resjson/en-US/resources.resjson +++ b/Tasks/AzurePowerShellV3/Strings/resources.resjson/en-US/resources.resjson @@ -3,7 +3,7 @@ "loc.helpMarkDown": "[More Information](https://go.microsoft.com/fwlink/?LinkID=613749)", "loc.description": "Run a PowerShell script within an Azure environment", "loc.instanceNameFormat": "Azure PowerShell script: $(ScriptType)", - "loc.releaseNotes": "This is an early preview. Added support for Fail on standard error and ErrorActionPreference", + "loc.releaseNotes": "Added support for Fail on standard error and ErrorActionPreference", "loc.group.displayName.AzurePowerShellVersionOptions": "Azure PowerShell version options", "loc.input.label.ConnectedServiceNameSelector": "Azure Connection Type", "loc.input.label.ConnectedServiceName": "Azure Classic Subscription", diff --git a/Tasks/AzurePowerShellV3/task.json b/Tasks/AzurePowerShellV3/task.json index 7756cb2ee72d..6d9db94944f9 100644 --- a/Tasks/AzurePowerShellV3/task.json +++ b/Tasks/AzurePowerShellV3/task.json @@ -16,14 +16,13 @@ "author": "Microsoft Corporation", "version": { "Major": 3, - "Minor": 0, - "Patch": 5 + "Minor": 1, + "Patch": 0 }, - "releaseNotes": "This is an early preview. Added support for Fail on standard error and ErrorActionPreference", + "releaseNotes": "Added support for Fail on standard error and ErrorActionPreference", "demands": [ "azureps" ], - "preview": true, "groups": [ { "name": "AzurePowerShellVersionOptions", diff --git a/Tasks/AzurePowerShellV3/task.loc.json b/Tasks/AzurePowerShellV3/task.loc.json index 27cb6ee0c9f0..71e2543ac502 100644 --- a/Tasks/AzurePowerShellV3/task.loc.json +++ b/Tasks/AzurePowerShellV3/task.loc.json @@ -16,14 +16,13 @@ "author": "Microsoft Corporation", "version": { "Major": 3, - "Minor": 0, - "Patch": 5 + "Minor": 1, + "Patch": 0 }, "releaseNotes": "ms-resource:loc.releaseNotes", "demands": [ "azureps" ], - "preview": true, "groups": [ { "name": "AzurePowerShellVersionOptions", diff --git a/Tasks/AzureRmWebAppDeploymentV3/README.md b/Tasks/AzureRmWebAppDeploymentV3/README.md new file mode 100644 index 000000000000..259e2a087fc5 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/README.md @@ -0,0 +1,161 @@ +# Azure App Service Deployment: ARM + +## Overview + +The Azure App Service Deployment task is used to update different Azure App Service to deploy [Web Apps](https://azure.microsoft.com/en-in/documentation/articles/app-service-web-overview/) and [WebJobs](https://azure.microsoft.com/en-us/blog/webjobs-goes-into-full-production/) to Azure. The task works on cross platform VSTS agents running Windows, Linux or Mac and uses the underlying deployment technologies of [Web Deploy](https://www.iis.net/downloads/microsoft/web-deploy) and [Kudu REST APIs](https://github.com/projectkudu/kudu/wiki/REST-API). + +The task works for [ASP.NET](https://www.visualstudio.com/en-us/docs/release/examples/azure/azure-web-apps-from-build-and-release-hubs), [ASP.NET Core](https://www.visualstudio.com/en-us/docs/release/examples/azure/aspnet-core10-azure-web-apps), PHP, Java, Python and [Node.js](https://www.visualstudio.com/en-us/docs/release/examples/nodejs/node-to-azure-webapps) based web applications. + +The task can be used to deploy different Azure App Services like Function App, Web App on Windows, Web App on Linux, Web App for Containers and Azure App Service Environments. + +The task is **under development and is available to a limited set of accounts on Visual Studio Team Services (VSTS)**. The [video](https://www.youtube.com/watch?v=uQ2qCmaZ_Ag&feature=youtu.be) describes the features that are available in the task currently. + +## Contact Information + +Please report a problem at [Developer Community Forum](https://developercommunity.visualstudio.com/spaces/21/index.html) if you are facing problems in making this task work. Also, share feedback about the task, and the new features that you would like to see in it. + +## Pre-requisites for the task + +The following pre-requisites need to be setup in the target machine(s) for the task to work properly. + +##### Azure Web App + +The task is used to deploy a Web project to an existing Azure Web App. The Web App should exist prior to running the task. The Web App can be created from the [Azure portal](https://azure.microsoft.com/en-in/documentation/videos/azure-app-service-web-apps-with-yochay-kiriaty/) and [configured](https://azure.microsoft.com/en-us/documentation/articles/web-sites-configure/) there. Alternatively, the [Azure PowerShell task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/AzurePowerShell) can be used to run [AzureRM PowerShell scripts](https://msdn.microsoft.com/en-us/library/mt619237.aspx) to provision and configure the Web App. + +##### Azure Subscription + +To deploy to Azure, an Azure subscription has to be linked to Team Foundation Server or to Visual Studio Team Services using the Services tab in the Account Administration section. Add the Azure subscription to use in the Build or Release Management definition by opening the Account Administration screen (gear icon on the top-right of the screen) and then click on the Services Tab. + +Create the [ARM](https://azure.microsoft.com/en-in/documentation/articles/resource-group-overview/) service endpoint, use **'Azure Resource Manager'** endpoint type, for more details follow the steps listed in the link [here](https://go.microsoft.com/fwlink/?LinkID=623000&clcid=0x409). + +The task does not work with the Azure Classic service endpoint and it will not list these connections in the parameters in the task. + +##### Azure PowerShell + +The task needs the Azure PowerShell version to be installed on the automation agent, and that can be done easily using the [Azure PowerShell Installer v1.3.0](https://github.com/Azure/azure-powershell/releases/tag/v1.3.0-March2016). + +## Deployment + +Based on the type of Azure App Service and VSTS agent, the task chooses a suitable deployment technology. The different deployment technologies used by the task are: +* *Web Deploy* + +* *Kudu REST APIs* + +* *Container Registry* + +The task defaults to Web Deploy technology on a Windows Agent when the target is Web App for Windows. On other platforms (for any App service type), the task relies on [Kudu REST APIs](https://github.com/projectkudu/kudu/wiki/REST-API) to deploy the Web App. + +### Web Deploy + +Web Deploy (msdeploy.exe) is used to deploy the web application to the Azure Web App. Web Deploy Works on a Windows automation agent when the target is a Web App on Windows or Function App. Install it on the agent using the [Microsoft Web Platform Installer](https://www.microsoft.com/web/gallery/install.aspx?appid=wdeploynosmo). The Web Deploy 3.5 needs to be installed without the bundled SQL support. There is no need to choose any custom settings while installing Web Deploy. After installing the Web Deploy is available at C:\\Program Files (x86)\\IIS\\Microsoft Web Deploy V3. + +Web Deploy is feature rich and offers options like: +* **Rename locked files\*:** Rename file which are still in use by the web server by enabling msdeploy flag MSDEPLOY_RENAME_LOCKED_FILES=1 in Azure App Service application settings. The option if set enables msdeploy to rename locked files that are locked during app deployment + +* **Remove additional files at destination\*:** Deletes files on the Azure App Service that have no matching files in the App Service artifact package or folder getting deployed. + +* **Exclude files from the App_Data folder\*:** Prevent files in the App_Data folder (in the artifact package/folder getting deployed) from being deployed to the Azure App Service + +* **Additional Web Deploy arguments\*:** Arguments that will be applied when deploying the Azure App Service. Example: -disableLink:AppPoolExtension -disableLink:ContentExtension.For more examples of Web Deploy operation settings, refer [Web Deploy Operation Settings](https://go.microsoft.com/fwlink/?linkid=838471) + + +### [Kudu REST APIs](https://github.com/projectkudu/kudu/wiki/REST-API) +Works on a Windows as well as Linux automation agent when the target is a Web App on Windows or Web App on Linux (built-in source) or Function App. The task uses Kudu to copy over files to the Azure App service. + +### Container Registry +Works on a Windows as well as Linux automation agent when the target is a Web App for Containers. The task updates the Azure Web App for Containers by setting the right Container registry, repository, image name and tag information. You can also use the task to pass a startup command for the container image. + +### Parameters of the task + +The task is used to deploy a Web project to an existing Azure Web App. The mandatory fields are highlighted with a *. + +* **Azure Subscription\*:** Select the AzureRM Subscription. If none exists, then click on the **Manage** link, to navigate to the Services tab in the Administrators panel. In the tab click on **New Service Endpoint** and select **Azure Resource Manager** from the dropdown. + +* **App Service type\*:** Select the Azure App Service type. The different app types supported are Function App, Web App on Windows, Web App on Linux, Web App for Containers and Azure App Service Environments + +* **App Service Name\*:** Select the name of an existing Azure App Service. Enter the name of the Web App if it was provisioned dynamically using the [Azure PowerShell task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/AzurePowerShell) and [AzureRM PowerShell scripts](https://msdn.microsoft.com/en-us/library/mt619237.aspx). + +* **Deploy to Slot:** Select the option to deploy to an existing slot other than the Production slot. Do not select this option if the Web project is being deployed to the Production slot. The Web App itself is the Production slot. + +* **Resource Group:** Select the Azure Resource Group that contains the Azure App Service specified above. Enter the name of the Azure Resource Group if has been dynamically provisioned using [Azure Resource Group Deployment task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/DeployAzureResourceGroup) or [Azure PowerShell task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/AzurePowerShell). This is a required parameter if the option to Deploy to Slot has been selected. + +* **Slot:** Select the Slot to deploy the Web project to. Enter the name of the Slot if has been dynamically provisioned using [Azure Resource Group Deployment task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/DeployAzureResourceGroup) or [Azure PowerShell task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/AzurePowerShell). This is a required parameter if the option to Deploy to Slot has been selected. + +* **Virtual Application:** Specify the name of the Virtual Application that has been configured in the Azure portal. The option is not required for deployments to the website root. The Virtual Application should have been [configured](https://azure.microsoft.com/en-us/documentation/articles/web-sites-configure/) prior to deploying the Web project to it using the task. + +* **Package or Folder\*:** Location of the Web App zip package or folder on the automation agent or on a UNC path accessible to the automation agent like, \\\\BudgetIT\\Web\\Deploy\\Fabrikam.zip. Predefined system variables and wild cards like, $(System.DefaultWorkingDirectory)\\\***.zip can be also used here. + +* **Publish using Web Deploy:** Select the option to use Web Deploy technology on a Windows Agent. On other platforms, the task implicitly relies on [Kudu REST APIs](https://github.com/projectkudu/kudu/wiki/REST-API) to deploy the web App and following Web deploy options are not supported. + +* **Parameters File:** (Optional) The parameter file is used to override the default settings in the web deploy zip package file like, the IIS Web application name or the database connection string. This helps in having a single package that can be deployed across dev, test, staging, and production, with a specific parameter file for each environment. + +* **Remove Additional Files at Destination:** Select the option to delete the files in the Azure App Service that have no matching files in the Web App zip package. This will ensure that during the Web project deployment any additional files in the Azure App Service are deleted, and the only files in the Azure App Service are the ones in the Web App zip package. +This will also remove all files related to any extension (for example Application Insights) installed on this Azure App Service. To prevent this, enable 'Exclude files from App_Data folder' as well. + +* **Exclude Files from the App_Data Folder:** Select the option to prevent files in the App_Data folder from being deployed to the Azure App Service. This is a useful option to select, if a local database or a WebJob has been deployed earlier to the Azure App Service, and they should not be deleted in the subsequent deployments of the Web project. + +* **Take Application Offline:** Select the option to take the Azure App Service offline by placing an app_offline.htm file in the root directory of the Web App before the sync operation begins. The file will be removed after the sync operation completes successfully. + +* **Additional Arguments:** Additional Web Deploy arguments that will be appended to the MSDeploy command while deploying the Azure Web App like,-disableLink:AppPoolExtension -disableLink:ContentExtension. A useful parameter for enabling and disabling rules and for skipping syncing of certain folders. + +* **Generate Web.config:** A standard Web.config will be generated and deployed to Azure App Service if the application does not have one. For example, for [Nodejs application, web.config](https://github.com/projectkudu/kudu/wiki/Using-a-custom-web.config-for-Node-apps) will have startup file and iis_node module values. Similarly for Python (Bottle, Django, Flask) the web.config will have details of WSGI handler, Python path etc. The task will generate a new web.config only when the artifact package/folder does not contain an existing web.config. The default values populated by the task can be overriden in the task by using the Web.config parameters field. + +* **Web.config parameters:** Edit values like startup file in the task generated web.config file. The default values populated by the task can be overridden in the task by passing the web.config parameters. This edit feature is **only for the generated web.config**. Feature is useful when [Azure App Service Manage task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/AzureAppServiceManage) is used to install specific Python version by using extensions or when you want to provide a different startup file for Node.js. +In case of Python, the path can be set as an output variable of the [Azure App Service Manage task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/AzureAppServiceManage) and then set as the Python path in the web.config generated by this deploy task. You can try out this feature by selecting any Python, Nodejs, PHP release definition template. + +* **Deployment script:** +The task provides an option to customize the deployment by providing a script that will run on the Azure App Service once the application artifacts have been copied successfully to the App Service. You can choose to either provide an inline deployment script or point to a script file in your atifact folder. This is very useful when you want to restore your application dependencies on the App service directly. Restoring packages of Node, PHP, Python applications helps in avoiding timeouts when the application dependency results in a large artifact getting copied over from VSTS Agent to Azure app service. An example of this script is: + +>@echo off +>if NOT exist requirements.txt ( +> echo No Requirements.txt found. +> EXIT /b 0 +>) +>if NOT exist "$(PYTHON_EXT)/python.exe" ( +> echo Python extension not available >&2 +> EXIT /b 1 +>) +>echo Installing dependencies +>call "$(PYTHON_EXT)/python.exe" -m pip install -U setuptools +>if %errorlevel% NEQ 0 ( +> echo Failed to install setuptools >&2 +> EXIT /b 1 +>) +>call "$(PYTHON_EXT)/python.exe" -m pip install -r requirements.txt +>if %errorlevel% NEQ 0 ( +> echo Failed to install dependencies>&2 + EXIT /b 1 +) + +* **Image Source:** +App Service on Linux offers two different options to publish your application, one is Custom image deployment (Web App for Containers) and the other is App deployment with a built-in platform image (Web App on Linux). You will see this parameter only when you selected 'Linux Web App' in the App type selection option in the task. + +For Web **Web App for Containers** you need to provide the following details: +* *Registry or Namespace:* +A globally unique top-level domain name for your specific registry or namespace. A fully qualified image name will be of the format: '/:'. For example, 'myregistry.azurecr.io/nginx:latest'. + +* *Image:* +Image Name of the repository where the container images are stored. A fully qualified image name will be of the format: '/:'. For example, 'myregistry.azurecr.io/nginx:latest'. + +* *Tag:* +Tags are optional, it is the mechanism that registries use to give Docker images a version. A fully qualified image name will be of the format: '/:'. For example, 'myregistry.azurecr.io/nginx:latest'. + +* *Startup command:* +Start up command for the container. + +For Web **Web App on Linux** you need to provide the following details: +* *Runtime stack:* Select the framework and version your web app will run on. + +* *Startup command:* +Start up command for the app. For example if you are using PM2 process manager for Nodejs then you can specify the PM2 file here. + +### Output Variables + +* **Web App Hosted URL:** Provide a name, like FabrikamWebAppURL for the variable for the Azure App Service Hosted URL. The variable can be used as $(variableName), like $(FabrikamWebAppURL) to refer to the Hosted URL of the Azure App Service in subsequent tasks like in the [Run Functional Tests task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/RunDistributedTests) or the [Visual Studio Test task](https://github.com/Microsoft/vsts-tasks/tree/master/Tasks/VsTest). + + +### FAQ +* To ignore SSL error set a Variable of name VSTS_ARM_REST_IGNORE_SSL_ERRORS with value : true in the release definition. +* The task works with the [Azure Resource Manager APIs](https://msdn.microsoft.com/en-us/library/azure/dn790568.aspx) only. +* For avoiding deployment failure with error code ERROR_FILE_IN_USE, in case of .NET apps targeting Web App on Windows, ensure that 'Rename locked files' and 'Take App Offline' are enabled. For zero downtime deployment use slot swap. +* When deploying to an App Service with App Insights configured, if you have enabled “Remove additional files at destination” then you also need to enable “Exclude files from the App_Data folder” in order to keep App insights extension in safe state. This is required because App Insights continuous web job gets installed into the App_Data folder. diff --git a/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/de-de/resources.resjson b/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/de-de/resources.resjson new file mode 100644 index 000000000000..583b1735075e --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/de-de/resources.resjson @@ -0,0 +1,219 @@ +{ + "loc.friendlyName": "Azure App Service-Bereitstellung", + "loc.helpMarkDown": "[Weitere Informationen](https://aka.ms/azurermwebdeployreadme)", + "loc.description": "Hiermit werden Azure WebApp-Dienste unter Windows, Web-Apps unter Linux mit integrierten Images oder Docker-Containern, ASP.NET-, .NET Core-, PHP-, Python- oder Node-basierte Webanwendungen, Funktions-Apps, mobile Apps, API-Anwendungen, WebJos mit basierte Web-Applikationen, Function Apps, Mobile Apps, API-Anwendungen, WebJobs mit Web Deploy/Kudu-REST-APIs aktualisiert.", + "loc.instanceNameFormat": "Azure App Service bereitstellen: $(WebAppName)", + "loc.releaseNotes": "Neues in Version 3.0:
  Unterstützt Dateiumwandlungen (XDT)
  Unterstützt Variablenersetzungen (XML, JSON)
Klicken Sie [hier](https://aka.ms/azurermwebdeployreadme), um weitere Informationen zu erhalten.", + "loc.group.displayName.FileTransformsAndVariableSubstitution": "Optionen für Dateitransformationen und Variablenersetzungen", + "loc.group.displayName.AdditionalDeploymentOptions": "Zusätzliche Bereitstellungsoptionen", + "loc.group.displayName.PostDeploymentAction": "Aktion nach der Bereitstellung", + "loc.group.displayName.ApplicationAndConfigurationSettings": "Anwendungs- und Konfigurationseinstellungen", + "loc.group.displayName.output": "Ausgabe", + "loc.input.label.ConnectedServiceName": "Azure-Abonnement", + "loc.input.help.ConnectedServiceName": "Wählen Sie das Azure Resource Manager-Abonnement für die Bereitstellung aus.", + "loc.input.label.WebAppKind": "App-Typ", + "loc.input.help.WebAppKind": "Wählen Sie den Typ der Web-App, die bereitgestellt werden soll.
Hinweis: Wählen Sie eine Linux-Web-App aus, um integrierte Plattformimages zu verwenden, oder stellen Sie ein benutzerdefiniertes Containerimage bereit.", + "loc.input.label.WebAppName": "App Service-Name", + "loc.input.help.WebAppName": "Geben Sie den Namen eines vorhandenen Azure App Service ein, oder wählen Sie ihn aus. Es werden nur App-Dienste für den ausgewählten App-Typ angezeigt.", + "loc.input.label.DeployToSlotFlag": "In Slot bereitstellen", + "loc.input.help.DeployToSlotFlag": "Wählen Sie diese Option aus, um die Bereitstellung nicht im Produktionsslot, sondern in einem anderen vorhandenen Slot durchzuführen. Wenn diese Option nicht aktiviert ist, wird der Azure App Service im Produktionsslot bereitgestellt.", + "loc.input.label.ResourceGroupName": "Ressourcengruppe", + "loc.input.help.ResourceGroupName": "Geben Sie die Azure-Ressourcengruppe ein, die den oben angegebene Azure App Service enthält, oder wählen Sie sie aus.", + "loc.input.label.SlotName": "Slot", + "loc.input.help.SlotName": "Geben Sie einen anderen vorhandenen Slot als den Produktionsslot ein, oder wählen Sie ihn aus.", + "loc.input.label.ImageSource": "Imagequelle", + "loc.input.help.ImageSource": "App Service unter Linux bietet zwei verschiedene Optionen, um Ihre Anwendung zu veröffentlichen.
Sie können benutzerdefinierte Images bereitstellen oder eine App-Bereitstellung mithilfe eines integrierten Plattformimages durchführen. [Weitere Informationen](https://go.microsoft.com/fwlink/?linkid=862490)", + "loc.input.label.AzureContainerRegistry": "Registrierung", + "loc.input.help.AzureContainerRegistry": "Ein global eindeutiger Name einer Domäne der obersten Ebene für Ihre spezifische Registrierung.
Hinweis: Vollqualifizierte Imagenamen erhalten das folgende Format: \"'`/`:`'\". Beispiel: \"myregistry.azurecr.io/nginx:latest\".", + "loc.input.label.AzureContainerRegistryLoginServer": "Name des Anmeldeservers für die Registrierung", + "loc.input.help.AzureContainerRegistryLoginServer": "Geben Sie einen Namen für einen Azure Container Registry-Anmeldeserver ein, oder wählen Sie einen Server aus.", + "loc.input.label.AzureContainerRegistryImage": "Image", + "loc.input.help.AzureContainerRegistryImage": "Name des Repositorys, in dem Containerimages gespeichert werden.
Hinweis: Vollqualifizierte Imagenamen erhalten das folgende Format: \"'`/`:`'\". Beispiel: \"myregistry.azurecr.io/nginx:latest\".", + "loc.input.label.AzureContainerRegistryTag": "Tag", + "loc.input.help.AzureContainerRegistryTag": "Tags sind optional. Sie werden von den Registrierungen genutzt, um eine Version für die Docker-Images zu vergeben.
Hinweis: Vollqualifizierte Imagenamen erhalten das folgende Format: \"`/`:`\". Beispiel: \"myregistry.azurecr.io/nginx:latest\".", + "loc.input.label.DockerRepositoryAccess": "Repositoryzugriff", + "loc.input.help.DockerRepositoryAccess": "Wählen Sie den Docker-Repositoryzugriff aus.", + "loc.input.label.RegistryConnectedServiceName": "Registrierungsverbindung", + "loc.input.help.RegistryConnectedServiceName": "Wählen Sie die Registrierungsverbindung aus.", + "loc.input.label.PrivateRegistryImage": "Image", + "loc.input.help.PrivateRegistryImage": "Name des Repositorys, in dem Containerimages gespeichert werden.
Hinweis: Vollqualifizierte Imagenamen erhalten das folgende Format: \"'`/`:`'\". Beispiel: \"myregistry.azurecr.io/nginx:latest\".", + "loc.input.label.PrivateRegistryTag": "Tag", + "loc.input.help.PrivateRegistryTag": "Tags sind optional. Sie werden von den Registrierungen genutzt, um eine Version für die Docker-Images zu vergeben.
Hinweis: Vollqualifizierte Imagenamen erhalten das folgende Format: \"`/`:`\". Beispiel: \"myregistry.azurecr.io/nginx:latest\".", + "loc.input.label.DockerNamespace": "Registrierung oder Namespace", + "loc.input.help.DockerNamespace": "Eine global eindeutiger Name einer Domäne der obersten Ebene für Ihre spezifische Registrierung oder den Namespace.
Hinweis: Vollqualifizierte Imagenamen haben das folgende Format: \"`/`:`\". Beispiel: \"myregistry.azurecr.io/nginx:latest\".", + "loc.input.label.DockerRepository": "Image", + "loc.input.help.DockerRepository": "Name des Repositorys, in dem Containerimages gespeichert werden.
Hinweis: Vollqualifizierte Imagenamen haben das folgende Format: \"'/`:`\". Beispiel: \"myregistry.azurecr.io/nginx:latest\".", + "loc.input.label.DockerImageTag": "Tag", + "loc.input.help.DockerImageTag": "Tags sind optional. Sie werden von den Registrierungen genutzt, um eine Version für die Docker-Images zu vergeben.
Hinweis: Vollqualifizierte Imagenamen haben das folgende Format: \"`/`:`\". Beispiel: \"myregistry.azurecr.io/nginx:latest\".", + "loc.input.label.VirtualApplication": "Virtuelle Anwendung", + "loc.input.help.VirtualApplication": "Geben Sie den Namen der virtuellen Anwendung ein, die im Azure-Portal konfiguriert wurde. Die Option ist für Bereitstellungen im App Service-Stamm nicht erforderlich.", + "loc.input.label.Package": "Paket oder Ordner", + "loc.input.help.Package": "Dateipfad zum Paket, ein Ordner mit über MSBuild generierten App Service-Inhalten oder eine komprimierte ZIP- oder WAR-Datei.
Variablen ([Build](https://www.visualstudio.com/docs/build/define/variables) | [Release](https://www.visualstudio.com/docs/release/author-release-definition/understanding-tasks#predefvariables)) und Platzhalter werden unterstützt.
Beispiel: $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip oder $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.BuiltinLinuxPackage": "Paket oder Ordner", + "loc.input.help.BuiltinLinuxPackage": "Dateipfad zum Paket, ein Ordner mit über MSBuild generierten App Service-Inhalten oder eine komprimierte ZIP- oder WAR-Datei.
Variablen ([Build](https://www.visualstudio.com/docs/build/define/variables) | [Release](https://www.visualstudio.com/docs/release/author-release-definition/understanding-tasks#predefvariables)) und Platzhalter werden unterstützt.
Beispiel: $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip oder $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.RuntimeStack": "Runtimestapel", + "loc.input.help.RuntimeStack": "Wählen Sie Framework und Version aus.", + "loc.input.label.StartupCommand": "Startbefehl ", + "loc.input.help.StartupCommand": "Geben Sie den Startbefehl ein.", + "loc.input.label.WebAppUri": "App Service-URL", + "loc.input.help.WebAppUri": "Geben Sie einen Namen für die Ausgabevariable an, die für die Azure App Service-URL generiert wird. Die Variable kann in nachfolgenden Tasks verwendet werden.", + "loc.input.label.ScriptType": "Bereitstellungsskripttyp", + "loc.input.help.ScriptType": "Passen Sie die Bereitstellung durch das Angeben eines Skripts an, das im Azure App Service ausgeführt wird, nachdem die Aufgabe die Bereitstellung erfolgreich abgeschlossen hat. Stellen Sie beispielsweise Pakete für Node-, PHP- oder Python-Anwendungen wieder her. [Weitere Informationen](https://go.microsoft.com/fwlink/?linkid=843471).", + "loc.input.label.InlineScript": "Inlineskript", + "loc.input.label.ScriptPath": "Bereitstellungsskriptpfad", + "loc.input.label.GenerateWebConfig": "Web.config erstellen", + "loc.input.help.GenerateWebConfig": "Eine Web.config-Standarddatei wird erstellt und für Azure App Service bereitgestellt, wenn die Anwendung über keine solche Datei verfügt. Die Werte in einer Web.config-Datei können bearbeitet werden und variieren je nach Anwendungsframework. Für eine node.js-Anwendung umfasst \"web.config\" beispielsweise eine Startdatei und iis_node-Modulwerte. [Weitere Informationen](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.WebConfigParameters": "Web.config-Parameter", + "loc.input.help.WebConfigParameters": "Bearbeiten Sie Werte wie die Startdatei in der erstellten web.config-Datei. Diese Bearbeitungsfunktion kann nur für die erstellte \"web.config\" verwendet werden. [Weitere Informationen](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.AppSettings": "App-Einstellungen", + "loc.input.help.AppSettings": "Web-app-Anwendungseinstellungen folgt die Syntax bearbeiten-Wert. Wert, die Leerzeichen enthalten, muss in doppelte Anführungszeichen eingeschlossen werden.
Beispiel :-Port 5000 - RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Eastern Standard Time\"", + "loc.input.label.ConfigurationSettings": "Konfigurationseinstellungen", + "loc.input.help.ConfigurationSettings": "Bearbeiten Sie die Web-app-Clientkonfigurationseinstellungen folgt die Syntax-Wert. Wert, die Leerzeichen enthalten, muss in doppelte Anführungszeichen eingeschlossen werden.
Beispiel: - PhpVersion 5.6 - LinuxFxVersion: Knoten|6.11", + "loc.input.label.TakeAppOfflineFlag": "App offline schalten", + "loc.input.help.TakeAppOfflineFlag": "Wählen Sie diese Option aus, um den Azure App Service offline zu schalten, indem vor dem Synchronisierungsvorgang eine Datei \"app_offline.htm\" im App Service-Stammverzeichnis platziert wird. Die Datei wird entfernt, nachdem der Synchronisierungsvorgang erfolgreich abgeschlossen wurde.", + "loc.input.label.UseWebDeploy": "Mit Web Deploy veröffentlichen", + "loc.input.help.UseWebDeploy": "Eine Veröffentlichung unter Verwendung von Web Deploy-Optionen wird nur unterstützt, wenn der Windows-Agent verwendet wird. Auf anderen Plattformen stützt sich der Task auf [Kudu-REST-APIs](https://github.com/projectkudu/kudu/wiki/REST-API), um den Azure App Service bereitzustellen, und die folgenden Optionen werden nicht unterstützt.", + "loc.input.label.SetParametersFile": "SetParameters-Datei", + "loc.input.help.SetParametersFile": "Optional: Speicherort für die zu verwendende Datei \"SetParameters.xml\".", + "loc.input.label.RemoveAdditionalFilesFlag": "Zusätzliche Dateien am Ziel entfernen", + "loc.input.help.RemoveAdditionalFilesFlag": "Wählen Sie diese Option aus, um Dateien im Azure App Service zu löschen, für die keine übereinstimmenden Dateien im Paket oder Ordner des App Service vorhanden sind.

Hierdurch werden auch alle zugehörigen Dateien für Erweiterungen entfernt, die in diesem Azure App Service installiert sind. Um dies zu verhindern, aktivieren Sie das Kontrollkästchen \"Dateien aus App_Data-Ordner ausschließen\".", + "loc.input.label.ExcludeFilesFromAppDataFlag": "Dateien aus dem Ordner \"App_Data\" ausschließen", + "loc.input.help.ExcludeFilesFromAppDataFlag": "Wählen Sie diese Option aus, um zu verhindern, dass Dateien im Ordner \"App_Data\" im Azure App Service bereitgestellt werden.", + "loc.input.label.AdditionalArguments": "Zusätzliche Argumente", + "loc.input.help.AdditionalArguments": "Weitere Web Deploy-Argumente mit der Syntax \"-key:value\".
Diese werden angewendet, wenn der Azure App Service bereitgestellt wird. Beispiel: -disableLink:AppPoolExtension -disableLink:ContentExtension.
Weitere Beispiele für Einstellungen für den Web Deploy-Vorgang finden Sie [hier] (https://go.microsoft.com/fwlink/?linkid=838471).", + "loc.input.label.RenameFilesFlag": "Gesperrte Dateien umbenennen", + "loc.input.help.RenameFilesFlag": "Wählen Sie die Option aus, um das msdeploy-Flag MSDEPLOY_RENAME_LOCKED_FILES=1 in den Azure App Service-Anwendungseinstellungen zu aktivieren. Wenn diese Option festgelegt ist, kann \"msdeploy\" gesperrte Dateien umbenennen, die während der App-Bereitstellung gesperrt sind.", + "loc.input.label.XmlTransformation": "XML-Transformation", + "loc.input.help.XmlTransformation": "Die Konfigurationstransformationen werden für \"*.Release.config\" und \"*..config\" in der Datei \"*.config\" ausgeführt.
Konfigurationstransformationen werden vor der Variablenersetzung ausgeführt.
XML-Transformationen werden nur für Windows-Plattformen unterstützt.", + "loc.input.label.XmlVariableSubstitution": "XML-Variablenersetzung", + "loc.input.help.XmlVariableSubstitution": "In der Build- oder Releasedefinition definierte Variablen werden mit den Einträgen \"key\" oder \"name\" in den appSettings-, applicationSettings- und connectionStrings-Abschnitten jeder Konfigurationsdatei und \"parameters.xml\"-Datei abgeglichen. Die Variablenersetzung wird nach den Konfigurationstransformationen ausgeführt.

Hinweis: Wenn in der Releasedefinition und der Umgebung dieselben Variablen definiert wurden, haben die Umgebungsvariablen Vorrang vor den Variablen der Releasedefinition.
", + "loc.input.label.JSONFiles": "JSON-Variablenersetzung", + "loc.input.help.JSONFiles": "Stellen Sie eine durch Zeilenumbrüche getrennte Liste der JSON-Dateien für die Ersetzung der Variablenwerte bereit. Die Dateinamen müssen relativ zum Stammordner angegeben werden.
Um geschachtelte oder hierarchische JSON-Variablen zu ersetzen, geben Sie diese mithilfe von JSONPath-Ausdrücken an.

Um etwa im Beispiel unten den Wert von \"ConnectionString\" zu ersetzen, müssen Sie in der Build- oder Releasedefinition (oder der Umgebung der Releasedefinition) eine Variable als \"Data.DefaultConnection.ConnectionString\" definieren.
{
  \"Data\": {
    \"DefaultConnection\": {
      \"ConnectionString\": \"Server=(localdb)\\SQLEXPRESS;Database=MyDB;Trusted_Connection=True\"
    }
  }
}
Die Variablenersetzung wird nach den Konfigurationstransformationen durchgeführt.

Hinweis: Systemdefinitionsvariablen des Builds bzw. Releases sind von der Ersetzung ausgenommen.", + "loc.messages.Invalidwebapppackageorfolderpathprovided": "Ungültiges App Service-Paket oder ungültiger App Service-Ordnerpfad angegeben: %s", + "loc.messages.SetParamFilenotfound0": "Datei zum Festlegen der Parameter nicht gefunden: %s", + "loc.messages.XDTTransformationsappliedsuccessfully": "Die XML-Transformationen wurden erfolgreich angewendet.", + "loc.messages.GotconnectiondetailsforazureRMWebApp0": "Die Verbindungsdetails für Azure App Service wurden abgerufen: \"%s\"", + "loc.messages.ErrorNoSuchDeployingMethodExists": "Fehler: Keine solche Bereitstellungsmethode vorhanden.", + "loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp": "Die Verbindungsdetails für Azure App Service können nicht abgerufen werden: %s. Statuscode: %s (%s)", + "loc.messages.UnabletoretrieveResourceID": "Die Verbindungsdetails für die Azure-Ressource konnten nicht abgerufen werden: \"%s\". Statuscode: %s", + "loc.messages.CouldnotfetchaccesstokenforAzureStatusCode": "Das Zugriffstoken für Azure konnte nicht abgerufen werden. Statuscode: %s (%s)", + "loc.messages.Successfullyupdateddeploymenthistory": "Der Bereitstellungsverlauf unter \"%s\" wurde erfolgreich aktualisiert.", + "loc.messages.Failedtoupdatedeploymenthistory": "Fehler beim Aktualisieren des Bereitstellungsverlaufs. Fehler: %s", + "loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "WARNUNG: Der Bereitstellungsstatus kann nicht aktualisiert werden: Der SCM-Endpunkt ist für diese Website nicht aktiviert.", + "loc.messages.Unabletoretrievewebconfigdetails": "Die App Service-Konfigurationsdetails können nicht abgerufen werden. Statuscode: \"%s\"", + "loc.messages.Unabletoretrievewebappsettings": "Die App Service-Anwendungseinstellungen können nicht abgerufen werden. [Statuscode: %s, Fehlermeldung: %s]", + "loc.messages.Unabletoupdatewebappsettings": "Die App Service-Anwendungseinstellungen können nicht aktualisiert werden. Statuscode: \"%s\"", + "loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "Der Bereitstellungsstatus kann nicht aktualisiert werden: Die eindeutige Bereitstellungs-ID kann nicht abgerufen werden.", + "loc.messages.PackageDeploymentSuccess": "Web-Paket für den App Service erfolgreich bereitgestellt.", + "loc.messages.PackageDeploymentFailed": "Fehler beim Bereitstellen des Web-Pakets für den App Service.", + "loc.messages.Runningcommand": "Befehl wird ausgeführt: %s", + "loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath": "Webpaket \"%s\" wird im virtuellen Pfad (physischen Pfad) bereitgestellt: %s (%s)", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Das Paket \"%s\" wurde unter Verwendung des Kudu-Diensts erfolgreich unter \"%s\" bereitgestellt.", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Fehler beim Bereitstellen des App Service-Pakets mithilfe des Kudu-Diensts: %s", + "loc.messages.Unabletodeploywebappresponsecode": "Der App Service kann nicht bereitgestellt werden. Fehlercode: %s", + "loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "Mit MSDeploy generierte Pakete werden nur für Windows-Plattformen unterstützt.", + "loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "Nicht unterstützte installierte Version %s für MSDeploy gefunden. Version 3 oder höher muss installiert sein.", + "loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError": "Der Speicherort von MS Deploy wurde nicht in der Registrierung auf dem Computer gefunden (Fehler: %s).", + "loc.messages.Nopackagefoundwithspecifiedpattern": "Kein Paket mit dem angegebenen Muster gefunden: %s", + "loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "Mindestens zwei Pakete stimmten mit dem angegebenen Suchmuster überein: %s. Schränken Sie das Suchmuster ein.", + "loc.messages.Trytodeploywebappagainwithappofflineoptionselected": "Versuchen Sie, den App Service mit ausgewählter Option \"Anwendung offline schalten\" erneut bereitzustellen.", + "loc.messages.Trytodeploywebappagainwithrenamefileoptionselected": "Versuchen Sie, den App Service mit ausgewählter Option \"Gesperrte Dateien umbenennen\" erneut bereitzustellen.", + "loc.messages.NOJSONfilematchedwithspecificpattern": "Keine JSON-Datei stimmte mit dem angegebenen Muster überein: %s", + "loc.messages.Configfiledoesntexists": "Die Konfigurationsdatei \"%s\" ist nicht vorhanden.", + "loc.messages.Failedtowritetoconfigfilewitherror": "Fehler beim Schreiben in die Konfigurationsdatei \"%s\". Fehler: %s ", + "loc.messages.AppOfflineModeenabled": "Der App-Offlinemodus wurde aktiviert.", + "loc.messages.Failedtoenableappofflinemode": "Fehler beim Aktivieren des App-Offlinemodus. Statuscode: %s (%s)", + "loc.messages.AppOflineModedisabled": "Der App-Offlinemodus wurde deaktiviert.", + "loc.messages.FailedtodisableAppOfflineMode": "Fehler beim Deaktivieren des App-Offlinemodus. Statuscode: %s (%s)", + "loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform": "XML-Transformationen können auf einer Nicht-Windows-Plattform nicht ausgeführt werden.", + "loc.messages.XdtTransformationErrorWhileTransforming": "XML-Transformationsfehler beim Transformieren von \"%s\" unter Verwendung von \"%s\".", + "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Eine Veröffentlichung unter Verwendung von webdeploy-Optionen wird nur unterstützt, wenn der Windows-Agent verwendet wird. ", + "loc.messages.ResourceDoesntExist": "Die Ressource \"%s\" ist nicht vorhanden. Die Ressource muss vor der Bereitstellung vorhanden sein.", + "loc.messages.EncodeNotSupported": "Erkannte Codierung der Datei \"%s\": %s. Eine Variablenersetzung wird für die Dateicodierung \"%s\" nicht unterstützt. Unterstützte Codierungen sind UTF-8 und UTF-16 LE.", + "loc.messages.UnknownFileEncodeError": "Die Codierung der Datei \"%s\" wurde nicht erkannt (typeCode: %s). Unterstützte Codierungen sind UTF-8 und UTF-16 LE.", + "loc.messages.ShortFileBufferError": "Der Dateipuffer ist zu klein, um den Codierungstyp zu erkennen: %s", + "loc.messages.FailedToUpdateAzureRMWebAppConfigDetails": "Fehler beim Aktualisieren der App Service-Konfigurationsdetails. Fehler: %s", + "loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails": "Die App Service-Konfigurationsdetails wurden erfolgreich aktualisiert.", + "loc.messages.RequestedURLforkuduphysicalpath": "Angeforderte URL für physischen Kudu-Pfad: %s", + "loc.messages.Physicalpathalreadyexists": "Der physische Pfad \"%s\" ist bereits vorhanden.", + "loc.messages.KuduPhysicalpathCreatedSuccessfully": "Der physische Kudu-Pfad wurde erfolgreich erstellt: %s", + "loc.messages.FailedtocreateKuduPhysicalPath": "Fehler beim Erstellen des physischen Kudu-Pfads. Fehler: %s", + "loc.messages.FailedtocheckphysicalPath": "Fehler beim Überprüfen des physischen Kudu-Pfads. Fehlercode: %s", + "loc.messages.VirtualApplicationDoesNotExist": "Die virtuelle Anwendung ist nicht vorhanden: %s", + "loc.messages.JSONParseError": "Die JSON-Datei konnte nicht analysiert werden: %s. Fehler: %s", + "loc.messages.JSONvariablesubstitutionappliedsuccessfully": "Die JSON-Variablenersetzung wurde erfolgreich angewendet.", + "loc.messages.XMLvariablesubstitutionappliedsuccessfully": "XML-Variablenersetzung erfolgreich angewendet.", + "loc.messages.failedtoUploadFileToKudu": "Datei \"%s\" kann nicht in Kudu (%s) hochgeladen werden. Statuscode: %s", + "loc.messages.failedtoUploadFileToKuduError": "Hochladen der Datei: %s auf Kudu (%s) nicht möglich. Fehler: %s", + "loc.messages.ExecuteScriptOnKudu": "Das angegebene Skript wird im Kudu-Dienst ausgeführt.", + "loc.messages.FailedToRunScriptOnKuduError": "Das Skript kann nicht im Kudu-Dienst ausgeführt werden. Fehler: %s", + "loc.messages.FailedToRunScriptOnKudu": "Ausführen des Skripts in Kudu nicht möglich: %s. Statuscode: %s", + "loc.messages.ScriptExecutionOnKuduSuccess": "Skript in Kudu erfolgreich ausgeführt.", + "loc.messages.ScriptExecutionOnKuduFailed": "Das ausgeführte Skript hat \"%s\" als Rückgabecode zurückgegeben. Fehler: %s", + "loc.messages.FailedtoDeleteFileFromKudu": "Die Datei \"%s\" kann nicht aus Kudu (%s) gelöscht werden. Statuscode: %s", + "loc.messages.FailedtoDeleteFileFromKuduError": "Löschen der Datei: %s von Kudu (%s) nicht möglich. Fehler: %s", + "loc.messages.ScriptFileNotFound": "Skriptdatei \"%s\" nicht gefunden.", + "loc.messages.InvalidScriptFile": "Ungültige Skriptdatei \"%s\" angegeben. Gültige Erweiterungen sind \".bat\" und \".cmd\" für Windows und \".sh\" für Linux.", + "loc.messages.RetryForTimeoutIssue": "Fehler beim Ausführen des Skripts mit Zeitüberschreitung. Es wird noch mal versucht.", + "loc.messages.stdoutFromScript": "Standardausgabe von Skript:", + "loc.messages.stderrFromScript": "Standardfehler von Skript:", + "loc.messages.WebConfigAlreadyExists": "web.config-Datei ist bereits vorhanden. Sie wird nicht erstellt.", + "loc.messages.SuccessfullyGeneratedWebConfig": "web.config-Datei erfolgreich erstellt.", + "loc.messages.FailedToGenerateWebConfig": "Fehler beim Erstellen von \"web.config\". %s", + "loc.messages.FailedToGetKuduFileContent": "Dateiinhalt konnte nicht abgerufen werden: %s. Statuscode: %s (%s)", + "loc.messages.FailedToGetKuduFileContentError": "Dateiinhalt konnte nicht abgerufen werden: %s. Fehler: %s", + "loc.messages.ScriptStatusTimeout": "Skriptstatus konnte aufgrund einer Zeitüberschreitung nicht abgerufen werden.", + "loc.messages.PollingForFileTimeOut": "Der Skriptstatus konnte aufgrund einer Zeitüberschreitung nicht abgerufen werden. Sie können das Zeitlimit erhöhen, indem Sie die erforderliche Minutenzahl für die Variable \"appservicedeploy.retrytimeout\" festlegen.", + "loc.messages.InvalidPollOption": "Ungültige Abrufoption angegeben: %s.", + "loc.messages.MissingAppTypeWebConfigParameters": "Das Attribut \"-appType\" fehlt in den Parametern \"Web.config\". Gültige Werte für \"-appType\" sind: \"python_Bottle\", \"python_Django\", \"python_Flask\" und \"node\".
Beispiel: \"-appType python_Bottle\" (ohne Anführungszeichen) im Fall von Python Bottle-Framework.", + "loc.messages.AutoDetectDjangoSettingsFailed": "Der Pfad für die Datei \"settings.py\" von DJANGO_SETTINGS_MODULE 'settings.py' wurde nicht gefunden. Überprüfen Sie, ob die Datei \"settings.py\" existiert, oder geben Sie den korrekten Pfad in der Parametereingabe \"Web.config\" im folgenden Format an: \"-DJANGO_SETTINGS_MODULE .settings\".", + "loc.messages.FailedToApplyTransformation": "Die Transformation für das angegebene Paket kann nicht angewendet werden. Führen Sie die folgenden Schritte aus.", + "loc.messages.FailedToApplyTransformationReason1": "1. Prüfen Sie, ob die Transformation für das beim Build generierte MSBuild-Paket bereits angewendet wurde. Ist dies der Fall, entfernen Sie das Tag aus allen Konfigurationen in der CSPROJ-Datei, und führen Sie den Build erneut aus. ", + "loc.messages.FailedToApplyTransformationReason2": "2. Stellen Sie sicher, dass sich die Konfigurationsdatei und die Transformationsdateien im selben Ordner im Paket befinden.", + "loc.messages.AutoParameterizationMessage": "ConnectionString-Attribute in Web.config ist standardmäßig parametrisiert. Beachten Sie, dass die Transformation keine Auswirkungen auf connectionString-Attribute hat, da der Wert bei der Bereitstellung durch Dateien vom Typ \"Parameters.xml\" oder \"SetParameters.xml\" überschrieben wird. Sie können die automatische Parametrisierung deaktivieren, indem Sie beim Erstellung des MSBuild-Pakets die Einstellung \"/p:AutoParameterizationWebConfigConnectionStrings=False\" festlegen.", + "loc.messages.UnsupportedAppType": "App-Typ \"%s\" wird beim Erstellen von \"Web.config\" nicht unterstützt. Gültige Werte für \"-appType\" sind: \"python_Bottle\", \"python_Django\", \"python_Flask\" und \"node\".", + "loc.messages.UnableToFetchAuthorityURL": "Abrufen der Autoritäts-URL nicht möglich.", + "loc.messages.UnableToFetchActiveDirectory": "Abrufen der Active Directory-Ressourcen-ID nicht möglich.", + "loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand": "Runtimestapel und Startbefehl erfolgreich aktualisiert.", + "loc.messages.FailedToUpdateRuntimeStackAndStartupCommand": "Fehler beim Aktualisieren des Runtimestapels und des Startbefehls. Fehler: %s.", + "loc.messages.SuccessfullyUpdatedWebAppSettings": "App-Einstellungen erfolgreich aktualisiert.", + "loc.messages.FailedToUpdateAppSettingsInConfigDetails": "Fehler beim Aktualisieren der App-Einstellungen. Fehler: %s.", + "loc.messages.UnableToGetAzureRMWebAppMetadata": "Fehler beim Abrufen von AzureRM-WebApp-Metadaten. ErrorCode: %s", + "loc.messages.UnableToUpdateAzureRMWebAppMetadata": "AzureRM-WebApp-Metadaten können nicht aktualisiert werden. Fehlercode: %s", + "loc.messages.Unabletoretrieveazureregistrycredentials": "Fehler beim Abrufen von Azure Container Registry-Anmeldeinformationen. [Statuscode: \"%s\"]", + "loc.messages.UnableToReadResponseBody": "Antworttext konnte nicht gelesen werden. Fehler: %s", + "loc.messages.UnableToUpdateWebAppConfigDetails": "WebApp-Konfigurationsdetails konnten nicht aktualisiert werden. StatusCode: \"%s\"", + "loc.messages.AddingReleaseAnnotation": "Releaseanmerkung für Application Insights-Ressource \"%s\" wird hinzugefügt.", + "loc.messages.SuccessfullyAddedReleaseAnnotation": "Releaseanmerkung erfolgreich zu Application Insight hinzugefügt: %s", + "loc.messages.FailedAddingReleaseAnnotation": "Fehler beim Hinzufügen einer Releaseanmerkung. %s", + "loc.messages.RenameLockedFilesEnabled": "Umbenennung gesperrter Dateien für App Service aktiviert.", + "loc.messages.FailedToEnableRenameLockedFiles": "Fehler beim Aktivieren der Umbenennung gesperrter Dateien. Fehler: %s", + "loc.messages.WebJobsInProgressIssue": "Einige WebJobs im ausgeführten Zustand verhindern das Entfernen der Dateien durch die Bereitstellung. Sie können die Option \"Zusätzliche Dateien am Ziel entfernen\" deaktivieren oder fortlaufende WebJobs anhalten, bevor Sie die Bereitstellung durchführen.", + "loc.messages.FailedToFetchKuduAppSettings": "Fehler beim Abrufen von Kudu-App-Einstellungen. Fehler: %s", + "loc.messages.FailedToCreatePath": "Fehler beim Erstellen des Pfads \"%s\" aus Kudu. Fehler: %s", + "loc.messages.FailedToDeleteFile": "Fehler beim Löschen der Datei \"%s/%s\" aus Kudu. Fehler: %s", + "loc.messages.FailedToUploadFile": "Fehler beim Hochladen der Datei \"%s/%s\" aus Kudu. Fehler: %s", + "loc.messages.FailedToGetFileContent": "Fehler beim Abrufen des Dateiinhalts \"%s/%s\" aus Kudu. Fehler: %s", + "loc.messages.FailedToListPath": "Fehler beim Auflisten von Pfad \"%s\" aus Kudu. Fehler: %s", + "loc.messages.RetryToDeploy": "Es wird erneut versucht, das Paket bereitzustellen.", + "loc.messages.FailedToGetAppServiceDetails": "Fehler beim Abrufen der App Service-Details \"%s\". Fehler: %s", + "loc.messages.FailedToGetAppServicePublishingProfile": "Fehler beim Abrufen des Veröffentlichungsprofils für App Service \"%s\". Fehler: %s", + "loc.messages.FailedToUpdateAppServiceMetadata": "Fehler beim Aktualisieren der Metadaten für App Service \"%s\". Fehler: %s", + "loc.messages.FailedToGetAppServiceMetadata": "Fehler beim Abrufen der Metadaten für App Service \"%s\". Fehler: %s", + "loc.messages.FailedToPatchAppServiceConfiguration": "Fehler beim Patchen der Konfiguration für App Service \"%s\". Fehler: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Fehler beim Aktualisieren der App-Dienstkonfiguration \"%s\". Fehler: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Fehler beim Abrufen der Konfiguration für App Service \"%s\". Fehler: %s", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Fehler beim Abrufen der Anmeldeinformationen für die Veröffentlichung für App Service \"%s\". Fehler: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Fehler beim Abrufen der Anwendungseinstellungen für App Service \"%s\". Fehler: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Fehler beim Aktualisieren der Anwendungseinstellungen für App Service \"%s\". Fehler: %s", + "loc.messages.UpdatingAppServiceConfigurationSettings": "Die App Service-Konfigurationseinstellungen werden aktualisiert. Daten: %s", + "loc.messages.UpdatedAppServiceConfigurationSettings": "Die App Service-Konfigurationseinstellungen wurden aktualisiert.", + "loc.messages.UpdatingAppServiceApplicationSettings": "Die App Service-Anwendungseinstellungen werden aktualisiert. Daten: %s", + "loc.messages.UpdatedAppServiceApplicationSettings": "Die App Service-Anwendungseinstellungen und die Kudu-Anwendungseinstellungen wurden aktualisiert.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Mehrere Ressourcengruppen für App Service \"%s\" gefunden.", + "loc.messages.PackageDeploymentUsingZipDeployFailed": "Fehler bei der Paketbereitstellung über ZIP Deploy. Weitere Informationen finden Sie in den Protokollen.", + "loc.messages.PackageDeploymentInitiated": "Die Paketbereitstellung über ZIP Deploy wurde eingeleitet.", + "loc.messages.FailedToGetDeploymentLogs": "Fehler beim Abrufen von Bereitstellungsprotokollen. Fehler: %s", + "loc.messages.GoExeNameNotPresent": "Die Go Exe-Name ist nicht vorhanden", + "loc.messages.WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier." +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/en-US/resources.resjson b/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/en-US/resources.resjson new file mode 100644 index 000000000000..769b174d0a0d --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/en-US/resources.resjson @@ -0,0 +1,224 @@ +{ + "loc.friendlyName": "Azure App Service Deploy", + "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:
  Supports File Transformations (XDT)
  Supports Variable Substitutions(XML, JSON)
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.
Note: Select Linux Web App for built-in platform images or custom container image deployments.", + "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.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.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
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.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/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.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx: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.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "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.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx: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.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerNamespace": "Registry or Namespace", + "loc.input.help.DockerNamespace": "A globally unique top-level domain name for your specific registry or namespace.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerRepository": "Image", + "loc.input.help.DockerRepository": "Name of the repository where the container images are stored.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerImageTag": "Tag", + "loc.input.help.DockerImageTag": "Tags are optional, it is the mechanism that registries use to give Docker images a version.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.VirtualApplication": "Virtual application", + "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.
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.
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.
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.
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.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.
Example : -Port 5000 -RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Eastern Standard Time\"", + "loc.input.label.ConfigurationSettings": "Configuration settings", + "loc.input.help.ConfigurationSettings": "Edit web app configuration settings following the syntax -key value. Value containing spaces should be enclosed in double quotes.
Example : -phpVersion 5.6 -linuxFxVersion: node|6.11", + "loc.input.label.TakeAppOfflineFlag": "Take App Offline", + "loc.input.help.TakeAppOfflineFlag": "Select the option to take the Azure App Service offline by placing an app_offline.htm file in the root directory of the App Service before the sync operation begins. The file will be removed after the sync operation completes successfully.", + "loc.input.label.UseWebDeploy": "Publish using Web Deploy", + "loc.input.help.UseWebDeploy": "Publish using Web Deploy options are supported only when using Windows agent. On other platforms, the task relies on [Kudu REST APIs](https://github.com/projectkudu/kudu/wiki/REST-API) to deploy the Azure App Service, and following options are not supported", + "loc.input.label.SetParametersFile": "SetParameters file", + "loc.input.help.SetParametersFile": "Optional: location of the SetParameters.xml file to use.", + "loc.input.label.RemoveAdditionalFilesFlag": "Remove additional files at destination", + "loc.input.help.RemoveAdditionalFilesFlag": "Select the option to delete files on the Azure App Service that have no matching files in the App Service package or folder.

Note: This will also remove all files related to any extension installed on this Azure App Service. To prevent this, select 'Exclude files from App_Data folder' checkbox. ", + "loc.input.label.ExcludeFilesFromAppDataFlag": "Exclude files from the App_Data folder", + "loc.input.help.ExcludeFilesFromAppDataFlag": "Select the option to prevent files in the App_Data folder from being deployed to the Azure App Service.", + "loc.input.label.AdditionalArguments": "Additional arguments", + "loc.input.help.AdditionalArguments": "Additional Web Deploy arguments following the syntax -key:value .
These will be applied when deploying the Azure App Service. Example: -disableLink:AppPoolExtension -disableLink:ContentExtension.
For more examples of Web Deploy operation settings, refer to [this](https://go.microsoft.com/fwlink/?linkid=838471).", + "loc.input.label.RenameFilesFlag": "Rename locked files", + "loc.input.help.RenameFilesFlag": "Select the option to enable msdeploy flag MSDEPLOY_RENAME_LOCKED_FILES=1 in Azure App Service application settings. The option if set enables msdeploy to rename locked files that are locked during app deployment", + "loc.input.label.XmlTransformation": "XML transformation", + "loc.input.help.XmlTransformation": "The config transforms will be run for `*.Release.config` and `*..config` on the `*.config file`.
Config transforms will be run prior to the Variable Substitution.
XML transformations are supported only for Windows platform.", + "loc.input.label.XmlVariableSubstitution": "XML variable substitution", + "loc.input.help.XmlVariableSubstitution": "Variables defined in the Build or Release Definition will be matched against the 'key' or 'name' entries in the appSettings, applicationSettings, and connectionStrings sections of any config file and parameters.xml. Variable Substitution is run after config transforms.

Note: If same variables are defined in the Release Definition and in the Environment, then the Environment variables will supersede the Release Definition variables.
", + "loc.input.label.JSONFiles": "JSON variable substitution", + "loc.input.help.JSONFiles": "Provide new line separated list of JSON files to substitute the variable values. Files names are to be provided relative to the root folder.
To substitute JSON variables that are nested or hierarchical, specify them using JSONPath expressions.

For example, to replace the value of ‘ConnectionString’ in the sample below, you need to define a variable as ‘Data.DefaultConnection.ConnectionString’ in the build/release definition (or release definition’s environment).
{
  \"Data\": {
    \"DefaultConnection\": {
      \"ConnectionString\": \"Server=(localdb)\\SQLEXPRESS;Database=MyDB;Trusted_Connection=True\"
    }
  }
}
Variable Substitution is run after configuration transforms.

Note: Build/Release’s system definition variables are excluded in substitution", + "loc.messages.Invalidwebapppackageorfolderpathprovided": "Invalid App Service package or folder path provided: %s", + "loc.messages.SetParamFilenotfound0": "Set parameters file not found: %s", + "loc.messages.XDTTransformationsappliedsuccessfully": "XML Transformations applied successfully", + "loc.messages.GotconnectiondetailsforazureRMWebApp0": "Got connection details for Azure App Service:'%s'", + "loc.messages.ErrorNoSuchDeployingMethodExists": "Error : No such deploying method exists", + "loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp": "Unable to retrieve connection details for Azure App Service : %s. Status Code: %s (%s)", + "loc.messages.UnabletoretrieveResourceID": "Unable to retrieve connection details for Azure Resource:'%s'. Status Code: %s", + "loc.messages.CouldnotfetchaccesstokenforAzureStatusCode": "Could not fetch access token for Azure. Status Code: %s (%s)", + "loc.messages.Successfullyupdateddeploymenthistory": "Successfully updated deployment History at %s", + "loc.messages.Failedtoupdatedeploymenthistory": "Failed to update deployment history. Error: %s", + "loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "WARNING : Cannot update deployment status : SCM endpoint is not enabled for this website", + "loc.messages.Unabletoretrievewebconfigdetails": "Unable to retrieve App Service configuration details. Status Code: '%s'", + "loc.messages.Unabletoretrievewebappsettings": "Unable to retrieve App Service application settings. [Status Code: '%s', Error Message: '%s']", + "loc.messages.Unabletoupdatewebappsettings": "Unable to update App service application settings. Status Code: '%s'", + "loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "Cannot update deployment status : Unique Deployment ID cannot be retrieved", + "loc.messages.PackageDeploymentSuccess": "Successfully deployed web package to App Service.", + "loc.messages.PackageDeploymentFailed": "Failed to deploy web package to App Service.", + "loc.messages.Runningcommand": "Running command: %s", + "loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath": "Deploying web package : %s at virtual path (physical path) : %s (%s)", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Successfully deployed package %s using kudu service at %s", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Failed to deploy App Service package using kudu service : %s", + "loc.messages.Unabletodeploywebappresponsecode": "Unable to deploy App Service due to error code : %s", + "loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "MSDeploy generated packages are only supported for Windows platform.", + "loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "Unsupported installed version: %s found for MSDeploy. version should be at least 3 or above", + "loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError": "Unable to find the location of MS Deploy from registry on machine (Error : %s)", + "loc.messages.Nopackagefoundwithspecifiedpattern": "No package found with specified pattern: %s", + "loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "More than one package matched with specified pattern: %s. Please restrain the search pattern.", + "loc.messages.Trytodeploywebappagainwithappofflineoptionselected": "Try to deploy app service again with Take application offline option selected.", + "loc.messages.Trytodeploywebappagainwithrenamefileoptionselected": "Try to deploy app service again with Rename locked files option selected.", + "loc.messages.NOJSONfilematchedwithspecificpattern": "NO JSON file matched with specific pattern: %s.", + "loc.messages.Configfiledoesntexists": "Configuration file %s doesn't exist.", + "loc.messages.Failedtowritetoconfigfilewitherror": "Failed to write to config file %s with error : %s", + "loc.messages.AppOfflineModeenabled": "App offline mode enabled.", + "loc.messages.Failedtoenableappofflinemode": "Failed to enable app offline mode. Status Code: %s (%s)", + "loc.messages.AppOflineModedisabled": "App offline mode disabled.", + "loc.messages.FailedtodisableAppOfflineMode": "Failed to disable App offline mode. Status Code: %s (%s)", + "loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform": "Cannot perform XML transformations on a non-Windows platform.", + "loc.messages.XdtTransformationErrorWhileTransforming": "XML transformation error while transforming %s using %s.", + "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Publish using webdeploy options are supported only when using Windows agent", + "loc.messages.ResourceDoesntExist": "Resource '%s' doesn't exist. Resource should exist before deployment.", + "loc.messages.EncodeNotSupported": "Detected file encoding of the file %s as %s. Variable substitution is not supported with file encoding %s. Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.UnknownFileEncodeError": "Unable to detect encoding of the file %s (typeCode: %s). Supported encodings are UTF-8 and UTF-16 LE.", + "loc.messages.ShortFileBufferError": "File buffer is too short to detect encoding type : %s", + "loc.messages.FailedToUpdateAzureRMWebAppConfigDetails": "Failed to update App Service configuration details. Error: %s", + "loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails": "Successfully updated App Service configuration details", + "loc.messages.RequestedURLforkuduphysicalpath": "Requested URL for kudu physical path : %s", + "loc.messages.Physicalpathalreadyexists": "Physical path '%s' already exists", + "loc.messages.KuduPhysicalpathCreatedSuccessfully": "Kudu physical path created successfully : %s", + "loc.messages.FailedtocreateKuduPhysicalPath": "Failed to create kudu physical path. Error : %s", + "loc.messages.FailedtocheckphysicalPath": "Failed to check kudu physical path. Error Code: %s", + "loc.messages.VirtualApplicationDoesNotExist": "Virtual application doesn't exists : %s", + "loc.messages.JSONParseError": "Unable to parse JSON file: %s. Error: %s", + "loc.messages.JSONvariablesubstitutionappliedsuccessfully": "JSON variable substitution applied successfully.", + "loc.messages.XMLvariablesubstitutionappliedsuccessfully": "XML variable substitution applied successfully.", + "loc.messages.failedtoUploadFileToKudu": "Unable to upload file: %s to Kudu (%s). Status Code: %s", + "loc.messages.failedtoUploadFileToKuduError": "Unable to upload file: %s to Kudu (%s). Error: %s", + "loc.messages.ExecuteScriptOnKudu": "Executing given script on Kudu service.", + "loc.messages.FailedToRunScriptOnKuduError": "Unable to run the script on Kudu Service. Error: %s", + "loc.messages.FailedToRunScriptOnKudu": "Unable to run the script on Kudu: %s. Status Code: %s", + "loc.messages.ScriptExecutionOnKuduSuccess": "Successfully executed script on Kudu.", + "loc.messages.ScriptExecutionOnKuduFailed": "Executed script returned '%s' as return code. Error: %s", + "loc.messages.FailedtoDeleteFileFromKudu": "Unable to delete file: %s from Kudu (%s). Status Code: %s", + "loc.messages.FailedtoDeleteFileFromKuduError": "Unable to delete file: %s from Kudu (%s). Error: %s", + "loc.messages.ScriptFileNotFound": "Script file '%s' not found.", + "loc.messages.InvalidScriptFile": "Invalid script file '%s' provided. Valid extensions are .bat and .cmd for windows and .sh for linux", + "loc.messages.RetryForTimeoutIssue": "Script execution failed with timeout issue. Retrying once again.", + "loc.messages.stdoutFromScript": "Standard output from script: ", + "loc.messages.stderrFromScript": "Standard error from script: ", + "loc.messages.WebConfigAlreadyExists": "web.config file already exists. Not generating.", + "loc.messages.SuccessfullyGeneratedWebConfig": "Successfully generated web.config file", + "loc.messages.FailedToGenerateWebConfig": "Failed to generate web.config. %s", + "loc.messages.FailedToGetKuduFileContent": "Unable to get file content: %s . Status code: %s (%s)", + "loc.messages.FailedToGetKuduFileContentError": "Unable to get file content: %s. Error: %s", + "loc.messages.ScriptStatusTimeout": "Unable to fetch script status due to timeout.", + "loc.messages.PollingForFileTimeOut": "Unable to fetch script status due to timeout. You can increase the timeout limit by setting 'appservicedeploy.retrytimeout' variable to number of minutes required.", + "loc.messages.InvalidPollOption": "Invalid polling option provided: %s.", + "loc.messages.MissingAppTypeWebConfigParameters": "Attribute '-appType' is missing in the Web.config parameters. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask', 'node' and 'Go'.
For example, '-appType python_Bottle' (sans-quotes) in case of Python Bottle framework..", + "loc.messages.AutoDetectDjangoSettingsFailed": "Unable to detect DJANGO_SETTINGS_MODULE 'settings.py' file path. Ensure that the 'settings.py' file exists or provide the correct path in Web.config parameter input in the following format '-DJANGO_SETTINGS_MODULE .settings'", + "loc.messages.FailedToApplyTransformation": "Unable to apply transformation for the given package. Verify the following.", + "loc.messages.FailedToApplyTransformationReason1": "1. Whether the Transformation is already applied for the MSBuild generated package during build. If yes, remove the tag for each config in the csproj file and rebuild. ", + "loc.messages.FailedToApplyTransformationReason2": "2. Ensure that the config file and transformation files are present in the same folder inside the package.", + "loc.messages.AutoParameterizationMessage": "ConnectionString attributes in Web.config is parameterized by default. Note that the transformation has no effect on connectionString attributes as the value is overridden during deployment by 'Parameters.xml or 'SetParameters.xml' files. You can disable the auto-parameterization by setting /p:AutoParameterizationWebConfigConnectionStrings=False during MSBuild package generation.", + "loc.messages.UnsupportedAppType": "App type '%s' not supported in Web.config generation. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask' and 'node'", + "loc.messages.UnableToFetchAuthorityURL": "Unable to fetch authority url.", + "loc.messages.UnableToFetchActiveDirectory": "Unable to fetch active directory resource id.", + "loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand": "Successfully updated the Runtime Stack and Startup Command.", + "loc.messages.FailedToUpdateRuntimeStackAndStartupCommand": "Failed to update the Runtime Stack and Startup Command. Error: %s.", + "loc.messages.SuccessfullyUpdatedWebAppSettings": "Successfully updated the App settings.", + "loc.messages.FailedToUpdateAppSettingsInConfigDetails": "Failed to update the App settings. Error: %s.", + "loc.messages.UnableToGetAzureRMWebAppMetadata": "Failed to fetch AzureRM WebApp metadata. ErrorCode: %s", + "loc.messages.UnableToUpdateAzureRMWebAppMetadata": "Unable to update AzureRM WebApp metadata. Error Code: %s", + "loc.messages.Unabletoretrieveazureregistrycredentials": "Unable to retrieve Azure Container Registry credentails.[Status Code: '%s']", + "loc.messages.UnableToReadResponseBody": "Unable to read response body. Error: %s", + "loc.messages.UnableToUpdateWebAppConfigDetails": "Unable to update WebApp config details. StatusCode: '%s'", + "loc.messages.AddingReleaseAnnotation": "Adding release annotation for the Application Insights resource '%s'", + "loc.messages.SuccessfullyAddedReleaseAnnotation": "Successfully added release annotation to the Application Insight : %s", + "loc.messages.FailedAddingReleaseAnnotation": "Failed to add release annotation. %s", + "loc.messages.RenameLockedFilesEnabled": "Rename locked files enabled for App Service.", + "loc.messages.FailedToEnableRenameLockedFiles": "Failed to enable rename locked files. Error: %s", + "loc.messages.WebJobsInProgressIssue": "Few WebJobs in running state prevents the deployment from removing the files. You can disable 'Remove additional files at destinaton' option or Stop continuous Jobs before deployment.", + "loc.messages.FailedToFetchKuduAppSettings": "Failed to fetch Kudu App Settings. Error: %s", + "loc.messages.FailedToCreatePath": "Failed to create path '%s' from Kudu. Error: %s", + "loc.messages.FailedToDeleteFile": "Failed to delete file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "Failed to upload file '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToGetFileContent": "Failed to get file content '%s/%s' from Kudu. Error: %s", + "loc.messages.FailedToListPath": "Failed to list path '%s' from Kudu. Error: %s", + "loc.messages.RetryToDeploy": "Retrying to deploy the package.", + "loc.messages.FailedToGetAppServiceDetails": "Failed to fetch App Service '%s' details. Error: %s", + "loc.messages.FailedToGetAppServicePublishingProfile": "Failed to fetch App Service '%s' publishing profile. Error: %s", + "loc.messages.FailedToUpdateAppServiceMetadata": "Failed to update App service '%s' Meta data. Error: %s", + "loc.messages.FailedToGetAppServiceMetadata": "Failed to get App service '%s' Meta data. Error: %s", + "loc.messages.FailedToPatchAppServiceConfiguration": "Failed to patch App Service '%s' configuration. Error: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Failed to update App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Failed to get App service '%s' configuration. Error: %s", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Failed to fetch App Service '%s' publishing credentials. Error: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Failed to get App service '%s' application settings. Error: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Failed to update App service '%s' application settings. Error: %s", + "loc.messages.UpdatingAppServiceConfigurationSettings": "Updating App Service Configuration settings. Data: %s", + "loc.messages.UpdatedAppServiceConfigurationSettings": "Updated App Service Configuration settings.", + "loc.messages.UpdatingAppServiceApplicationSettings": "Updating App Service Application settings. Data: %s", + "loc.messages.UpdatedAppServiceApplicationSettings": "Updated App Service Application settings and Kudu Application settings.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Multiple resource group found for App Service '%s'.", + "loc.messages.PackageDeploymentUsingZipDeployFailed": "Package deployment using ZIP Deploy failed. Refer logs for more details.", + "loc.messages.PackageDeploymentInitiated": "Package deployment using ZIP Deploy initiated.", + "loc.messages.FailedToGetDeploymentLogs": "Failed to get deployment logs. Error: %s", + "loc.messages.GoExeNameNotPresent": "Go exe name is not present", + "loc.messages.WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier.", + "loc.messages.Updatemachinetoenablesecuretlsprotocol": "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "loc.messages.FailedToGetResourceID": "Failed to get resource ID for resource type '%s' and resource name '%s'. Error: %s", + "loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "loc.messages.ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release pipeline", + "loc.messages.ASE_WebDeploySSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to pass -allowUntrusted in additional arguments of web deploy option." +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/es-es/resources.resjson b/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/es-es/resources.resjson new file mode 100644 index 000000000000..8fe4f18e9c2d --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/es-es/resources.resjson @@ -0,0 +1,219 @@ +{ + "loc.friendlyName": "Implementación de Azure App Service", + "loc.helpMarkDown": "[Más información](https://aka.ms/azurermwebdeployreadme)", + "loc.description": "Actualice Azure WebApp Services en Windows, Web App en Linux con imágenes integradas o contenedores de Docker, ASP.NET, .NET Core, PHP, Python o aplicaciones web basadas en nodos, Function App, Mobile Apps, aplicaciones API, WebJobs mediante las API de REST de Web Deploy/Kudu", + "loc.instanceNameFormat": "Implementación de Azure App Service: $(WebAppName)", + "loc.releaseNotes": "Novedades de la versión 3.0:
  Admite las transformaciones de archivos (XDT)
  Admite la sustitución de variables (XML, JSON)
Haga clic [aquí](https://aka.ms/azurermwebdeployreadme) para más información.", + "loc.group.displayName.FileTransformsAndVariableSubstitution": "Transformaciones de archivos y opciones de sustitución de variables", + "loc.group.displayName.AdditionalDeploymentOptions": "Opciones de implementación adicionales", + "loc.group.displayName.PostDeploymentAction": "Acción posterior a la implementación", + "loc.group.displayName.ApplicationAndConfigurationSettings": "Configuración y opciones de la aplicación", + "loc.group.displayName.output": "Salida", + "loc.input.label.ConnectedServiceName": "Suscripción a Azure", + "loc.input.help.ConnectedServiceName": "Seleccione la suscripción de Azure Resource Manager para la implementación.", + "loc.input.label.WebAppKind": "Tipo de aplicación", + "loc.input.help.WebAppKind": "Seleccione el tipo de aplicación web para implementar.
Nota: Seleccione Linux Web App para las imágenes de la plataforma integrada o implementaciones de imagen del contenedor personalizado.", + "loc.input.label.WebAppName": "Nombre de App Service", + "loc.input.help.WebAppName": "Escriba o seleccione el nombre de una instancia existente de Azure App Service. Solo se enumerarán las instancias de App Service basadas en el tipo de aplicación seleccionado.", + "loc.input.label.DeployToSlotFlag": "Implementar en ranura", + "loc.input.help.DeployToSlotFlag": "Seleccione esta opción para implementar la aplicación en un espacio que no sea el de producción. Si no selecciona esta opción, Azure App Service se implementará en el espacio de producción.", + "loc.input.label.ResourceGroupName": "Grupo de recursos", + "loc.input.help.ResourceGroupName": "Escriba o seleccione el grupo de recursos de Azure que contiene la instancia de Azure App Service especificada anteriormente.", + "loc.input.label.SlotName": "Espacio", + "loc.input.help.SlotName": "Escriba o seleccione un espacio que no sea el de producción.", + "loc.input.label.ImageSource": "Origen de imagen", + "loc.input.help.ImageSource": "App Service en Linux ofrece dos opciones distintas para publicar su aplicación:
Implementación de una imagen personalizada o Implementación de aplicaciones con una imagen de plataforma integrada. [Más información](https://go.microsoft.com/fwlink/?linkid=862490)", + "loc.input.label.AzureContainerRegistry": "Registry", + "loc.input.help.AzureContainerRegistry": "Nombre de dominio de nivel superior único global para su Registro específico.
Nota: Un nombre de imagen completo tiene el formato: \"/:\". Por ejemplo, \"miRegistro.azurecr.io/nginx:última\".", + "loc.input.label.AzureContainerRegistryLoginServer": "Nombre del servidor de inicio de sesión de Registry", + "loc.input.help.AzureContainerRegistryLoginServer": "Escriba o seleccione un nombre del servidor de inicio de sesión de Azure Container Registry.", + "loc.input.label.AzureContainerRegistryImage": "Imagen", + "loc.input.help.AzureContainerRegistryImage": "Nombre del repositorio en el que se almacenan las imágenes del contenedor.
Nota: Un nombre de imagen completo tiene el formato: \"/:\". Por ejemplo, \"miRegistro.azurecr.io/nginx:última\".", + "loc.input.label.AzureContainerRegistryTag": "Etiqueta", + "loc.input.help.AzureContainerRegistryTag": "Las etiquetas son opcionales. Este es el mecanismo que los registros usan para asignar una versión a las imágenes de Docker.
Nota: Un nombre de imagen completo tiene el formato: \"/:\". Por ejemplo, \"miRegistro.azurecr.io/nginx:última\".", + "loc.input.label.DockerRepositoryAccess": "Acceso al repositorio", + "loc.input.help.DockerRepositoryAccess": "Seleccione el acceso al repositorio de Docker.", + "loc.input.label.RegistryConnectedServiceName": "Conexión de Registro", + "loc.input.help.RegistryConnectedServiceName": "Seleccione la conexión del Registro.", + "loc.input.label.PrivateRegistryImage": "Imagen", + "loc.input.help.PrivateRegistryImage": "Nombre del repositorio en el que se almacenan las imágenes del contenedor.
Nota: Un nombre de imagen completo tiene el formato: \"/:\". Por ejemplo, \"miRegistro.azurecr.io/nginx:última\".", + "loc.input.label.PrivateRegistryTag": "Etiqueta", + "loc.input.help.PrivateRegistryTag": "Las etiquetas son opcionales. Este es el mecanismo que los registros usan para asignar una versión a las imágenes de Docker.
Nota: Un nombre de imagen completo tiene el formato: \"/:\". Por ejemplo, \"miRegistro.azurecr.io/nginx:última\".", + "loc.input.label.DockerNamespace": "Registro o espacio de nombres", + "loc.input.help.DockerNamespace": "Nombre de dominio de nivel superior único global para su espacio de nombres o Registro específico.
Nota: El nombre de imagen completo tiene el formato: \"/:\". Por ejemplo, \"miRegistro.azurecr.io/nginx:última\".", + "loc.input.label.DockerRepository": "Imagen", + "loc.input.help.DockerRepository": "Nombre del repositorio en el que se almacenan las imágenes del contenedor.
Nota: Un nombre de imagen completo tiene el formato: \"/:\". Por ejemplo, \"miRegistro.azurecr.io/nginx:última\".", + "loc.input.label.DockerImageTag": "Etiqueta", + "loc.input.help.DockerImageTag": "Las etiquetas son opcionales. Este es el mecanismo que los registros usan para asignar una versión a las imágenes de Docker.
Nota: El nombre de imagen completo tiene el formato: \"/:\". Por ejemplo, \"miRegistro.azurecr.io/nginx:última\".", + "loc.input.label.VirtualApplication": "Aplicación virtual", + "loc.input.help.VirtualApplication": "Especifique el nombre de la aplicación virtual que se ha configurado en Azure Portal. Esta opción no es necesaria para implementaciones en la raíz de App Service.", + "loc.input.label.Package": "Paquete o carpeta", + "loc.input.help.Package": "Ruta de acceso del archivo al paquete o a una carpeta con contenido de App Service que genera MSBuild o un archivo war o ZIP comprimido.
Se admiten variables ([Compilación](https://www.visualstudio.com/docs/build/define/variables) | [Versión](https://www.visualstudio.com/docs/release/author-release-definition/understanding-tasks#predefvariables)) y caracteres comodín.
Por ejemplo, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip o $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.BuiltinLinuxPackage": "Paquete o carpeta", + "loc.input.help.BuiltinLinuxPackage": "Ruta de acceso del archivo al paquete o a una carpeta con contenido de App Service que genera MSBuild o un archivo war o ZIP comprimido.
Se admiten variables ([Compilación](https://www.visualstudio.com/docs/build/define/variables) | [Versión](https://www.visualstudio.com/docs/release/author-release-definition/understanding-tasks#predefvariables)) y caracteres comodín.
Por ejemplo, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip o $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.RuntimeStack": "Pila en tiempo de ejecución", + "loc.input.help.RuntimeStack": "Seleccione el marco y la versión.", + "loc.input.label.StartupCommand": "Comando de inicio ", + "loc.input.help.StartupCommand": "Escriba el comando de inicio.", + "loc.input.label.WebAppUri": "Dirección URL de App Service", + "loc.input.help.WebAppUri": "Especifique un nombre para la variable de salida que se genera para la dirección URL de Azure App Service. La variable se puede consumir en sucesivas tareas.", + "loc.input.label.ScriptType": "Tipo de script de implementación", + "loc.input.help.ScriptType": "Para personalizar la implementación, proporcione un script que se ejecute en Azure App Service una vez que la tarea haya completado la implementación correctamente. Por ejemplo, restaure paquetes para aplicaciones de Node, PHP y Python. [Más información](https://go.microsoft.com/fwlink/?linkid=843471).", + "loc.input.label.InlineScript": "Script en línea", + "loc.input.label.ScriptPath": "Ruta de acceso del script de implementación", + "loc.input.label.GenerateWebConfig": "Generar archivo web.config", + "loc.input.help.GenerateWebConfig": "Se generará un archivo web.config estándar y se implementará en Azure App Service si la aplicación no tiene uno. Los valores de web.config se pueden editar y pueden variar en función del marco de trabajo de la aplicación. Por ejemplo, para la aplicación node.js, web.config tendrá los valores de archivo de inicio y del módulo iis_node. [Más información](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.WebConfigParameters": "Parámetros del archivo web.config", + "loc.input.help.WebConfigParameters": "Edite valores como el archivo de inicio en el archivo web.config generado. Esta característica de edición es solo para el archivo web.config generado. [Más información](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.AppSettings": "Configuración de la aplicación", + "loc.input.help.AppSettings": "Editar configuración de la aplicación de aplicación web la sintaxis-valor de clave. Valor que contenga espacios debe incluirse entre comillas dobles.
Ejemplo :-puerto 5000 - RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Hora estándar\"", + "loc.input.label.ConfigurationSettings": "Opciones de configuración", + "loc.input.help.ConfigurationSettings": "Editar opciones de configuración de aplicación web la sintaxis-valor de clave. Valor que contenga espacios debe incluirse entre comillas dobles.
Ejemplo: - phpVersion 5.6 - linuxFxVersion: nodo|6.11", + "loc.input.label.TakeAppOfflineFlag": "Desconectar la aplicación", + "loc.input.help.TakeAppOfflineFlag": "Seleccione esta opción para poner sin conexión Azure App Service colocando el archivo app_offline.htm en el directorio raíz de App Service antes de que comience la operación de sincronización. El archivo se quitará cuando la operación de sincronización finalice correctamente.", + "loc.input.label.UseWebDeploy": "Publicar usando Web Deploy", + "loc.input.help.UseWebDeploy": "Las opciones de publicación mediante Web Deploy solo se admiten cuando se usa el agente de Windows. En otras plataformas, la tarea depende de [API de REST de Kudu](https://github.com/projectkudu/kudu/wiki/REST-API) para implementar Azure App Service y no se admiten las siguientes opciones", + "loc.input.label.SetParametersFile": "Archivo SetParameters", + "loc.input.help.SetParametersFile": "Opcional: ubicación del archivo SetParameters.xml que debe usarse.", + "loc.input.label.RemoveAdditionalFilesFlag": "Quitar archivos adicionales en el destino", + "loc.input.help.RemoveAdditionalFilesFlag": "Seleccione la opción para eliminar archivos en la instancia de Azure App Service que no tiene archivos coincidentes en la carpeta o el paquete de App Service.

Nota: Al hacerlo, también se quitarán todos los archivos relacionados con cualquier extensión instalada en esta instancia de Azure App Service. Para evitarlo, seleccione la casilla \"Excluir archivos de la carpeta App_Data\". ", + "loc.input.label.ExcludeFilesFromAppDataFlag": "Excluir archivos de la carpeta App_Data", + "loc.input.help.ExcludeFilesFromAppDataFlag": "Seleccione esta opción para evitar que los archivos de la carpeta App_Data se implementen en Azure App Service.", + "loc.input.label.AdditionalArguments": "Argumentos adicionales", + "loc.input.help.AdditionalArguments": "Argumentos adicionales de Web Deploy que siguen la sintaxis -clave:valor.
Se aplicarán cuando se implemente la instancia de Azure App Service. Ejemplo: -disableLink:AppPoolExtension -disableLink:ContentExtension.
Para más ejemplos de configuración de la operación de Web Deploy, consulte [aquí] (https://go.microsoft.com/fwlink/?linkid=838471).", + "loc.input.label.RenameFilesFlag": "Cambiar nombre de archivos bloqueados", + "loc.input.help.RenameFilesFlag": "Seleccione la opción para habilitar la marca de msdeploy MSDEPLOY_RENAME_LOCKED_FILES=1 en la configuración de la aplicación de Azure App Service. Si está establecida, la opción permite que msdeploy cambie el nombre de los archivos bloqueados que se bloquean durante la implementación de la aplicación", + "loc.input.label.XmlTransformation": "Transformación XML", + "loc.input.help.XmlTransformation": "Las transformaciones de configuración se ejecutarán para \"*.Release.config\" y \"*..config\" en el \"archivo *.config\".
Las transformaciones de configuración se ejecutarán antes de la sustitución de variables.
Las transformaciones XML solo se admiten para la plataforma Windows.", + "loc.input.label.XmlVariableSubstitution": "Sustitución de variables XML", + "loc.input.help.XmlVariableSubstitution": "Las variables que se definen en la definición de compilación o de versión se compararán con las entradas \"key\" o \"name\" de las secciones appSettings, applicationSettings y connectionStrings de cualquier archivo de configuración y parameters.xml. La sustitución de variable tiene lugar después de las transformaciones de configuración.

Nota: Si las mismas variables están definidas en la definición de versión y en el entorno, las variables de entorno sustituirán las variables de la definición de versión.
", + "loc.input.label.JSONFiles": "Sustitución de variables JSON", + "loc.input.help.JSONFiles": "Proporcione una nueva lista separada por líneas de los archivos JSON para sustituir los valores de variable. Los nombres de archivos que se proporcionen deben ser relativos a la carpeta raíz.
Para sustituir las variables JSON anidadas o jerárquicas, especifíquelas mediante expresiones JSONPath.

Por ejemplo, para reemplazar el valor de “ConnectionString” en el ejemplo siguiente, debe definir una variable como “Data.DefaultConnection.ConnectionString” en la definición de compilación o versión (o el entorno de la definición de versión).
{
  \"Data\": {
    \"DefaultConnection\": {
      \"ConnectionString\": \"Server=(localdb)\\SQLEXPRESS;Database=MyDB;Trusted_Connection=True\"
    }
  }
}
La sustitución de variables se ejecuta una vez que se transforma la configuración.

Nota: Las variables de definición del sistema de la compilación o versión se excluyen de la sustitución", + "loc.messages.Invalidwebapppackageorfolderpathprovided": "Paquete App Service o ruta de acceso de carpeta proporcionados no válidos: %s", + "loc.messages.SetParamFilenotfound0": "No se ha encontrado el archivo de parámetros establecido: %s", + "loc.messages.XDTTransformationsappliedsuccessfully": "Las transformaciones XML se aplicaron correctamente", + "loc.messages.GotconnectiondetailsforazureRMWebApp0": "Se obtuvieron detalles de conexión para Azure App Service: \"%s\"", + "loc.messages.ErrorNoSuchDeployingMethodExists": "Error : No existe tal método de implementación", + "loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp": "No se pueden recuperar los detalles de conexión para Azure App Service : %s. Código de estado: %s (%s)", + "loc.messages.UnabletoretrieveResourceID": "No se pueden recuperar los detalles de conexión para el recurso de Azure: \"%s\". Código de estado: %s", + "loc.messages.CouldnotfetchaccesstokenforAzureStatusCode": "No se pudo recuperar el token de acceso para Azure. Código de estado: %s (%s)", + "loc.messages.Successfullyupdateddeploymenthistory": "El historial de implementación se actualizó correctamente en %s", + "loc.messages.Failedtoupdatedeploymenthistory": "No se pudo actualizar el historial de implementación. Error: %s", + "loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "ADVERTENCIA : no se puede actualizar el estado de implementación, el punto de conexión de SCM no está habilitado para este sitio web", + "loc.messages.Unabletoretrievewebconfigdetails": "No se pueden recuperar los detalles de configuración de la instancia de App Service. Código de estado: \"%s\"", + "loc.messages.Unabletoretrievewebappsettings": "No se puede recuperar la configuración de aplicación de App Service. [Código de estado: \"%s\", Mensaje de error: \"%s\"]", + "loc.messages.Unabletoupdatewebappsettings": "No se puede actualizar la configuración de aplicación de la instancia de App Service. Código de estado: '%s'", + "loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "No se puede actualizar el estado de implementación : no se puede recuperar el id. de implementación único", + "loc.messages.PackageDeploymentSuccess": "El paquete web se implementó correctamente en App Service.", + "loc.messages.PackageDeploymentFailed": "No se pudo implementar el paquete web en App Service.", + "loc.messages.Runningcommand": "Ejecutando el comando: %s", + "loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath": "Implementando el paquete web : %s en una ruta de acceso virtual (ruta de acceso física): %s (%s)", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "El paquete %s se implementó correctamente mediante el servicio kudu en %s", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "No se pudo implementar el paquete App Service mediante el servicio Kudu : %s", + "loc.messages.Unabletodeploywebappresponsecode": "No se puede implementar App Service debido al código de error: %s", + "loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "Los paquetes generados por MSDeploy solo se admiten para la plataforma Windows.", + "loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "Versión instalada no admitida: se encontró %s para MSDeploy, pero la versión mínima admitida es 3 o posterior.", + "loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError": "No se puede encontrar la ubicación de MS Deploy del Registro en la máquina (Error : %s)", + "loc.messages.Nopackagefoundwithspecifiedpattern": "No se encontró ningún paquete con el patrón especificado: %s", + "loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "Más de un paquete coincidió con el patrón especificado: %s. Restrinja el patrón de búsqueda.", + "loc.messages.Trytodeploywebappagainwithappofflineoptionselected": "Intente volver a implementar el servicio de la aplicación con la opción Poner la aplicación sin conexión seleccionada.", + "loc.messages.Trytodeploywebappagainwithrenamefileoptionselected": "Intente volver a implementar el servicio de la aplicación con la opción Cambiar de nombre archivos bloqueados seleccionada.", + "loc.messages.NOJSONfilematchedwithspecificpattern": "Ningún archivo JSON coincidía con un patrón específico: %s.", + "loc.messages.Configfiledoesntexists": "El archivo de configuración %s no existe.", + "loc.messages.Failedtowritetoconfigfilewitherror": "No se pudo escribir en el archivo de configuración %s con el error: %s", + "loc.messages.AppOfflineModeenabled": "Modo de aplicación sin conexión habilitado.", + "loc.messages.Failedtoenableappofflinemode": "No se pudo habilitar el modo de aplicación sin conexión. Código de estado: %s (%s)", + "loc.messages.AppOflineModedisabled": "Modo de aplicación sin conexión deshabilitado.", + "loc.messages.FailedtodisableAppOfflineMode": "No se pudo deshabilitar el modo de aplicación sin conexión. Código de estado: %s (%s)", + "loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform": "No se pueden realizar las transformaciones XML en una plataforma que no es Windows.", + "loc.messages.XdtTransformationErrorWhileTransforming": "Error de transformación XML al transformar %s mediante %s.", + "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Las opciones de publicación mediante webdeploy solo se admiten cuando se usa el agente de Windows", + "loc.messages.ResourceDoesntExist": "El recurso \"%s\" no existe. Este debe existir antes de la implementación.", + "loc.messages.EncodeNotSupported": "Se detectó una codificación de archivos del archivo %s como %s. No se admite la sustitución de variables con la codificación de archivos %s. Las codificaciones admitidas son UTF-8 y UTF-16 LE.", + "loc.messages.UnknownFileEncodeError": "No se puede detectar la codificación del archivo %s (typeCode: %s). Las codificaciones admitidas son UTF-8 y UTF-16 LE.", + "loc.messages.ShortFileBufferError": "El búfer de archivos es demasiado breve para detectar el tipo de codificación : %s", + "loc.messages.FailedToUpdateAzureRMWebAppConfigDetails": "No se pudieron actualizar los detalles de configuración de App Service. Error: %s", + "loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails": "Los detalles de configuración de App Service se actualizaron correctamente", + "loc.messages.RequestedURLforkuduphysicalpath": "Dirección URL solicitada para la ruta de acceso física a Kudu: %s", + "loc.messages.Physicalpathalreadyexists": "La ruta de acceso física \"%s\" ya existe", + "loc.messages.KuduPhysicalpathCreatedSuccessfully": "La ruta de acceso física a Kudu se creó correctamente: %s", + "loc.messages.FailedtocreateKuduPhysicalPath": "No se pudo crear la ruta de acceso física de kudu. Error: %s", + "loc.messages.FailedtocheckphysicalPath": "No se pudo comprobar la ruta de acceso física de kudu. Código de error: %s", + "loc.messages.VirtualApplicationDoesNotExist": "La aplicación virtual no existe: %s", + "loc.messages.JSONParseError": "No se puede analizar el archivo JSON: %s. Error: %s", + "loc.messages.JSONvariablesubstitutionappliedsuccessfully": "La sustitución de variable JSON se aplicó correctamente.", + "loc.messages.XMLvariablesubstitutionappliedsuccessfully": "Sustitución de variables XML aplicada correctamente.", + "loc.messages.failedtoUploadFileToKudu": "No se puede cargar el archivo %s en Kudu (%s). Código de estado: %s", + "loc.messages.failedtoUploadFileToKuduError": "No se puede cargar el archivo %s en Kudu (%s). Error: %s", + "loc.messages.ExecuteScriptOnKudu": "Ejecutando el script dado en el servicio Kudu.", + "loc.messages.FailedToRunScriptOnKuduError": "No se puede ejecutar el script en el servicio Kudu. Error: %s", + "loc.messages.FailedToRunScriptOnKudu": "No se puede ejecutar el script en Kudu: %s. Código de estado: %s", + "loc.messages.ScriptExecutionOnKuduSuccess": "El script se ejecutó correctamente en Kudu.", + "loc.messages.ScriptExecutionOnKuduFailed": "El script ejecutado devolvió \"%s\" como código de retorno. Error: %s", + "loc.messages.FailedtoDeleteFileFromKudu": "No se puede eliminar el archivo %s de Kudu (%s). Código de estado: %s", + "loc.messages.FailedtoDeleteFileFromKuduError": "No se puede eliminar el archivo %s de Kudu (%s). Error: %s", + "loc.messages.ScriptFileNotFound": "No se encuentra el archivo de script \"%s\".", + "loc.messages.InvalidScriptFile": "Se proporcionó un archivo de script \"%s\" no válido. Las extensiones válidas son .bat y .cmd para Windows y .sh para Linux.", + "loc.messages.RetryForTimeoutIssue": "No se pudo ejecutar el script porque se agotó el tiempo de espera. Se reintentará una vez más.", + "loc.messages.stdoutFromScript": "Salida estándar del script: ", + "loc.messages.stderrFromScript": "Error estándar del script: ", + "loc.messages.WebConfigAlreadyExists": "El archivo web.config ya existe. No se va a generar.", + "loc.messages.SuccessfullyGeneratedWebConfig": "El archivo web.config se generó correctamente", + "loc.messages.FailedToGenerateWebConfig": "No se pudo generar el archivo web.config. %s", + "loc.messages.FailedToGetKuduFileContent": "No se puede obtener el contenido del archivo: %s. Código de estado: %s (%s)", + "loc.messages.FailedToGetKuduFileContentError": "No se puede obtener el contenido del archivo: %s. Error: %s", + "loc.messages.ScriptStatusTimeout": "No se pudo recuperar el estado del script porque se agotó el tiempo de espera.", + "loc.messages.PollingForFileTimeOut": "No se puede recuperar el estado del script porque se agotó el tiempo de espera. Puede aumentar el tiempo de espera estableciendo la variable \"appservicedeploy.retrytimeout\" en el número de minutos que sea necesario.", + "loc.messages.InvalidPollOption": "Se ha proporcionado una opción de sondeo no válida: %s.", + "loc.messages.MissingAppTypeWebConfigParameters": "El atributo \"-appType\" falta en los parámetros de Web.config. Los valores válidos para \"-appType\" son: \"python_Bottle\", \"python_Django\", \"python_Flask\" y \"node\".
Por ejemplo, \"-appType python_Bottle\" (sin comillas) en caso de la plataforma Python Bottle.", + "loc.messages.AutoDetectDjangoSettingsFailed": "No se puede detectar la ruta de acceso del archivo \"settings.py\" de DJANGO_SETTINGS_MODULE. Asegúrese de que el archivo \"settings.py\" existe o indique la ruta de acceso correcta en la entrada del parámetro de Web.config siguiendo este formato: \"-DJANGO_SETTINGS_MODULE .settings\"", + "loc.messages.FailedToApplyTransformation": "No se puede aplicar la transformación para el paquete dado. Compruebe lo siguiente.", + "loc.messages.FailedToApplyTransformationReason1": "1. Si la transformación ya se ha aplicado para el paquete generado por MSBuild durante la compilación. Si es así, quite la etiqueta para cada configuración del archivo csproj y compile de nuevo. ", + "loc.messages.FailedToApplyTransformationReason2": "2. Asegúrese de que el archivo de configuración y los archivos de transformación están presentes en la misma carpeta dentro del paquete.", + "loc.messages.AutoParameterizationMessage": "Los atributos de ConnectionString en Web.config están parametrizados de manera predeterminada. Tenga en cuenta que la transformación no tiene efecto en los atributos connectionString porque el valor se invalida durante la implementación por los archivos \"Parameters.xml\" o \"SetParameters.xml\". Puede deshabilitar la parametrización automática estableciendo /p:AutoParameterizationWebConfigConnectionStrings=False durante la generación del paquete MSBuild.", + "loc.messages.UnsupportedAppType": "El tipo de aplicación \"'%s\" no se admite en la generación de Web.config. Los valores válidos para \"-appType\" son: \"python_Bottle\", \"python_Django\", \"python_Flask\" y \"'node\"", + "loc.messages.UnableToFetchAuthorityURL": "No se puede recuperar la dirección URL de la autoridad.", + "loc.messages.UnableToFetchActiveDirectory": "No se puede recuperar el identificador de recurso de Active Directory.", + "loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand": "La pila en tiempo de ejecución y el comando de inicio se actualizaron correctamente.", + "loc.messages.FailedToUpdateRuntimeStackAndStartupCommand": "No se pudieron actualizar la pila en tiempo de ejecución y el comando de inicio. Error: %s.", + "loc.messages.SuccessfullyUpdatedWebAppSettings": "La configuración de la aplicación se actualizó correctamente.", + "loc.messages.FailedToUpdateAppSettingsInConfigDetails": "No se pudo actualizar la configuración de la aplicación. Error: %s.", + "loc.messages.UnableToGetAzureRMWebAppMetadata": "No se pudieron capturar los metadatos de WebApp de AzureRM. Código de error: %s", + "loc.messages.UnableToUpdateAzureRMWebAppMetadata": "No se pueden actualizar los metadatos de WebApp de AzureRM. Código de error: %s", + "loc.messages.Unabletoretrieveazureregistrycredentials": "No se pueden recuperar las credenciales de Azure Container Registry. [Código de estado: \"%s\"]", + "loc.messages.UnableToReadResponseBody": "No se puede leer el cuerpo de la respuesta. Error: %s", + "loc.messages.UnableToUpdateWebAppConfigDetails": "No se pueden actualizar los detalles de la configuración de WebApp. Código de estado: \"%s\"", + "loc.messages.AddingReleaseAnnotation": "Agregar anotación de versión para el recurso de Application Insights \"%s\".", + "loc.messages.SuccessfullyAddedReleaseAnnotation": "La anotación de versión se agregó correctamente a la instancia de Application Insights: %s", + "loc.messages.FailedAddingReleaseAnnotation": "No se pudo agregar la anotación de versión. %s", + "loc.messages.RenameLockedFilesEnabled": "La opción Cambiar nombre de archivos bloqueados está habilitada para la instancia de App Service.", + "loc.messages.FailedToEnableRenameLockedFiles": "No se pudo habilitar el cambio de nombre de los archivos bloqueados. Error: %s", + "loc.messages.WebJobsInProgressIssue": "Algunos WebJobs en estado de ejecución impiden que la implementación quite los archivos. Puede deshabilitar la opción \"Quitar archivos adicionales en el destino\" o detener los trabajos continuos antes de la implementación.", + "loc.messages.FailedToFetchKuduAppSettings": "No se pudo capturar la configuración de la aplicación de Kudu. Error: %s", + "loc.messages.FailedToCreatePath": "No se pudo crear la ruta de acceso \"%s\" de Kudu. Error: %s", + "loc.messages.FailedToDeleteFile": "No se pudo eliminar el archivo \"%s/%s\" de Kudu. Error: %s", + "loc.messages.FailedToUploadFile": "No se pudo cargar el archivo \"%s/%s\" de Kudu. Error: %s", + "loc.messages.FailedToGetFileContent": "No se pudo obtener el contenido del archivo \"%s/%s\" de Kudu. Error: %s", + "loc.messages.FailedToListPath": "No se pudo enumerar la ruta de acceso \"%s\" de Kudu. Error: %s", + "loc.messages.RetryToDeploy": "Reintentando la implementación del paquete.", + "loc.messages.FailedToGetAppServiceDetails": "No se pudieron capturar los detalles de la instancia de App Service \"%s\". Error: %s", + "loc.messages.FailedToGetAppServicePublishingProfile": "No se pudo capturar el perfil de publicación de la instancia de App Service \"%s\". Error: %s", + "loc.messages.FailedToUpdateAppServiceMetadata": "No se pudieron actualizar los metadatos de la instancia de App Service \"%s\". Error: %s", + "loc.messages.FailedToGetAppServiceMetadata": "No se pudieron obtener los metadatos de la instancia de App Service \"%s\". Error: %s", + "loc.messages.FailedToPatchAppServiceConfiguration": "No se pudo aplicar una revisión a la configuración de la instancia de App Service \"%s\". Error: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "No se pudo actualizar la configuración de la instancia de App Service \"%s\". Error: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "No se pudo obtener la configuración de la instancia de App Service \"%s\". Error: %s", + "loc.messages.FailedToGetAppServicePublishingCredentials": "No se pudieron capturar las credenciales de publicación de la instancia de App Service \"%s\". Error: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "No se pudo obtener la configuración de aplicación de la instancia de App Service \"%s\". Error: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "No se pudo actualizar la configuración de aplicación de la instancia de App Service \"%s\". Error: %s", + "loc.messages.UpdatingAppServiceConfigurationSettings": "Actualizando los valores de configuración de App Service. Datos: %s", + "loc.messages.UpdatedAppServiceConfigurationSettings": "Se han actualizado los valores de configuración de App Service.", + "loc.messages.UpdatingAppServiceApplicationSettings": "Actualizando la configuración de aplicación de App Service. Datos: %s", + "loc.messages.UpdatedAppServiceApplicationSettings": "Se han actualizado la configuración de aplicación de App Service y la configuración de aplicación de Kudu.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Se encontraron varios grupos de recursos para la instancia de App Service \"%s\".", + "loc.messages.PackageDeploymentUsingZipDeployFailed": "Error al implementar el paquete mediante la implementación de ZIP. Consulte los registros para obtener más detalles.", + "loc.messages.PackageDeploymentInitiated": "Se ha iniciado la implementación del paquete mediante la implementación de ZIP.", + "loc.messages.FailedToGetDeploymentLogs": "No se pudieron obtener los registros de implementación. Error: %s", + "loc.messages.GoExeNameNotPresent": "Nombre de exe ir no está presente", + "loc.messages.WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier." +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/fr-fr/resources.resjson b/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/fr-fr/resources.resjson new file mode 100644 index 000000000000..5097159159da --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/fr-fr/resources.resjson @@ -0,0 +1,219 @@ +{ + "loc.friendlyName": "Déploiement Azure App Service", + "loc.helpMarkDown": "[Plus d'informations](https://aka.ms/azurermwebdeployreadme)", + "loc.description": "Mettre à jour Azure WebApp Services sur Windows, Web App sur Linux avec des conteneurs Docker ou des images intégrées, des applications web ASP.NET, .NET Core, PHP, Python ou Node, Function Apps, Mobile Apps, API Apps, des WebJobs à l'aide des API REST Web Deploy / Kudu", + "loc.instanceNameFormat": "Déploiement d'Azure App Service : $(WebAppName)", + "loc.releaseNotes": "Nouveautés de la version 3.0 :
  Prise en charge des transformations de fichiers (XDT)
  Prise en charge des substitutions de variables (XML, JSON)
Cliquez [ici](https://aka.ms/azurermwebdeployreadme) pour plus d'informations.", + "loc.group.displayName.FileTransformsAndVariableSubstitution": "Transformations de fichiers et options de substitution de variable", + "loc.group.displayName.AdditionalDeploymentOptions": "Options de déploiement supplémentaires", + "loc.group.displayName.PostDeploymentAction": "Action de postdéploiement", + "loc.group.displayName.ApplicationAndConfigurationSettings": "Paramètres d'application et de configuration", + "loc.group.displayName.output": "Sortie", + "loc.input.label.ConnectedServiceName": "Abonnement Azure", + "loc.input.help.ConnectedServiceName": "Sélectionnez l'abonnement Azure Resource Manager pour le déploiement.", + "loc.input.label.WebAppKind": "Type d'application", + "loc.input.help.WebAppKind": "Sélectionnez le type d'application web à déployer.
Remarque : Sélectionnez Linux Web App pour les déploiements d'images de plateforme intégrées ou d'images conteneurs personnalisées.", + "loc.input.label.WebAppName": "Nom App Service", + "loc.input.help.WebAppName": "Entrez ou sélectionnez le nom d'un Azure App Service existant. Seuls les App Services basés sur le type d'application sélectionné sont listés.", + "loc.input.label.DeployToSlotFlag": "Déployer sur l'emplacement", + "loc.input.help.DeployToSlotFlag": "Sélectionnez cette option pour effectuer le déploiement sur un emplacement existant autre que l'emplacement de production. Si cette option n'est pas sélectionnée, Azure App Service est déployé sur l'emplacement de production.", + "loc.input.label.ResourceGroupName": "Groupe de ressources", + "loc.input.help.ResourceGroupName": "Entrez ou sélectionnez le groupe de ressources Azure qui contient le service Azure App Service spécifié ci-dessus.", + "loc.input.label.SlotName": "Emplacement", + "loc.input.help.SlotName": "Entrez ou sélectionnez un emplacement existant autre que l'emplacement de production.", + "loc.input.label.ImageSource": "Source de l'image", + "loc.input.help.ImageSource": "App Service sur Linux propose deux options différentes pour publier votre application :
le déploiement d'image personnalisé ou le déploiement d'application avec une image de plateforme intégrée. [En savoir plus](https://go.microsoft.com/fwlink/?linkid=862490)", + "loc.input.label.AzureContainerRegistry": "Registre", + "loc.input.help.AzureContainerRegistry": "Nom de domaine de premier niveau de type identificateur global unique pour votre registre spécifique.
Remarque : Le nom d'image complet est au format : '/:<étiquette>'. Exemple : 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.AzureContainerRegistryLoginServer": "Nom du serveur de connexion au registre", + "loc.input.help.AzureContainerRegistryLoginServer": "Entrez ou sélectionnez un nom de serveur de connexion au registre de conteneurs Azure.", + "loc.input.label.AzureContainerRegistryImage": "Image", + "loc.input.help.AzureContainerRegistryImage": "Nom du dépôt où sont stockés les images conteneurs.
Remarque : Le nom d'image complet est au format : '/:<étiquette>'. Exemple : 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.AzureContainerRegistryTag": "Étiquette", + "loc.input.help.AzureContainerRegistryTag": "Les étiquettes sont facultatives. Il s'agit du mécanisme utilisé par les registres pour donner une version aux images Docker.
Remarque : Le nom d'image complet est au format suivant : '/:<étiquette>'. Exemple : 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerRepositoryAccess": "Accès au dépôt", + "loc.input.help.DockerRepositoryAccess": "Sélectionnez l'accès au dépôt Docker.", + "loc.input.label.RegistryConnectedServiceName": "Connexion au registre", + "loc.input.help.RegistryConnectedServiceName": "Sélectionnez la connexion au registre.", + "loc.input.label.PrivateRegistryImage": "Image", + "loc.input.help.PrivateRegistryImage": "Nom du dépôt où sont stockés les images conteneurs.
Remarque : Le nom d'image complet est au format : '/:<étiquette>'. Exemple : 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.PrivateRegistryTag": "Étiquette", + "loc.input.help.PrivateRegistryTag": "Les étiquettes sont facultatives. Il s'agit du mécanisme utilisé par les registres pour donner une version aux images Docker.
Remarque : Le nom d'image complet est au format suivant : '/:<étiquette>'. Exemple : 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerNamespace": "Registre ou espace de noms", + "loc.input.help.DockerNamespace": "Nom de domaine de premier niveau de type identificateur global unique pour votre registre ou espace de noms spécifique.
Remarque : Le nom d'image complet est au format : '/:<étiquette>'. Exemple : 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerRepository": "Image", + "loc.input.help.DockerRepository": "Nom du dépôt où sont stockés les images conteneurs.
Remarque : Le nom d'image complet est au format : '/:<étiquette>'. Exemple : 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerImageTag": "Étiquette", + "loc.input.help.DockerImageTag": "Les étiquettes sont facultatives. Il s'agit du mécanisme utilisé par les registres pour donner une version aux images Docker.
Remarque : Le nom d'image complet est au format suivant : '/:<étiquette>'. Exemple : 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.VirtualApplication": "Application virtuelle", + "loc.input.help.VirtualApplication": "Spécifiez le nom de l'application virtuelle configurée dans le portail Azure. L'option n'est pas nécessaire pour les déploiements sur la racine App Service.", + "loc.input.label.Package": "Package ou dossier", + "loc.input.help.Package": "Chemin de fichier du package ou d'un dossier de contenu App Service généré par MSBuild, ou d'un fichier zip ou war compressé.
Les variables ([Build](https://www.visualstudio.com/docs/build/define/variables) | [Mise en production](https://www.visualstudio.com/docs/release/author-release-definition/understanding-tasks#predefvariables)) et les caractères génériques sont pris en charge.
Exemple : $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip ou $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.BuiltinLinuxPackage": "Package ou dossier", + "loc.input.help.BuiltinLinuxPackage": "Chemin de fichier du package ou d'un dossier de contenu App Service généré par MSBuild, ou d'un fichier zip ou war compressé.
Les variables ([Build](https://www.visualstudio.com/docs/build/define/variables) | [Mise en production](https://www.visualstudio.com/docs/release/author-release-definition/understanding-tasks#predefvariables)) et les caractères génériques sont pris en charge.
Exemple : $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip ou $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.RuntimeStack": "Pile d'exécution", + "loc.input.help.RuntimeStack": "Sélectionnez le framework et la version.", + "loc.input.label.StartupCommand": "Commande de démarrage ", + "loc.input.help.StartupCommand": "Entrez la commande de démarrage.", + "loc.input.label.WebAppUri": "URL d'App Service", + "loc.input.help.WebAppUri": "Spécifiez un nom pour la variable de sortie générée pour l'URL d'Azure App Service. La variable peut être consommée dans des tâches ultérieures.", + "loc.input.label.ScriptType": "Type du script de déploiement", + "loc.input.help.ScriptType": "Personnalisez le déploiement en fournissant un script qui s'exécute sur Azure App Service, une fois que la tâche a effectué le déploiement avec succès. Par exemple, restaurez les packages des applications Node, PHP et Python. [En savoir plus](https://go.microsoft.com/fwlink/?linkid=843471).", + "loc.input.label.InlineScript": "Script Inline", + "loc.input.label.ScriptPath": "Chemin du script de déploiement", + "loc.input.label.GenerateWebConfig": "Générer web.config", + "loc.input.help.GenerateWebConfig": "Un fichier web.config standard va être généré et déployé sur Azure App Service, si l'application n'en a pas. Vous pouvez modifier les valeurs du fichier web.config. Celles-ci varient en fonction du framework d'application. Par exemple, pour l'application node.js, web.config a un fichier de démarrage et des valeurs de module iis_node. [En savoir plus](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.WebConfigParameters": "Paramètres web.config", + "loc.input.help.WebConfigParameters": "Modifiez des valeurs telles que le fichier de démarrage dans le fichier web.config généré. Cette fonctionnalité d'édition est réservée au fichier web.config généré. [En savoir plus](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.AppSettings": "Paramètres de l'application", + "loc.input.help.AppSettings": "Modifier les paramètres d’application web app respectant la syntaxe-valeur de clé. Valeur contenant des espaces doit être entre guillemets.
Exemple :-Port 5000 - RequestTimeout 5000
-WEBSITE_TIME_ZONE « Heure »", + "loc.input.label.ConfigurationSettings": "Paramètres de configuration", + "loc.input.help.ConfigurationSettings": "Modifier les paramètres de configuration d’application web respectant la syntaxe-valeur de clé. Valeur contenant des espaces doit être entre guillemets.
Exemple : - linuxFxVersion - phpVersion 5.6 : nœud|6.11", + "loc.input.label.TakeAppOfflineFlag": "Mettre l'application hors connexion", + "loc.input.help.TakeAppOfflineFlag": "Sélectionnez cette option pour mettre Azure App Service hors connexion en plaçant un fichier app_offline.htm dans le répertoire racine de l'App Service avant le début de l'opération de synchronisation. Le fichier est supprimé une fois l'opération de synchronisation correctement effectuée.", + "loc.input.label.UseWebDeploy": "Publication à l'aide de Web Deploy", + "loc.input.help.UseWebDeploy": "Les options de publication à l'aide de Web Deploy ne sont prises en charge qu'en cas d'utilisation de l'agent Windows. Sur d'autres plateformes, la tâche repose sur les [API REST Kudu](https://github.com/projectkudu/kudu/wiki/REST-API) pour déployer Azure App Service et les options suivantes ne sont pas prises en charge", + "loc.input.label.SetParametersFile": "Fichier SetParameters", + "loc.input.help.SetParametersFile": "Facultatif : emplacement du fichier SetParameters.xml à utiliser.", + "loc.input.label.RemoveAdditionalFilesFlag": "Supprimer les fichiers supplémentaires à la destination", + "loc.input.help.RemoveAdditionalFilesFlag": "Sélectionnez l'option permettant de supprimer les fichiers du service Azure App Service qui n'ont aucun fichier correspondant dans le package ou dossier App Service.

Remarque : Tous les fichiers associés à une extension installée sur ce service Azure App Service sont également supprimés. Pour éviter que cela se produise, cochez la case 'Exclure les fichiers du dossier App_Data'. ", + "loc.input.label.ExcludeFilesFromAppDataFlag": "Exclure les fichiers du dossier App_Data", + "loc.input.help.ExcludeFilesFromAppDataFlag": "Sélectionnez cette option pour empêcher le déploiement des fichiers du dossier App_Data sur Azure App Service.", + "loc.input.label.AdditionalArguments": "Arguments supplémentaires", + "loc.input.help.AdditionalArguments": "Arguments Web Deploy supplémentaires suivant la syntaxe -key:value.
Ceux-ci sont appliqués au moment du déploiement d'Azure App Service, par exemple : -disableLink:AppPoolExtension -disableLink:ContentExtension.
Pour plus d'exemples de paramètres d'opération Web Deploy, consultez [cette page](https://go.microsoft.com/fwlink/?linkid=838471).", + "loc.input.label.RenameFilesFlag": "Renommer les fichiers verrouillés", + "loc.input.help.RenameFilesFlag": "Sélectionnez l'option permettant d'activer l'indicateur msdeploy MSDEPLOY_RENAME_LOCKED_FILES=1 dans les paramètres d'application Azure App Service. Si cette option est définie, elle permet à msdeploy de renommer les fichiers verrouillés durant le déploiement de l'application", + "loc.input.label.XmlTransformation": "Transformation XML", + "loc.input.help.XmlTransformation": "Les transformations de configuration sont exécutées pour '*Release.config' et '*..config' sur le fichier '*.config'.
Elles sont exécutées avant la substitution de variable.
Les transformations XML sont prises en charge uniquement pour la plateforme Windows.", + "loc.input.label.XmlVariableSubstitution": "Substitution de variable XML", + "loc.input.help.XmlVariableSubstitution": "Les variables définies dans la définition de build ou mise en production sont mappées aux entrées 'key' ou 'name' dans les sections appSettings, connectionStrings et applicationSettings d'un fichier config et d'un fichier parameters.xml. La substitution de variable est exécutée après les transformations de configurations.

Remarque : Si les mêmes variables sont définies dans la définition de mise en production et dans l'environnement, les variables d'environnement remplacent les variables de définition de mise en production.
", + "loc.input.label.JSONFiles": "Substitution de variable JSON", + "loc.input.help.JSONFiles": "Fournissez une liste de fichiers JSON séparés par une ligne pour remplacer les valeurs de variable. Les noms de fichiers doivent être indiqués par rapport au dossier racine.
Pour remplacer les variables JSON imbriquées ou hiérarchiques, spécifiez-les à l'aide d'expressions JSONPath.

Par exemple, pour remplacer la valeur de 'ConnectionString' dans l'exemple ci-dessous, vous devez définir une variable en tant que 'Data.DefaultConnection.ConnectionString' dans la définition de build/mise en production (ou l'environnement de la définition de mise en production).
{
  \"Data\": {
    \"DefaultConnection\": {
      \"ConnectionString\": \"Server=(localdb)\\SQLEXPRESS;Database=MyDB;Trusted_Connection=True\"
    }
  }
}
La substitution de variable est exécutée après les transformations de configuration.

Remarque : les variables de définition du système de la build/mise en production sont exclues de la substitution", + "loc.messages.Invalidwebapppackageorfolderpathprovided": "Chemin de dossier ou package App Service fourni non valide : %s", + "loc.messages.SetParamFilenotfound0": "Fichier de définition de paramètres introuvable : %s", + "loc.messages.XDTTransformationsappliedsuccessfully": "Transformations XML correctement appliquées", + "loc.messages.GotconnectiondetailsforazureRMWebApp0": "Détails de connexion obtenus pour Azure App Service : '%s'", + "loc.messages.ErrorNoSuchDeployingMethodExists": "Erreur : Aucune méthode de déploiement de ce type n'existe", + "loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp": "Impossible de récupérer les détails de connexion d'Azure App Service : %s. Code d'état : %s (%s)", + "loc.messages.UnabletoretrieveResourceID": "Impossible de récupérer les détails de connexion de la ressource Azure : '%s'. Code d'état : %s", + "loc.messages.CouldnotfetchaccesstokenforAzureStatusCode": "Impossible de récupérer (fetch) le jeton d'accès pour Azure. Code d'état : %s (%s)", + "loc.messages.Successfullyupdateddeploymenthistory": "Historique de déploiement mis à jour sur %s", + "loc.messages.Failedtoupdatedeploymenthistory": "Échec de la mise à jour de l'historique de déploiement. Erreur : %s", + "loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "AVERTISSEMENT : Impossible de mettre à jour l'état de déploiement : le point de terminaison SCM n'est pas activé pour ce site web", + "loc.messages.Unabletoretrievewebconfigdetails": "Impossible de récupérer les détails de la configuration d'App Service. Code d'état : '%s'", + "loc.messages.Unabletoretrievewebappsettings": "Impossible de récupérer les paramètres d'application App Service. [Code d'état : '%s', message d'erreur : '%s']", + "loc.messages.Unabletoupdatewebappsettings": "Impossible de mettre à jour les paramètres d'application d'App Service. Code d'état : '%s'", + "loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "Impossible de mettre à jour l'état du déploiement : l'ID de déploiement unique ne peut pas être récupéré", + "loc.messages.PackageDeploymentSuccess": "Déploiement réussi du package web sur App Service.", + "loc.messages.PackageDeploymentFailed": "Échec de déploiement du package web sur App Service.", + "loc.messages.Runningcommand": "Exécution de la commande : %s", + "loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath": "Déploiement du package web : %s sur le chemin virtuel (chemin physique) : %s (%s)", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Package %s déployé à l'aide du service kudu sur %s", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Impossible de déployer le package App Service à l'aide du service kudu : %s", + "loc.messages.Unabletodeploywebappresponsecode": "Impossible de déployer App Service en raison du code d'erreur %s", + "loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "Les packages générés par MSDeploy sont uniquement pris en charge par la plateforme Windows.", + "loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "Version installée non prise en charge : %s trouvé pour MSDeploy. Il doit s'agir au minimum de la version 3 ou d'une version ultérieure", + "loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError": "Emplacement introuvable de MSDeploy dans le Registre de l'ordinateur (Erreur : %s)", + "loc.messages.Nopackagefoundwithspecifiedpattern": "Package introuvable avec le modèle spécifié : %s", + "loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "Plusieurs packages correspondent au modèle spécifié : %s. Affinez le modèle de recherche.", + "loc.messages.Trytodeploywebappagainwithappofflineoptionselected": "Essayez de redéployer App Service avec l'option Mettre l'application hors connexion sélectionnée.", + "loc.messages.Trytodeploywebappagainwithrenamefileoptionselected": "Essayez de redéployer App Service avec l'option Renommer les fichiers verrouillés sélectionnée.", + "loc.messages.NOJSONfilematchedwithspecificpattern": "Aucun fichier JSON ne correspond au modèle spécifique : %s.", + "loc.messages.Configfiledoesntexists": "Le fichier de configuration %s n'existe pas.", + "loc.messages.Failedtowritetoconfigfilewitherror": "Échec d'écriture dans le fichier config %s avec l'erreur : %s", + "loc.messages.AppOfflineModeenabled": "Mode hors connexion de l'application activé.", + "loc.messages.Failedtoenableappofflinemode": "Échec de l'activation du mode hors connexion de l'application. Code d'état : %s (%s)", + "loc.messages.AppOflineModedisabled": "Mode hors connexion de l'application désactivé.", + "loc.messages.FailedtodisableAppOfflineMode": "Impossible de désactiver le mode hors connexion de l'application. Code d'état : %s (%s)", + "loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform": "Impossible d'effectuer les transformations XML sur une plateforme non-Windows.", + "loc.messages.XdtTransformationErrorWhileTransforming": "Erreur de transformation XML lors de la transformation de %s à l'aide de %s.", + "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Les options de publication à l'aide de webdeploy ne sont prises en charge qu'en cas d'utilisation de l'agent Windows", + "loc.messages.ResourceDoesntExist": "La ressource '%s' n'existe pas. La ressource doit exister avant le déploiement.", + "loc.messages.EncodeNotSupported": "Encodage du fichier %s en %s détecté. La substitution de variable n'est pas prise en charge avec l'encodage de fichier %s. Les encodages pris en charge sont UTF-8 et UTF-16 LE.", + "loc.messages.UnknownFileEncodeError": "Impossible de détecter l'encodage du fichier %s (typeCode : %s). Les encodages pris en charge sont UTF-8 et UTF-16 LE.", + "loc.messages.ShortFileBufferError": "La mémoire tampon de fichier est insuffisante pour détecter le type d'encodage : %s", + "loc.messages.FailedToUpdateAzureRMWebAppConfigDetails": "Impossible de mettre à jour les informations sur la configuration App Service. Erreur : %s", + "loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails": "Informations sur la configuration App Service correctement mises à jour", + "loc.messages.RequestedURLforkuduphysicalpath": "URL demandée pour le chemin d'accès physique Kudu : %s", + "loc.messages.Physicalpathalreadyexists": "Le chemin d'accès physique '%s' existe déjà", + "loc.messages.KuduPhysicalpathCreatedSuccessfully": "Chemin d'accès physique Kudu correctement créé : %s", + "loc.messages.FailedtocreateKuduPhysicalPath": "Échec de la création du chemin physique de kudu. Erreur : %s", + "loc.messages.FailedtocheckphysicalPath": "Échec de la vérification du chemin physique de kudu. Code d'erreur : %s", + "loc.messages.VirtualApplicationDoesNotExist": "L'application virtuelle %s n'existe pas", + "loc.messages.JSONParseError": "Impossible d'analyser le fichier JSON : %s. Erreur : %s", + "loc.messages.JSONvariablesubstitutionappliedsuccessfully": "Substitution de variable JSON correctement appliquée.", + "loc.messages.XMLvariablesubstitutionappliedsuccessfully": "La substitution de la variable XML a été appliquée.", + "loc.messages.failedtoUploadFileToKudu": "Impossible de charger le fichier %s sur Kudu (%s). Code d'état : %s", + "loc.messages.failedtoUploadFileToKuduError": "Impossible de charger le fichier %s sur Kudu (%s). Erreur : %s", + "loc.messages.ExecuteScriptOnKudu": "Exécution du script donné sur le service Kudu.", + "loc.messages.FailedToRunScriptOnKuduError": "Impossible d'exécuter le script sur le service Kudu. Erreur : %s", + "loc.messages.FailedToRunScriptOnKudu": "Impossible d'exécuter le script sur Kudu : %s. Code d'état : %s", + "loc.messages.ScriptExecutionOnKuduSuccess": "Exécution réussie du script sur Kudu.", + "loc.messages.ScriptExecutionOnKuduFailed": "Le script exécuté a généré le code de retour '%s'. Erreur : %s", + "loc.messages.FailedtoDeleteFileFromKudu": "Impossible de supprimer le fichier %s de Kudu (%s). Code d'état : %s", + "loc.messages.FailedtoDeleteFileFromKuduError": "Impossible de supprimer le fichier %s de Kudu (%s). Erreur : %s", + "loc.messages.ScriptFileNotFound": "Le fichier de script '%s' est introuvable.", + "loc.messages.InvalidScriptFile": "Le fichier de script fourni '%s' est non valide. Les extensions valides sont .bat et .cmd pour Windows, et.sh pour Linux", + "loc.messages.RetryForTimeoutIssue": "Échec de l'exécution du script en raison d'un problème de délai d'expiration. Nouvelle tentative.", + "loc.messages.stdoutFromScript": "Sortie standard du script : ", + "loc.messages.stderrFromScript": "Erreur standard du script : ", + "loc.messages.WebConfigAlreadyExists": "Le fichier web.config existe déjà. Aucune génération en cours.", + "loc.messages.SuccessfullyGeneratedWebConfig": "Génération réussie du fichier web.config", + "loc.messages.FailedToGenerateWebConfig": "Échec de génération de web.config. %s", + "loc.messages.FailedToGetKuduFileContent": "Impossible d'obtenir le contenu du fichier : %s. Code d'état : %s (%s)", + "loc.messages.FailedToGetKuduFileContentError": "Impossible d'obtenir le contenu du fichier : %s. Erreur : %s", + "loc.messages.ScriptStatusTimeout": "Impossible de récupérer (fetch) l'état du script en raison du délai d'expiration.", + "loc.messages.PollingForFileTimeOut": "Impossible de récupérer (fetch) l'état du script en raison du délai d'expiration. Vous pouvez augmenter la limite du délai d'expiration en affectant le nombre de minutes nécessaires à la variable 'appservicedeploy.retrytimeout'.", + "loc.messages.InvalidPollOption": "Option d'interrogation non valide fournie : %s.", + "loc.messages.MissingAppTypeWebConfigParameters": "Il manque l'attribut '-appType' dans les paramètres de Web.config. Les valeurs valides pour '-appType' sont : 'python_Bottle', 'python_Django', 'python_Flask' et 'node'.
Exemple : '-appType python_Bottle' (sans guillemets) dans le cas d'un framework Python Bottle.", + "loc.messages.AutoDetectDjangoSettingsFailed": "Impossible de détecter le chemin du fichier 'settings.py' pour DJANGO_SETTINGS_MODULE. Vérifiez que le fichier 'settings.py' existe, ou indiquez le chemin approprié dans l'entrée de paramètre de Web.config au format suivant : '-DJANGO_SETTINGS_MODULE .settings'", + "loc.messages.FailedToApplyTransformation": "Impossible d'appliquer la transformation pour le package donné. Vérifiez ce qui suit.", + "loc.messages.FailedToApplyTransformationReason1": "1. La transformation est-elle déjà appliquée pour le package MSBuild généré durant la build ? Si la réponse est oui, supprimez la balise pour chaque configuration dans le fichier csproj, puis effectuez une regénération. ", + "loc.messages.FailedToApplyTransformationReason2": "2. Vérifiez que le fichier config et les fichiers de transformation sont présents dans le même dossier à l'intérieur du package.", + "loc.messages.AutoParameterizationMessage": "Les attributs de ConnectionString dans Web.config sont paramétrables par défaut. Notez que la transformation n'a aucun effet sur les attributs de connectionString, car la valeur est remplacée durant le déploiement par les fichiers 'Parameters.xml' ou 'SetParameters.xml'. Vous pouvez désactiver le paramétrage automatique en définissant /p:AutoParameterizationWebConfigConnectionStrings=False durant la génération du package MSBuild.", + "loc.messages.UnsupportedAppType": "Le type d'application '%s' n'est pas pris en charge dans la génération de Web.config. Les valeurs valides pour '-appType' sont : 'python_Bottle', 'python_Django', 'python_Flask' et 'node'", + "loc.messages.UnableToFetchAuthorityURL": "Impossible de récupérer (fetch) l'URL d'autorité.", + "loc.messages.UnableToFetchActiveDirectory": "Impossible de récupérer (fetch) l'ID de ressource du répertoire actif.", + "loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand": "Mise à jour réussie de la pile d'exécution et de la commande de démarrage.", + "loc.messages.FailedToUpdateRuntimeStackAndStartupCommand": "Échec de la mise à jour de la pile d'exécution et de la commande de démarrage. Erreur : %s.", + "loc.messages.SuccessfullyUpdatedWebAppSettings": "Mise à jour réussie des paramètres de l'application.", + "loc.messages.FailedToUpdateAppSettingsInConfigDetails": "Échec de la mise à jour des paramètres de l'application. Erreur : %s.", + "loc.messages.UnableToGetAzureRMWebAppMetadata": "Échec de la récupération (fetch) des métadonnées de la WebApp AzureRM. ErrorCode : %s", + "loc.messages.UnableToUpdateAzureRMWebAppMetadata": "Impossible de mettre à jour les métadonnées de la WebApp AzureRM. Code d'erreur : %s", + "loc.messages.Unabletoretrieveazureregistrycredentials": "Impossible de récupérer les informations d'identification d'Azure Container Registry.[Code d'état : '%s']", + "loc.messages.UnableToReadResponseBody": "Impossible de lire le corps de la réponse. Erreur : %s", + "loc.messages.UnableToUpdateWebAppConfigDetails": "Impossible de mettre à jour les détails de configuration de la WebApp. StatusCode : '%s'", + "loc.messages.AddingReleaseAnnotation": "Ajout d'une annotation de mise en production pour la ressource Application Insights '%s'", + "loc.messages.SuccessfullyAddedReleaseAnnotation": "Ajout réussi de l'annotation de mise en production à Application Insight : %s", + "loc.messages.FailedAddingReleaseAnnotation": "Échec de l'ajout de l'annotation de mise en production. %s", + "loc.messages.RenameLockedFilesEnabled": "Le renommage des fichiers verrouillés est activé pour App Service.", + "loc.messages.FailedToEnableRenameLockedFiles": "Échec de l'activation du renommage des fichiers verrouillés. Erreur : %s", + "loc.messages.WebJobsInProgressIssue": "Un petit nombre de WebJobs à l'état en cours d'exécution empêchent le processus de déploiement de supprimer les fichiers. Désactivez l'option 'Supprimer les fichiers supplémentaires à l'emplacement de destination', ou arrêtez les travaux continus avant le déploiement.", + "loc.messages.FailedToFetchKuduAppSettings": "Échec de la récupération (fetch) des paramètres d'application Kudu. Erreur : %s", + "loc.messages.FailedToCreatePath": "Échec de la création du chemin '%s' à partir de Kudu. Erreur : %s", + "loc.messages.FailedToDeleteFile": "Échec de la suppression du fichier '%s/%s' à partir de Kudu. Erreur : %s", + "loc.messages.FailedToUploadFile": "Échec du chargement du fichier '%s/%s' à partir de Kudu. Erreur : %s", + "loc.messages.FailedToGetFileContent": "Échec de l'obtention du contenu du fichier '%s/%s' à partir de Kudu. Erreur : %s", + "loc.messages.FailedToListPath": "Échec du listage du chemin '%s' à partir de Kudu. Erreur : %s", + "loc.messages.RetryToDeploy": "Nouvelle tentative de déploiement du package.", + "loc.messages.FailedToGetAppServiceDetails": "Échec de la récupération (fetch) des détails de l'App Service '%s'. Erreur : %s", + "loc.messages.FailedToGetAppServicePublishingProfile": "Échec de la récupération (fetch) du profil de publication de l'App Service '%s'. Erreur : %s", + "loc.messages.FailedToUpdateAppServiceMetadata": "Échec de la mise à jour des métadonnées de l'App Service '%s'. Erreur : %s", + "loc.messages.FailedToGetAppServiceMetadata": "Échec de l'obtention des métadonnées de l'App Service '%s'. Erreur : %s", + "loc.messages.FailedToPatchAppServiceConfiguration": "Échec de l'application du correctif à la configuration de l'App Service '%s'. Erreur : %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Échec de la mise à jour de la configuration de l'App Service '%s'. Erreur : %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Échec de l'obtention de la configuration de l'App Service '%s'. Erreur : %s", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Échec de la récupération (fetch) des informations d'identification de publication de l'App Service '%s'. Erreur : %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Échec de l'obtention des paramètres d'application de l'App Service '%s'. Erreur : %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Échec de la mise à jour des paramètres d'application de l'App Service '%s'. Erreur : %s", + "loc.messages.UpdatingAppServiceConfigurationSettings": "Mise à jour des paramètres de configuration d'App Service. Données : %s", + "loc.messages.UpdatedAppServiceConfigurationSettings": "Mise à jour effectuée des paramètres de configuration d'App Service.", + "loc.messages.UpdatingAppServiceApplicationSettings": "Mise à jour des paramètres d'application d'App Service. Données : %s", + "loc.messages.UpdatedAppServiceApplicationSettings": "Mise à jour effectuée des paramètres d'application d'App Service et des paramètres d'application de Kudu.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Plusieurs groupes de ressources trouvés pour l'App Service '%s'.", + "loc.messages.PackageDeploymentUsingZipDeployFailed": "Échec du déploiement de package à l'aide de ZIP Deploy. Pour plus d'informations, consultez les journaux.", + "loc.messages.PackageDeploymentInitiated": "Lancement effectué du déploiement de package à l'aide de ZIP Deploy.", + "loc.messages.FailedToGetDeploymentLogs": "Échec de l'obtention des journaux de déploiement. Erreur : %s", + "loc.messages.GoExeNameNotPresent": "Nom de l’exe atteindre n’est pas présent", + "loc.messages.WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier." +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/it-IT/resources.resjson b/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/it-IT/resources.resjson new file mode 100644 index 000000000000..6a774b952cf3 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/it-IT/resources.resjson @@ -0,0 +1,219 @@ +{ + "loc.friendlyName": "Distribuzione servizio app di Azure", + "loc.helpMarkDown": "[Altre informazioni](https://aka.ms/azurermwebdeployreadme)", + "loc.description": "Consente di aggiornare servizi app Web di Azure in Windows, app Web in Linux con immagini o contenitori Docker predefiniti, applicazioni Web basate su ASP.NET, .NET Core, PHP, Python o Node, app per le funzioni, app per dispositivi mobili, applicazioni API, processi Web che usano API REST Distribuzione Web/Kudu", + "loc.instanceNameFormat": "Distribuzione servizio app di Azure: $(WebAppName)", + "loc.releaseNotes": "Novità della versione 3.0:
  Supporta le trasformazioni di file (XDT)
  Supporta le sostituzioni di variabili (XML, JSON)
Per altre informazioni, fare clic [qui](https://aka.ms/azurermwebdeployreadme).", + "loc.group.displayName.FileTransformsAndVariableSubstitution": "Opzioni di trasformazioni di file e sostituzioni di variabili", + "loc.group.displayName.AdditionalDeploymentOptions": "Opzioni di distribuzione aggiuntive", + "loc.group.displayName.PostDeploymentAction": "Azione post-distribuzione", + "loc.group.displayName.ApplicationAndConfigurationSettings": "Impostazioni applicazione e configurazione", + "loc.group.displayName.output": "Output", + "loc.input.label.ConnectedServiceName": "Sottoscrizione di Azure", + "loc.input.help.ConnectedServiceName": "Selezionare la sottoscrizione di Azure Resource Manager per la distribuzione.", + "loc.input.label.WebAppKind": "Tipo di app", + "loc.input.help.WebAppKind": "Consente di selezionare il tipo di app Web da distribuire.
Nota: selezionare App Web Linux per le immagine della piattaforma predefinita o per distribuzioni di immagini del contenitore personalizzate.", + "loc.input.label.WebAppName": "Nome del servizio app", + "loc.input.help.WebAppName": "Consente di immettere o selezionare il nome di un servizio app di Azure. Verranno elencati solo i servizi app basati sul tipo di app selezionato.", + "loc.input.label.DeployToSlotFlag": "Distribuisci nello slot", + "loc.input.help.DeployToSlotFlag": "Consente di selezionare l'opzione per eseguire la distribuzione in uno slot esistente diverso da quello di produzione. Se questa opzione non è selezionata, il servizio app di Azure verrà distribuito nello slot di produzione.", + "loc.input.label.ResourceGroupName": "Gruppo di risorse", + "loc.input.help.ResourceGroupName": "Consente di immettere o selezionare il gruppo di risorse di Azure contenente il servizio app di Azure specificato in precedenza.", + "loc.input.label.SlotName": "Slot", + "loc.input.help.SlotName": "Immettere o selezionare uno slot esistente diverso da quello di produzione.", + "loc.input.label.ImageSource": "Origine immagine", + "loc.input.help.ImageSource": "Il servizio app in Linux offre due diverse opzioni per pubblicare l'applicazione:
Distribuzione di un'immagine personalizzata oppure distribuzione dell'app con un'immagine della piattaforma predefinita. [Altre informazioni](https://go.microsoft.com/fwlink/?linkid=862490)", + "loc.input.label.AzureContainerRegistry": "Registro", + "loc.input.help.AzureContainerRegistry": "Nome di dominio di primo livello univoco a livello globale per il registro specifico.
Nota: il formato del nome completo dell'immagine è: '`/`:`'. Esempio: 'registropersonale.azurecr.io/nginx:latest'.", + "loc.input.label.AzureContainerRegistryLoginServer": "Nome del server di accesso del registro", + "loc.input.help.AzureContainerRegistryLoginServer": "Consente di immettere o selezionare un nome del server di accesso del Registro contenitori di Azure.", + "loc.input.label.AzureContainerRegistryImage": "Immagine", + "loc.input.help.AzureContainerRegistryImage": "Nome del repository in cui vengono archiviate le immagini del contenitore.
Nota: il formato del nome completo dell'immagine è: '`/`:`'. Esempio: 'registropersonale.azurecr.io/nginx:latest'.", + "loc.input.label.AzureContainerRegistryTag": "Tag", + "loc.input.help.AzureContainerRegistryTag": "I tag sono facoltativi e costituiscono il meccanismo usato dai registri per assegnare una versione alle immagini Docker.
Nota: il formato del nome completo dell'immagine è: '`/`:`'. Esempio: 'registropersonale.azurecr.io/nginx:latest'.", + "loc.input.label.DockerRepositoryAccess": "Accesso al repository", + "loc.input.help.DockerRepositoryAccess": "Consente di selezionare l'accesso al repository Docker.", + "loc.input.label.RegistryConnectedServiceName": "Connessione al registro", + "loc.input.help.RegistryConnectedServiceName": "Consente di selezionare la connessione al registro.", + "loc.input.label.PrivateRegistryImage": "Immagine", + "loc.input.help.PrivateRegistryImage": "Nome del repository in cui vengono archiviate le immagini del contenitore.
Nota: il formato del nome completo dell'immagine è: '`/`:`'. Esempio: 'registropersonale.azurecr.io/nginx:latest'.", + "loc.input.label.PrivateRegistryTag": "Tag", + "loc.input.help.PrivateRegistryTag": "I tag sono facoltativi e costituiscono il meccanismo usato dai registri per assegnare una versione alle immagini Docker.
Nota: il formato del nome completo dell'immagine è: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerNamespace": "Registro o spazio dei nomi", + "loc.input.help.DockerNamespace": "Nome di dominio di primo livello univoco a livello globale per il registro o lo spazio dei nomi specifico.
Nota: il formato del nome completo dell'immagine è: '`/`:`'. Esempio: 'registropersonale.azurecr.io/nginx:latest'.", + "loc.input.label.DockerRepository": "Immagine", + "loc.input.help.DockerRepository": "Nome del repository in cui vengono archiviate le immagini del contenitore.
Nota: il formato del nome completo dell'immagine è: '`/`:`'. Esempio: 'registropersonale.azurecr.io/nginx:latest'.", + "loc.input.label.DockerImageTag": "Tag", + "loc.input.help.DockerImageTag": "I tag sono facoltativi e costituiscono il meccanismo usato dai registri per assegnare una versione alle immagini Docker.
Nota: il formato del nome completo dell'immagine è: '`/`:`'. Esempio: 'registropersonale.azurecr.io/nginx:latest'.", + "loc.input.label.VirtualApplication": "Applicazione virtuale", + "loc.input.help.VirtualApplication": "Consente di specificare il nome dell'applicazione virtuale configurata nel portale di Azure. L'opzione non è necessaria per le distribuzioni nella radice del servizio app.", + "loc.input.label.Package": "Pacchetto o cartella", + "loc.input.help.Package": "Percorso file del pacchetto o di una cartella che include il contenuto del servizio app generato da MSBuild oppure un file WAR o ZIP compresso.
Variabili ( [Compilazione](https://www.visualstudio.com/docs/build/define/variables) | [Versione](https://www.visualstudio.com/docs/release/author-release-definition/understanding-tasks#predefvariables)). I caratteri jolly sono supportati.
Ad esempio, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip o $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.BuiltinLinuxPackage": "Pacchetto o cartella", + "loc.input.help.BuiltinLinuxPackage": "Percorso file del pacchetto o di una cartella che include il contenuto del servizio app generato da MSBuild oppure un file WAR o ZIP compresso.
Variabili ( [Compilazione](https://www.visualstudio.com/docs/build/define/variables) | [Versione](https://www.visualstudio.com/docs/release/author-release-definition/understanding-tasks#predefvariables)). I caratteri jolly sono supportati.
Ad esempio, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip o $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.RuntimeStack": "Stack di runtime", + "loc.input.help.RuntimeStack": "Consente di selezionare il framework e la versione.", + "loc.input.label.StartupCommand": "Comando di avvio ", + "loc.input.help.StartupCommand": "Consente di immettere il comando di avvio.", + "loc.input.label.WebAppUri": "URL del servizio app", + "loc.input.help.WebAppUri": "Consente di specificare un nome per la variabile di output generata per l'URL del servizio app di Azure. La variabile può essere utilizzata in attività successive.", + "loc.input.label.ScriptType": "Tipo dello script di distribuzione", + "loc.input.help.ScriptType": "È possibile personalizzare la distribuzione fornendo uno script che verrà eseguito nel servizio app di Azure una volta completata la distribuzione dell'attività, ad esempio per ripristinare i pacchetti per le applicazioni Node, PHP e Python. [Altre informazioni](https://go.microsoft.com/fwlink/?linkid=843471).", + "loc.input.label.InlineScript": "Script inline", + "loc.input.label.ScriptPath": "Percorso dello script di distribuzione", + "loc.input.label.GenerateWebConfig": "Genera Web.config", + "loc.input.help.GenerateWebConfig": "Verrà generato un file Web.config standard che verrà distribuito nel servizio app di Azure, se non è disponibile per l'applicazione. I valori presenti nel file Web.config sono modificabili e possono variare a seconda del framework dell'applicazione. Ad esempio, per l'applicazione node.js il file Web.config includerà i valori per il file di avvio e il modulo iis_node. [Altre informazioni](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.WebConfigParameters": "Parametri di Web.config", + "loc.input.help.WebConfigParameters": "Consente di modificare valori, ad esempio il file di avvio, nel file Web.config generato. Questa funzionalità di modifica è valida solo per il file Web.config generato. [Altre informazioni](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.AppSettings": "Impostazioni app", + "loc.input.help.AppSettings": "Consente di modificare le impostazioni applicazione dell'app Web successive al valore -key della sintassi. Il valore che contiene spazi deve essere racchiuso tra virgolette.
Esempio: -Port 5000 -RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Ora solare fuso orientale\"", + "loc.input.label.ConfigurationSettings": "Impostazioni di configurazione", + "loc.input.help.ConfigurationSettings": "Consente di modificare le impostazioni di configurazione dell'app Web successive al valore -key della sintassi. Il valore che contiene spazi deve essere racchiuso tra virgolette.
Esempio: -phpVersion 5.6 -linuxFxVersion: node|6.11", + "loc.input.label.TakeAppOfflineFlag": "Porta app offline", + "loc.input.help.TakeAppOfflineFlag": "Consente di selezionare l'opzione per portare offline il servizio app di Azure inserendo un file app_offline.htm nella directory radice del servizio app prima dell'inizio dell'operazione di sincronizzazione. Il file verrà rimosso al termine dell'operazione di sincronizzazione.", + "loc.input.label.UseWebDeploy": "Pubblica con Distribuzione Web", + "loc.input.help.UseWebDeploy": "Le opzioni di pubblicazione con Distribuzione Web sono supportate solo quando si usa l'agente Windows. In altre piattaforme l'attività si basa su [API REST Kudu](https://github.com/projectkudu/kudu/wiki/REST-API) per distribuire il servizio app di Azure e le opzioni seguenti non sono supportate", + "loc.input.label.SetParametersFile": "File SetParameters", + "loc.input.help.SetParametersFile": "Facoltativo: percorso del file SetParameters.xml da usare.", + "loc.input.label.RemoveAdditionalFilesFlag": "Rimuovi file aggiuntivi nella destinazione", + "loc.input.help.RemoveAdditionalFilesFlag": "Consente di selezionare l'opzione per eliminare nel servizio app di Azure i file per cui non esistono file corrispondenti nella cartella o nel pacchetto del servizio app.

Nota: verranno rimossi anche tutti i file correlati a eventuali estensioni installate in questo servizio app di Azure. Per evitarlo, selezionare la casella di controllo 'Escludi file dalla cartella App_Data'. ", + "loc.input.label.ExcludeFilesFromAppDataFlag": "Escludi file dalla cartella App_Data", + "loc.input.help.ExcludeFilesFromAppDataFlag": "Consente di selezionare l'opzione per impedire che i file nella cartella App_Data vengano distribuiti nel servizio app di Azure.", + "loc.input.label.AdditionalArguments": "Argomenti aggiuntivi", + "loc.input.help.AdditionalArguments": "Argomenti aggiuntivi di Web Deploy conformi alla sintassi -chiave:valore.
Tali argomenti verranno applicati durante la distribuzione del servizio app di Azure. Esempio: -disableLink:AppPoolExtension -disableLink:ContentExtension.
Per altri esempi di impostazioni per le operazioni di Web Deploy, fare clic [qui](https://go.microsoft.com/fwlink/?linkid=838471).", + "loc.input.label.RenameFilesFlag": "Rinomina i file bloccati", + "loc.input.help.RenameFilesFlag": "Consente di selezionare l'opzione per abilitare il flag MSDEPLOY_RENAME_LOCKED_FILES=1 di MSDeploy nelle impostazioni dell'applicazione del servizio app di Azure. Se impostata, l'opzione consente a MSDeploy di rinominare file bloccati che vengono bloccati durante la distribuzione dell'app", + "loc.input.label.XmlTransformation": "Trasformazione XML", + "loc.input.help.XmlTransformation": "Le trasformazioni dei file config verranno eseguite per `*.Release.config` e `*..config` nel file `*.config`.
Le trasformazioni dei file config verranno eseguite prima della sostituzione delle variabili.
Le trasformazioni XML sono supportate solo per la piattaforma Windows.", + "loc.input.label.XmlVariableSubstitution": "Sostituzione di variabili XML", + "loc.input.help.XmlVariableSubstitution": "Le variabili indicate nella definizione di compilazione o di versione verranno confrontate con le voci 'key' o 'name' nelle sezioni appSettings, applicationSettings e connectionStrings di tutti i file config e parameters.xml. La sostituzione delle variabili viene eseguita dopo le trasformazioni dei file config.

Nota: se si indicano le stesse variabili nella definizione di versione e nell'ambiente, quelle dell'ambiente prevarranno su quelle della definizione di versione.
", + "loc.input.label.JSONFiles": "Sostituzione di variabili JSON", + "loc.input.help.JSONFiles": "Consente di specificare l'elenco di file JSON delimitati da caratteri di nuova riga per sostituire i valori delle variabili. I nomi di file specificati devono essere relativi alla cartella radice.
Per sostituire le variabili JSON annidate o gerarchiche, specificarle usando espressioni JSONPath.

Ad esempio, per sostituire il valore di ‘ConnectionString’ nell'esempio seguente, è necessario definire una variabile come ‘Data.DefaultConnection.ConnectionString’ nella definizione di compilazione/versione (o nell'ambiente della definizione di versione).
{
  \"Data\": {
    \"DefaultConnection\": {
      \"ConnectionString\": \"Server=(localdb)\\SQLEXPRESS;Database=MyDB;Trusted_Connection=True\"
    }
  }
}
La sostituzione delle variabili viene eseguita dopo le trasformazioni della configurazione.

Nota: le variabili di definizione di sistema di compilazione/versione vengono escluse nella sostituzione", + "loc.messages.Invalidwebapppackageorfolderpathprovided": "Il percorso specificato per il pacchetto o la cartella del servizio app non è valido: %s", + "loc.messages.SetParamFilenotfound0": "Il file dei parametri del set non è stato trovato: %s", + "loc.messages.XDTTransformationsappliedsuccessfully": "Le trasformazioni XML sono state applicate", + "loc.messages.GotconnectiondetailsforazureRMWebApp0": "I dettagli della connessione per il servizio app di Azure sono stati recuperati: '%s'", + "loc.messages.ErrorNoSuchDeployingMethodExists": "Errore: non esiste alcun metodo di distribuzione di questo tipo", + "loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp": "Non è possibile recuperare i dettagli della connessione per il servizio app di Azure: %s. Codice di stato: %s (%s)", + "loc.messages.UnabletoretrieveResourceID": "Non è possibile recuperare i dettagli della connessione per la risorsa di Azure '%s'. Codice di stato: %s", + "loc.messages.CouldnotfetchaccesstokenforAzureStatusCode": "Non è stato possibile recuperare il token di accesso per Azure. Codice di stato: %s (%s)", + "loc.messages.Successfullyupdateddeploymenthistory": "L'aggiornamento della cronologia di distribuzione all'indirizzo %s è stato completato", + "loc.messages.Failedtoupdatedeploymenthistory": "Non è stato possibile aggiornare la cronologia di distribuzione. Errore: %s", + "loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "AVVISO: non è possibile aggiornare lo stato di distribuzione. L'endpoint di Gestione controllo del codice sorgente non è abilitato per questo sito Web", + "loc.messages.Unabletoretrievewebconfigdetails": "Non è possibile recuperare i dettagli di configurazione del servizio app. Codice di stato: '%s'", + "loc.messages.Unabletoretrievewebappsettings": "Non è possibile recuperare le impostazioni dell'applicazione del servizio app. [Codice di stato: '%s'. Messaggio di errore: '%s']", + "loc.messages.Unabletoupdatewebappsettings": "Non è possibile aggiornare le impostazioni dell'applicazione del servizio app. Codice di stato: '%s'", + "loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "Non è possibile aggiornare lo stato di distribuzione. L'ID distribuzione univoco non è stato recuperato", + "loc.messages.PackageDeploymentSuccess": "Il pacchetto Web è stato distribuito nel servizio app.", + "loc.messages.PackageDeploymentFailed": "Non è stato possibile distribuire il pacchetto Web nel servizio app.", + "loc.messages.Runningcommand": "Esecuzione del comando: %s", + "loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath": "Distribuzione del pacchetto Web %s nel percorso virtuale (percorso fisico) %s (%s)", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "La distribuzione del pacchetto %s con il servizio Kudu all'indirizzo %s è riuscita", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Non è stato possibile distribuire il pacchetto del servizio app con il servizio Kudu: %s", + "loc.messages.Unabletodeploywebappresponsecode": "Non è possibile distribuire il servizio app a causa del codice errore: %s", + "loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "I pacchetti generati da MSDeploy sono supportati solo per la piattaforma Windows.", + "loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "La versione installata non è supportata. La versione trovata per MSDeploy è %s, ma deve essere almeno 3 o successiva", + "loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError": "Il percorso di MSDeploy non è stato trovato dal Registro di sistema nel computer (errore: %s)", + "loc.messages.Nopackagefoundwithspecifiedpattern": "Non è stato trovato alcun pacchetto con il criterio specificato %s", + "loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "Più pacchetti corrispondono al criterio specificato %s. Restringere i criteri di ricerca.", + "loc.messages.Trytodeploywebappagainwithappofflineoptionselected": "Provare a distribuire di nuovo il servizio app dopo aver selezionato l'opzione Porta l'applicazione offline.", + "loc.messages.Trytodeploywebappagainwithrenamefileoptionselected": "Provare a distribuire di nuovo il servizio app dopo aver selezionato l'opzione Rinomina i file bloccati.", + "loc.messages.NOJSONfilematchedwithspecificpattern": "Non sono stati trovati file JSON corrispondenti al criterio specificato: %s.", + "loc.messages.Configfiledoesntexists": "Il file di configurazione %s non esiste.", + "loc.messages.Failedtowritetoconfigfilewitherror": "Non è stato possibile scrivere nel file config %s. Errore: %s", + "loc.messages.AppOfflineModeenabled": "La modalità offline dell'app è abilitata.", + "loc.messages.Failedtoenableappofflinemode": "Non è stato possibile abilitare la modalità offline dell'app. Codice di stato: %s (%s)", + "loc.messages.AppOflineModedisabled": "La modalità offline dell'app è disabilitata.", + "loc.messages.FailedtodisableAppOfflineMode": "Non è stato possibile disabilitare la modalità offline dell'app. Codice di stato: %s (%s)", + "loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform": "Non è possibile eseguire trasformazioni XML su una piattaforma non Windows.", + "loc.messages.XdtTransformationErrorWhileTransforming": "Si è verificato un errore di trasformazione XML durante la trasformazione di %s con %s.", + "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Le opzioni di pubblicazione con Distribuzione Web sono supportate solo quando si usa l'agente Windows", + "loc.messages.ResourceDoesntExist": "La risorsa '%s' non esiste. La risorsa deve esistere prima della distribuzione.", + "loc.messages.EncodeNotSupported": "La codifica rilevata del file %s è %s. La sostituzione delle variabili non è supportata con la codifica file %s. Le codifiche supportate sono UTF-8 e UTF-16 LE.", + "loc.messages.UnknownFileEncodeError": "Non è possibile rilevare la codifica del file %s (typeCode: %s). Le codifiche supportate sono UTF-8 e UTF-16 LE.", + "loc.messages.ShortFileBufferError": "Il buffer di file è troppo piccolo per il rilevamento del tipo di codifica: %s", + "loc.messages.FailedToUpdateAzureRMWebAppConfigDetails": "Non è stato possibile aggiornare i dettagli della configurazione del servizio app. Errore: %s", + "loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails": "I dettagli della configurazione del servizio app sono stati aggiornati", + "loc.messages.RequestedURLforkuduphysicalpath": "È stato richiesto l'URL per il percorso fisico di Kudu: %s", + "loc.messages.Physicalpathalreadyexists": "Il percorso fisico '%s' esiste già", + "loc.messages.KuduPhysicalpathCreatedSuccessfully": "Il percorso fisico di Kudu è stato creato: %s", + "loc.messages.FailedtocreateKuduPhysicalPath": "Non è stato possibile creare il percorso fisico di Kudu. Errore: %s", + "loc.messages.FailedtocheckphysicalPath": "Non è stato possibile verificare il percorso fisico di Kudu. Codice errore: %s", + "loc.messages.VirtualApplicationDoesNotExist": "L'applicazione virtuale non esiste: %s", + "loc.messages.JSONParseError": "Non è possibile analizzare il file JSON: %s. Errore: %s", + "loc.messages.JSONvariablesubstitutionappliedsuccessfully": "La sostituzione di variabili JSON è stata applicata.", + "loc.messages.XMLvariablesubstitutionappliedsuccessfully": "La sostituzione di variabili XML è stata applicata.", + "loc.messages.failedtoUploadFileToKudu": "Non è possibile caricare il file %s in Kudu (%s). Codice di stato: %s", + "loc.messages.failedtoUploadFileToKuduError": "Non è stato possibile caricare il file %s in Kudu (%s). Errore: %s", + "loc.messages.ExecuteScriptOnKudu": "Esecuzione dello script specificato nel servizio Kudu.", + "loc.messages.FailedToRunScriptOnKuduError": "Non è possibile eseguire lo script nel servizio Kudu. Errore: %s", + "loc.messages.FailedToRunScriptOnKudu": "Non è possibile eseguire lo script in Kudu: %s. Codice di stato: %s", + "loc.messages.ScriptExecutionOnKuduSuccess": "Lo script è stato eseguito in Kudu.", + "loc.messages.ScriptExecutionOnKuduFailed": "Il codice restituito dallo script eseguito è '%s'. Errore: %s", + "loc.messages.FailedtoDeleteFileFromKudu": "Non è possibile eliminare il file %s da Kudu (%s). Codice di stato: %s", + "loc.messages.FailedtoDeleteFileFromKuduError": "Non è possibile eliminare il file %s da Kudu (%s). Errore: %s", + "loc.messages.ScriptFileNotFound": "Il file di script '%s' non è stato trovato.", + "loc.messages.InvalidScriptFile": "Il file di script specificato '%s' non è valido. Le estensioni valide sono bat e cmd per Windows e sh per Linux", + "loc.messages.RetryForTimeoutIssue": "L'esecuzione dello script non è riuscita a causa del timeout. Verrà effettuato un nuovo tentativo.", + "loc.messages.stdoutFromScript": "Output standard dello script: ", + "loc.messages.stderrFromScript": "Errore standard dello script: ", + "loc.messages.WebConfigAlreadyExists": "Il file Web.config esiste già e non verrà generato.", + "loc.messages.SuccessfullyGeneratedWebConfig": "Il file Web.config è stato generato", + "loc.messages.FailedToGenerateWebConfig": "Non è stato possibile generare il file Web.config. %s", + "loc.messages.FailedToGetKuduFileContent": "Non è possibile recuperare il contenuto del file: %s. Codice di stato: %s (%s)", + "loc.messages.FailedToGetKuduFileContentError": "Non è possibile recuperare il contenuto del file: %s. Errore: %s", + "loc.messages.ScriptStatusTimeout": "Non è possibile recuperare lo stato dello script a causa del timeout.", + "loc.messages.PollingForFileTimeOut": "Non è possibile recuperare lo stato dello script a causa del timeout. È possibile aumentare il limite di timeout impostando la variabile 'appservicedeploy.retrytimeout' sul numero di minuti necessari.", + "loc.messages.InvalidPollOption": "L'opzione di polling specificata %s non è valida.", + "loc.messages.MissingAppTypeWebConfigParameters": "Nei parametri di Web.config manca l'attributo '-appType'. I valori validi per '-appType' sono: 'python_Bottle', 'python_Django', 'python_Flask' e 'node'.
Esempio: '-appType python_Bottle' (senza virgolette) nel caso del framework Python Bottle.", + "loc.messages.AutoDetectDjangoSettingsFailed": "Il percorso del file 'settings.py' di DJANGO_SETTINGS_MODULE non è stato rilevato. Assicurarsi che il file 'settings.py' sia esistente oppure specificare il percorso corretto nel campo di input del parametro di Web.config nel formato seguente: '-DJANGO_SETTINGS_MODULE .settings'", + "loc.messages.FailedToApplyTransformation": "Non è possibile applicare la trasformazione per il pacchetto specificato. Eseguire le verifiche seguenti.", + "loc.messages.FailedToApplyTransformationReason1": "1. Verificare se la trasformazione è già stata applicata per il pacchetto generato da MSBuild durante la compilazione. In caso affermativo, rimuovere il tag per ogni file config nel file csproj e ricompilare. ", + "loc.messages.FailedToApplyTransformationReason2": "2. Assicurarsi che il file config e i file di trasformazione siano presenti nella stessa cartella all'interno del pacchetto.", + "loc.messages.AutoParameterizationMessage": "Per impostazione predefinita, agli attributi di ConnectionString in Web.config sono associati parametri. Si noti che la trasformazione non ha effetto sugli attributi di ConnectionString perché durante la distribuzione il valore viene sostituito dai file 'Parameters.xml' o 'SetParameters.xml'. Per disabilitare l'aggiunta automatica di parametri, impostare /p:AutoParameterizationWebConfigConnectionStrings=False durante la generazione del pacchetto MSBuild.", + "loc.messages.UnsupportedAppType": "Il tipo di app '%s' non è supportato nella generazione di Web.config. I valori validi per '-appType' sono: 'python_Bottle', 'python_Django', 'python_Flask' e 'node'", + "loc.messages.UnableToFetchAuthorityURL": "Non è possibile recuperare l'URL dell'autorità.", + "loc.messages.UnableToFetchActiveDirectory": "Non è possibile recuperare l'ID risorsa di Active Directory.", + "loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand": "Lo stack di runtime e il comando di avvio sono stati aggiornati.", + "loc.messages.FailedToUpdateRuntimeStackAndStartupCommand": "Non è stato possibile aggiornare lo stack di runtime e il comando di avvio. Errore: %s.", + "loc.messages.SuccessfullyUpdatedWebAppSettings": "Le impostazioni dell'app sono state aggiornate.", + "loc.messages.FailedToUpdateAppSettingsInConfigDetails": "Non è stato possibile aggiornare le impostazioni dell'app. Errore: %s.", + "loc.messages.UnableToGetAzureRMWebAppMetadata": "Non è stato possibile recuperare i metadati dell'app Web AzureRM. Codice errore: %s", + "loc.messages.UnableToUpdateAzureRMWebAppMetadata": "Non è possibile aggiornare i metadati dell'app Web di AzureRM. Codice errore: %s", + "loc.messages.Unabletoretrieveazureregistrycredentials": "Non è possibile recuperare le credenziali del Registro contenitori di Azure. [Codice di stato: '%s']", + "loc.messages.UnableToReadResponseBody": "Non è possibile leggere il corpo della risposta. Errore: %s", + "loc.messages.UnableToUpdateWebAppConfigDetails": "Non è possibile aggiornare i dettagli di configurazione dell'app Web. Codice di stato: '%s'", + "loc.messages.AddingReleaseAnnotation": "Aggiunta dell'annotazione versione per la risorsa '%s' di Application Insights", + "loc.messages.SuccessfullyAddedReleaseAnnotation": "L'annotazione versione è stata aggiunta alla risorsa di Application Insights: %s", + "loc.messages.FailedAddingReleaseAnnotation": "Non è stato possibile aggiungere l'annotazione versione. %s", + "loc.messages.RenameLockedFilesEnabled": "La ridenominazione dei file bloccati è abilitata per il servizio app.", + "loc.messages.FailedToEnableRenameLockedFiles": "Non è stato possibile abilitare la ridenominazione de file bloccati. Errore: %s", + "loc.messages.WebJobsInProgressIssue": "Qualche processo Web nello stato in esecuzione impedisce alla distribuzione di rimuovere i file. È possibile disabilitare l'opzione 'Rimuovi file aggiuntivi nella destinazione' oppure arrestare i processi continui prima della distribuzione.", + "loc.messages.FailedToFetchKuduAppSettings": "Non è stato possibile recuperare le impostazioni dell'app Kudu. Errore: %s", + "loc.messages.FailedToCreatePath": "Non è stato possibile creare il percorso '%s' da Kudu. Errore: %s", + "loc.messages.FailedToDeleteFile": "Non è stato possibile eliminare il file '%s/%s' da Kudu. Errore: %s", + "loc.messages.FailedToUploadFile": "Non è stato possibile caricare il file '%s/%s' da Kudu. Errore: %s", + "loc.messages.FailedToGetFileContent": "Non è stato possibile ottenere il contenuto '%s/%s' del file da Kudu. Errore: %s", + "loc.messages.FailedToListPath": "Non è stato possibile elencare il percorso '%s' da Kudu. Errore: %s", + "loc.messages.RetryToDeploy": "Verrà effettuato un nuovo tentativo di distribuzione del pacchetto.", + "loc.messages.FailedToGetAppServiceDetails": "Non è stato possibile recuperare i dettagli del servizio app '%s'. Errore: %s", + "loc.messages.FailedToGetAppServicePublishingProfile": "Non è stato possibile recuperare il profilo di pubblicazione del servizio app '%s'. Errore: %s", + "loc.messages.FailedToUpdateAppServiceMetadata": "Non è stato possibile aggiornare i metadati del servizio app '%s'. Errore: %s", + "loc.messages.FailedToGetAppServiceMetadata": "Non è stato possibile ottenere i metadati del servizio app '%s'. Errore: %s", + "loc.messages.FailedToPatchAppServiceConfiguration": "Non è stato possibile correggere la configurazione del servizio app '%s'. Errore: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Non è stato possibile aggiornare la configurazione del servizio app '%s'. Errore: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Non è stato possibile ottenere la configurazione del servizio app '%s'. Errore: %s", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Non è stato possibile recuperare le credenziali di pubblicazione del servizio app '%s'. Errore: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Non è stato possibile ottenere le impostazioni applicazione del servizio app '%s'. Errore: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Non è stato possibile aggiornare le impostazioni applicazione del servizio app '%s'. Errore: %s", + "loc.messages.UpdatingAppServiceConfigurationSettings": "Aggiornamento delle impostazioni di configurazione del servizio app. Dati: %s", + "loc.messages.UpdatedAppServiceConfigurationSettings": "Le impostazioni di configurazione del servizio app sono state aggiornate.", + "loc.messages.UpdatingAppServiceApplicationSettings": "Aggiornamento delle impostazioni applicazione del servizio app. Dati: %s", + "loc.messages.UpdatedAppServiceApplicationSettings": "Le impostazioni applicazione del servizio app e le impostazioni applicazione di Kudu sono state aggiornate.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Sono stati trovati più gruppi di risorse per il servizio app '%s'.", + "loc.messages.PackageDeploymentUsingZipDeployFailed": "La distribuzione del pacchetto con zipdeploy non è riuscita. Per maggiori dettagli, vedere i log.", + "loc.messages.PackageDeploymentInitiated": "La distribuzione del pacchetto con zipdeploy è stata avviata.", + "loc.messages.FailedToGetDeploymentLogs": "Non è stato possibile ottenere i log di distribuzione. Errore: %s", + "loc.messages.GoExeNameNotPresent": "Il nome dell'eseguibile Go non è presente", + "loc.messages.WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier." +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/ja-jp/resources.resjson b/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/ja-jp/resources.resjson new file mode 100644 index 000000000000..3268105066e5 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/ja-jp/resources.resjson @@ -0,0 +1,219 @@ +{ + "loc.friendlyName": "Azure App Service 配置", + "loc.helpMarkDown": "[詳細情報](https://aka.ms/azurermwebdeployreadme)", + "loc.description": "Windows 上の Azure WebApp サービス、ビルトイン イメージまたは docker コンテナーを使用する Linux 上の Web アプリ、ASP.NET、.NET Core、PHP、Python、Node ベースの Web アプリケーション、Web 配置 / Kudu REST API を使用する関数アプリ、モバイル アプリ、API アプリケーション、Web ジョブを更新します", + "loc.instanceNameFormat": "Azure App Service の配置: $(WebAppName)", + "loc.releaseNotes": "バージョン 3.0 の新機能:
  ファイル変換 (XDT) をサポート
   変数置換 (XML、JSON) をサポート
詳細については、[ここ](https://aka.ms/azurermwebdeployreadme) をクリックしてください。", + "loc.group.displayName.FileTransformsAndVariableSubstitution": "ファイルの変換と変数の置換のオプション", + "loc.group.displayName.AdditionalDeploymentOptions": "追加の配置オプション", + "loc.group.displayName.PostDeploymentAction": "配置後アクション", + "loc.group.displayName.ApplicationAndConfigurationSettings": "アプリケーションと構成の設定", + "loc.group.displayName.output": "出力", + "loc.input.label.ConnectedServiceName": "Azure サブスクリプション", + "loc.input.help.ConnectedServiceName": "デプロイ用の Azure Resource Manager サブスクリプションを選択します。", + "loc.input.label.WebAppKind": "アプリの種類", + "loc.input.help.WebAppKind": "配置する Web アプリの種類を選択します。
注: 組み込みのプラットフォーム イメージまたはカスタム コンテナー イメージの配置には、Linux Web アプリを選択します。", + "loc.input.label.WebAppName": "App Service の名前", + "loc.input.help.WebAppName": "既存の Azure App Service の名前を入力するか、選択します。選択するアプリの種類に基づく App Service のみが一覧表示されます。", + "loc.input.label.DeployToSlotFlag": "スロットへの配置", + "loc.input.help.DeployToSlotFlag": "運用スロット以外の既存のスロットに配置する場合、このオプションを選択します。このオプションを選択しないと、Azure App Service は運用スロットに配置されます。", + "loc.input.label.ResourceGroupName": "リソース グループ", + "loc.input.help.ResourceGroupName": "上で指定された Azure App Service が含まれる Azure リソース グループを入力または選択してください。", + "loc.input.label.SlotName": "スロット", + "loc.input.help.SlotName": "運用スロット以外の既存のスロットを入力または選択してください。", + "loc.input.label.ImageSource": "イメージ ソース", + "loc.input.help.ImageSource": "Linux 上の App Service には、アプリケーションを発行するための 2 つの異なるオプションが備わっています。
カスタム イメージの配置と、組み込みのプラットフォーム イメージを使ったアプリの配置です。[詳細](https://go.microsoft.com/fwlink/?linkid=862490)", + "loc.input.label.AzureContainerRegistry": "レジストリ", + "loc.input.help.AzureContainerRegistry": "特定のレジストリをグローバルに識別する一意の最上位ドメイン名です。
メモ: 完全修飾イメージ名の形式は '`<レジストリ`>/`<リポジトリ`>:`<タグ`>' です。例: 'myregistry.azurecr.io/nginx:latest'。", + "loc.input.label.AzureContainerRegistryLoginServer": "レジストリ ログイン サーバー名", + "loc.input.help.AzureContainerRegistryLoginServer": "Azure Container Registry のログイン サーバー名を入力するか、選択します。", + "loc.input.label.AzureContainerRegistryImage": "イメージ", + "loc.input.help.AzureContainerRegistryImage": "コンテナー イメージが格納されるリポジトリの名前。
メモ: 完全修飾イメージ名の形式は '`<レジストリ`>/`<リポジトリ`>:`<タグ`>' です。例: 'myregistry.azurecr.io/nginx:latest'。", + "loc.input.label.AzureContainerRegistryTag": "タグ", + "loc.input.help.AzureContainerRegistryTag": "タグは省略可能です。タグは、Docker イメージにバージョンを付けるためにレジストリで使用されるメカニズムです。
メモ: 完全修飾イメージ名の形式は '`<レジストリ`>/`<リポジトリ`>:`<タグ`>' です。例: 'myregistry.azurecr.io/nginx:latest'。", + "loc.input.label.DockerRepositoryAccess": "リポジトリ アクセス", + "loc.input.help.DockerRepositoryAccess": "Docker リポジトリ アクセスを選択します。", + "loc.input.label.RegistryConnectedServiceName": "レジストリ接続", + "loc.input.help.RegistryConnectedServiceName": "レジストリ接続を選択します。", + "loc.input.label.PrivateRegistryImage": "イメージ", + "loc.input.help.PrivateRegistryImage": "コンテナー イメージが格納されるリポジトリの名前。
メモ: 完全修飾イメージ名の形式は '`<レジストリ`>/`<リポジトリ`>:`<タグ`>' です。例: 'myregistry.azurecr.io/nginx:latest'。", + "loc.input.label.PrivateRegistryTag": "タグ", + "loc.input.help.PrivateRegistryTag": "タグは省略可能です。タグは、Docker イメージにバージョンを付けるためにレジストリで使用されるメカニズムです。
メモ: 完全修飾イメージ名の形式: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerNamespace": "レジストリまたは名前空間", + "loc.input.help.DockerNamespace": "特定のレジストリまたは名前空間をグローバルに識別する一意の最上位ドメイン名です。
メモ: 完全修飾イメージ名の形式は '`<レジストリまたは名前空間`>/`<リポジトリ`>:`<タグ`>' です。例: 'myregistry.azurecr.io/nginx:latest'。", + "loc.input.label.DockerRepository": "イメージ", + "loc.input.help.DockerRepository": "コンテナー イメージが格納されるリポジトリの名前です。
メモ: 完全修飾イメージ名の形式は '`<レジストリまたは名前空間`>/`<リポジトリ`>:`<タグ`>' です。例: 'myregistry.azurecr.io/nginx:latest'。", + "loc.input.label.DockerImageTag": "タグ", + "loc.input.help.DockerImageTag": "タグは省略可能です。これは、レジストリで Docker イメージにバージョンを付けるために使う機構です。
メモ: 完全修飾イメージ名の形式は '`<レジストリまたは名前空間`>/`<リポジトリ`>:`<タグ`>' です。例: 'myregistry.azurecr.io/nginx:latest'。", + "loc.input.label.VirtualApplication": "仮想アプリケーション", + "loc.input.help.VirtualApplication": "Azure Portal に構成された仮想アプリケーションの名前を指定します。App Service ルートに配置する場合には、このオプションは不要です。", + "loc.input.label.Package": "パッケージまたはフォルダー", + "loc.input.help.Package": "パッケージ、MSBuild で生成された App Service コンテンツが入ったフォルダー、圧縮された zip ファイルまたは war ファイルのいずれかへのファイル パス。
変数 ( [ビルド](https://www.visualstudio.com/docs/build/define/variables) | [リリース](https://www.visualstudio.com/docs/release/author-release-definition/understanding-tasks#predefvariables))、ワイルドカードがサポートされています。
例: $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip または $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war。", + "loc.input.label.BuiltinLinuxPackage": "パッケージまたはフォルダー", + "loc.input.help.BuiltinLinuxPackage": "パッケージ、MSBuild で生成された App Service コンテンツが入ったフォルダー、圧縮された zip ファイルまたは war ファイルのいずれかへのファイル パス。
変数 ( [ビルド](https://www.visualstudio.com/docs/build/define/variables) | [リリース](https://www.visualstudio.com/docs/release/author-release-definition/understanding-tasks#predefvariables))、ワイルドカードがサポートされています。
例: $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip または $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war。", + "loc.input.label.RuntimeStack": "ランタイム スタック", + "loc.input.help.RuntimeStack": "フレームワークとバージョンを選択します。", + "loc.input.label.StartupCommand": "スタートアップ コマンド ", + "loc.input.help.StartupCommand": "スタートアップ コマンドを入力します。", + "loc.input.label.WebAppUri": "App Service URL", + "loc.input.help.WebAppUri": "Azure App Service の URL に対して生成される出力変数の名前を指定します。この変数は後続のタスクで使用できます。", + "loc.input.label.ScriptType": "配置スクリプトの種類", + "loc.input.help.ScriptType": "タスクで配置が正常に完了したときに Azure App Service 上で実行されるスクリプトを提供して、配置をカスタマイズします。たとえば、Node、PHP、Python アプリケーション用のパッケージを復元します。[詳細](https://go.microsoft.com/fwlink/?linkid=843471)。", + "loc.input.label.InlineScript": "インライン スクリプト", + "loc.input.label.ScriptPath": "配置スクリプトのパス", + "loc.input.label.GenerateWebConfig": "Web.config の生成", + "loc.input.help.GenerateWebConfig": "アプリケーションに web.config がない場合は、標準の web.config が生成され、Azure App Service に配置されます。web.config 内の値は編集可能で、アプリケーション フレームワークに基づいて変えることができます。たとえば、node.js アプリケーションの場合、スタートアップ ファイルと iis_node モジュールの値を web.config 内に設定します。[詳細](https://go.microsoft.com/fwlink/?linkid=843469)。", + "loc.input.label.WebConfigParameters": "Web.config のパラメーター", + "loc.input.help.WebConfigParameters": "生成された web.config ファイル内のスタートアップ ファイルなどの値を編集します。この編集機能は、生成された web.config 専用です。[詳細](https://go.microsoft.com/fwlink/?linkid=843469)。", + "loc.input.label.AppSettings": "アプリ設定", + "loc.input.help.AppSettings": "構文 -key value の後に続く Web App アプリケーションの設定を編集します。スペースが含まれる値は二重引用符で囲む必要があります。
: -Port 5000 -RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Eastern Standard Time\"", + "loc.input.label.ConfigurationSettings": "構成設定", + "loc.input.help.ConfigurationSettings": "構文 -key value の後に続く Web App 構成の設定を編集します。スペースが含まれる値は、二重引用符で囲む必要があります。
例: -phpVersion 5.6 -linuxFxVersion: node|6.11", + "loc.input.label.TakeAppOfflineFlag": "アプリをオフラインにする", + "loc.input.help.TakeAppOfflineFlag": "Azure App Service をオフラインにする場合、このオプションを選択します。オフラインにするには、同期操作を開始する前に App Service のルート ディレクトリに app_offline.htm ファイルを配置します。このファイルは、同期操作が正常に完了すると削除されます。", + "loc.input.label.UseWebDeploy": "Web 配置による公開", + "loc.input.help.UseWebDeploy": "Web 配置オプションを使用する公開は、Windows エージェントを使用している場合のみサポートされます。その他のプラットフォームでは、Azure App Service を配置するタスクは [Kudu REST API](https://github.com/projectkudu/kudu/wiki/REST-API) に依存しており、次のオプションはサポートされません", + "loc.input.label.SetParametersFile": "SetParameters ファイル", + "loc.input.help.SetParametersFile": "省略可能: 使用する SetParameters.xml ファイルの場所。", + "loc.input.label.RemoveAdditionalFilesFlag": "ターゲットで追加ファイルを削除する", + "loc.input.help.RemoveAdditionalFilesFlag": "App Service パッケージまたはフォルダー内に一致するファイルがない Azure App Service 上のファイルを削除する場合、このオプションを選択します。

注: これにより、この Azure App Service にインストールされたあらゆる拡張機能に関連するファイルも全部削除されます。これを避けるには、[App_Data フォルダーのファイルを除外する] チェックボックスを選択します。", + "loc.input.label.ExcludeFilesFromAppDataFlag": "App_Data フォルダーのファイルを除外する", + "loc.input.help.ExcludeFilesFromAppDataFlag": "App_Data フォルダー内のファイルが Azure App Service に配置されないようにする場合、このオプションを選択します。", + "loc.input.label.AdditionalArguments": "追加引数", + "loc.input.help.AdditionalArguments": "構文 -key:value に続くその他の Web 配置の引数。
これらの引数は、Azure App Service を配置するときに適用されます。例: -disableLink:AppPoolExtension -disableLink:ContentExtension。
Web 配置操作の設定に関するその他の例については、[ここ](https://go.microsoft.com/fwlink/?linkid=838471) を参照してください。", + "loc.input.label.RenameFilesFlag": "ロックされたファイルの名前を変更する", + "loc.input.help.RenameFilesFlag": "Azure App Service のアプリケーション設定で msdeploy フラグ FLAGMSDEPLOY_RENAME_LOCKED_FILES=1 を有効にするには、このオプションを選択します。このオプションを設定すると、アプリの配置中にロックされたファイルの名前を MSDeploy で変更できるようになります", + "loc.input.label.XmlTransformation": "XML 変換", + "loc.input.help.XmlTransformation": "`*.config ファイル` 上の `*.Release.config` と `*..config` に対する構成変換が実行されます。
構成変換は変数置換の前に実行されます。
XML 変換は、Windows プラットフォームの場合のみサポートされます。", + "loc.input.label.XmlVariableSubstitution": "XML 変数置換", + "loc.input.help.XmlVariableSubstitution": "ビルドまたはリリース定義内で定義されている変数が、構成ファイルおよび parameters.xml の appSettings、applicationSettings、connectionStrings セクション内の 'key' または 'name' エントリに対して照合されます。変数置換は構成変換の後に実行されます。

メモ: リリース定義と環境で同じ変数が定義されている場合、環境変数の方がリリース定義変数より優先されます。
", + "loc.input.label.JSONFiles": "JSON 変数置換", + "loc.input.help.JSONFiles": "JSON ファイルの行区切り一覧を新しく提供して、変数値を置換します。ルート フォルダーの相対ファイル名を提供します。
入れ子または階層の JSON 変数を置換するには、JSONPath 式を使用して指定します。

たとえば、下のサンプル内の ‘ConnectionString’ 値を置き換えるには、ビルド/リリース定義 (またはリリース定義の環境) 内で変数を ‘Data.DefaultConnection.ConnectionString’ として定義する必要があります。
{
  \"Data\": {
    \"DefaultConnection\": {
      \"ConnectionString\": \"Server=(localdb)\\SQLEXPRESS;Database=MyDB;Trusted_Connection=True\"
    }
  }
}
変数置換は構成変換の後に実行されます。

メモ: 置換では、ビルド/リリースのシステム定義変数は除外されます", + "loc.messages.Invalidwebapppackageorfolderpathprovided": "無効な App Service パッケージまたはフォルダー パスが指定されました: %s", + "loc.messages.SetParamFilenotfound0": "Set パラメーター ファイルが見つかりません: %s", + "loc.messages.XDTTransformationsappliedsuccessfully": "XML 変換が正常に適用されました", + "loc.messages.GotconnectiondetailsforazureRMWebApp0": "Azure App Service の接続の詳細を取得しました: '%s'", + "loc.messages.ErrorNoSuchDeployingMethodExists": "エラー: そのような配置方法はありません", + "loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp": "Azure App Service の接続の詳細を取得できません: %s。状態コード: %s (%s)", + "loc.messages.UnabletoretrieveResourceID": "Azure リソース '%s' の接続の詳細を取得できません。状態コード: %s", + "loc.messages.CouldnotfetchaccesstokenforAzureStatusCode": "Azure のアクセス トークンをフェッチできませんでした。状態コード: %s (%s)", + "loc.messages.Successfullyupdateddeploymenthistory": "配置履歴が %s で正常に更新されました", + "loc.messages.Failedtoupdatedeploymenthistory": "配置履歴を更新できませんでした。エラー: %s", + "loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "警告: 配置状態を更新できません: この Web サイトでは SCM エンドポイントが有効になっていません", + "loc.messages.Unabletoretrievewebconfigdetails": "App Service の構成の詳細を取得できません。状態コード: '%s'", + "loc.messages.Unabletoretrievewebappsettings": "App Service のアプリケーションの設定を取得できません。[状態コード: '%s'、エラー メッセージ: '%s']", + "loc.messages.Unabletoupdatewebappsettings": "App Service のアプリケーションの設定を更新できません。状態コード: '%s'", + "loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "配置の状態を更新できません: 一意の配置 ID を取得できません", + "loc.messages.PackageDeploymentSuccess": "Web パッケージを App Service に正常に配置できました。", + "loc.messages.PackageDeploymentFailed": "Web パッケージを App Service に配置できませんでした。", + "loc.messages.Runningcommand": "コマンドを実行しています: %s", + "loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath": "Web パッケージ: %s を仮想パス (物理パス) へ配置しています: %s (%s)", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "kudu サービスにより、パッケージ %s が %s に配置されました", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Kudu サービスを使用して App Service パッケージをデプロイできませんでした: %s", + "loc.messages.Unabletodeploywebappresponsecode": "エラー コードにより、App Service を配置できません: %s", + "loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "MSDeploy が生成したパッケージは Windows プラットフォームでのみサポートされます。", + "loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "MSDeploy のサポートされていないバージョン: %s がインストールされています。バージョンは 3 以降である必要があります", + "loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError": "コンピューター上のレジストリから、MS Deploy の場所を特定できません (エラー: %s)", + "loc.messages.Nopackagefoundwithspecifiedpattern": "指定したパターンのパッケージが見つかりませんでした: %s", + "loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "指定したパターンと一致するパッケージが複数あります: %s。検索パターンを絞り込んでください。", + "loc.messages.Trytodeploywebappagainwithappofflineoptionselected": "[アプリケーションをオフラインにする] オプションを選択して、もう一度 App Service を配置してください。", + "loc.messages.Trytodeploywebappagainwithrenamefileoptionselected": "[ロックされたファイルの名前を変更する] オプションを選択して、もう一度 App Service を配置してください。", + "loc.messages.NOJSONfilematchedwithspecificpattern": "指定のパターンと一致する JSON ファイルはありません: %s。", + "loc.messages.Configfiledoesntexists": "構成ファイル %s がありません。", + "loc.messages.Failedtowritetoconfigfilewitherror": "構成ファイル %s への書き込みに失敗しました。エラー: %s", + "loc.messages.AppOfflineModeenabled": "アプリのオフライン モードが有効です。", + "loc.messages.Failedtoenableappofflinemode": "アプリのオフライン モードを有効にできませんでした。状態コード: %s (%s)", + "loc.messages.AppOflineModedisabled": "アプリのオフライン モードが無効です。", + "loc.messages.FailedtodisableAppOfflineMode": "アプリのオフライン モードを無効にできませんでした。状態コード: %s (%s)", + "loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform": "非 Windows プラットフォームでは XML 変換を実行できません。", + "loc.messages.XdtTransformationErrorWhileTransforming": "%s の %s による変換中に XML 変換エラーが発生しました。", + "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Web 配置オプションによる公開は、Windows エージェントを使用している場合のみサポートされます", + "loc.messages.ResourceDoesntExist": "リソース '%s' がありません。リソースは配置前に存在している必要があります。", + "loc.messages.EncodeNotSupported": "ファイル %s のファイル エンコードが %s として検出されました。ファイル エンコード %s では変数置換はサポートされていません。サポートされているエンコードは UTF-8 と UTF-16 LE です。", + "loc.messages.UnknownFileEncodeError": "ファイル %s (typeCode: %s) のエンコードを検出できません。サポートされているエンコードは UTF-8 および UTF-16 LE です。", + "loc.messages.ShortFileBufferError": "ファイル バッファーが短すぎてエンコードの種類を検出できません: %s", + "loc.messages.FailedToUpdateAzureRMWebAppConfigDetails": "App Service 構成の詳細を更新できませんでした。エラー: %s", + "loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails": "App Service 構成の詳細が正常に更新されました", + "loc.messages.RequestedURLforkuduphysicalpath": "Kudu 物理パスに関して URL が要求されました: %s", + "loc.messages.Physicalpathalreadyexists": "物理パス '%s' は既に存在しています", + "loc.messages.KuduPhysicalpathCreatedSuccessfully": "Kudu 物理パスが正常に作成されました: %s", + "loc.messages.FailedtocreateKuduPhysicalPath": "Kudu 物理パスを作成することができませんでした。エラー: %s", + "loc.messages.FailedtocheckphysicalPath": "Kudu 物理パスを確認できませんでした。エラー コード: %s", + "loc.messages.VirtualApplicationDoesNotExist": "仮想アプリケーションがありません: %s", + "loc.messages.JSONParseError": "JSON ファイルを解析できません: %s。エラー: %s", + "loc.messages.JSONvariablesubstitutionappliedsuccessfully": "JSON 変数置換が正常に適用されました。", + "loc.messages.XMLvariablesubstitutionappliedsuccessfully": "XML 変数の置換が正常に適用されました。", + "loc.messages.failedtoUploadFileToKudu": "ファイル %s を Kudu (%s) にアップロードできません。状態コード: %s", + "loc.messages.failedtoUploadFileToKuduError": "ファイル %s を Kudu (%s) にアップロードできません。エラー: %s", + "loc.messages.ExecuteScriptOnKudu": "指定されたスクリプトを Kudu サービス上で実行しています。", + "loc.messages.FailedToRunScriptOnKuduError": "スクリプトを Kudu サービス上で実行できません。エラー: %s", + "loc.messages.FailedToRunScriptOnKudu": "スクリプトを Kudu (%s) 上で実行できません。状態コード: %s", + "loc.messages.ScriptExecutionOnKuduSuccess": "スクリプトを Kudu 上で正常に実行できました。", + "loc.messages.ScriptExecutionOnKuduFailed": "実行したスクリプトからリターン コードとして '%s' が返されました。エラー: %s", + "loc.messages.FailedtoDeleteFileFromKudu": "ファイル %s を Kudu (%s) から削除できません。状態コード: %s", + "loc.messages.FailedtoDeleteFileFromKuduError": "ファイル %s を Kudu (%s) から削除できません。エラー: %s", + "loc.messages.ScriptFileNotFound": "スクリプト ファイル '%s' が見つかりません。", + "loc.messages.InvalidScriptFile": "無効なスクリプト ファイル '%s' が指定されました。有効な拡張子は、Windows の場合は .bat と .cmd、Linux の場合は .sh です", + "loc.messages.RetryForTimeoutIssue": "タイムアウトの問題でスクリプトを実行できませんでした。もう一度お試しください。", + "loc.messages.stdoutFromScript": "スクリプトからの標準出力: ", + "loc.messages.stderrFromScript": "スクリプトからの標準エラー出力: ", + "loc.messages.WebConfigAlreadyExists": "web.config ファイルは既に存在します。生成しません。", + "loc.messages.SuccessfullyGeneratedWebConfig": "web.config ファイルを正常に生成できました", + "loc.messages.FailedToGenerateWebConfig": "web.config を生成できませんでした。%s", + "loc.messages.FailedToGetKuduFileContent": "ファイルの内容を取得できません: %s。状態コード: %s (%s)", + "loc.messages.FailedToGetKuduFileContentError": "ファイルの内容を取得できません: %s。エラー: %s", + "loc.messages.ScriptStatusTimeout": "タイムアウトのため、スクリプトの状態をフェッチできません。", + "loc.messages.PollingForFileTimeOut": "タイムアウトのため、スクリプトの状態をフェッチできません。タイムアウト制限を延長するには、'appservicedeploy.retrytimeout' 変数を必要な時間 (分) に設定します。", + "loc.messages.InvalidPollOption": "指定されたポーリング オプションが無効です: %s。", + "loc.messages.MissingAppTypeWebConfigParameters": "属性 '-appType' が Web.config パラメーターにありません。'-appType' に対して有効な値は、'python_Bottle'、'python_Django'、'python_Flask'、'node' です。
たとえば、Python Bottle フレームワークの場合は、'-appType python_Bottle' (sans-quotes) を指定します。", + "loc.messages.AutoDetectDjangoSettingsFailed": "DJANGO_SETTINGS_MODULE の 'settings.py' ファイル パスを検出できません。'settings.py' ファイルが存在することを確認するか、次の形式で Web.config パラメーター入力に正しいパスを指定してください: '-DJANGO_SETTINGS_MODULE .settings'", + "loc.messages.FailedToApplyTransformation": "指定されたパッケージに変換を適用することはできません。次の点をご確認ください。", + "loc.messages.FailedToApplyTransformationReason1": "1. ビルド中、MSBuild によって生成されたパッケージに対して変換が既に適用されたかどうか。適用された場合は、csproj ファイル内の各構成の タグを削除してから、リビルドします。", + "loc.messages.FailedToApplyTransformationReason2": "2. 構成ファイルと変換ファイルがパッケージ内の同じフォルダーに存在すること。", + "loc.messages.AutoParameterizationMessage": "Web.config の ConnectionString 属性は既定でパラメーター化されています。'Parameters.xml' ファイルまたは 'SetParameters.xml' ファイルによって値が配置中に上書きされるため、変換が connectionString 属性に影響を与えることはありません。自動パラメーター化は、MSBuild パッケージの生成中に /p:AutoParameterizationWebConfigConnectionStrings=False のように設定することによって無効にできます。", + "loc.messages.UnsupportedAppType": "アプリの種類 '%s' が Web.config 生成でサポートされていません。'-appType' に対して有効な値は、'python_Bottle'、'python_Django'、'python_Flask'、'node' です。", + "loc.messages.UnableToFetchAuthorityURL": "機関の URL をフェッチできません。", + "loc.messages.UnableToFetchActiveDirectory": "Active Directory リソース ID をフェッチできません。", + "loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand": "ランタイム スタックとスタートアップ コマンドが正常に更新されました。", + "loc.messages.FailedToUpdateRuntimeStackAndStartupCommand": "ランタイム スタックとスタートアップ コマンドの更新に失敗しました。エラー: %s。", + "loc.messages.SuccessfullyUpdatedWebAppSettings": "アプリの設定が正常に更新されました。", + "loc.messages.FailedToUpdateAppSettingsInConfigDetails": "アプリ設定の更新に失敗しました。エラー: %s。", + "loc.messages.UnableToGetAzureRMWebAppMetadata": "AzureRM WebApp メタデータをフェッチできませんでした。ErrorCode: %s", + "loc.messages.UnableToUpdateAzureRMWebAppMetadata": "AzureRM WebApp メタデータを更新できません。エラー コード: %s", + "loc.messages.Unabletoretrieveazureregistrycredentials": "Azure Container Registry の資格情報を取得できません。[状態コード: '%s']", + "loc.messages.UnableToReadResponseBody": "応答本文を読み取ることができません。エラー: %s", + "loc.messages.UnableToUpdateWebAppConfigDetails": "WebApp 構成の詳細を更新できません。StatusCode: '%s'", + "loc.messages.AddingReleaseAnnotation": "Application Insights リソース ’%s’ のリリース コメントを追加しています", + "loc.messages.SuccessfullyAddedReleaseAnnotation": "Application Insight にリリース コメントが正常に追加されました: %s", + "loc.messages.FailedAddingReleaseAnnotation": "リリース コメントを追加できませんでした。%s", + "loc.messages.RenameLockedFilesEnabled": "App Service で [ロックされたファイルの名前を変更する] が有効です。", + "loc.messages.FailedToEnableRenameLockedFiles": "[ロックされたファイルの名前を変更する] を有効にできませんでした。エラー: %s", + "loc.messages.WebJobsInProgressIssue": "実行状態の Web ジョブが少数あり、配置でファイルを削除できません。[ターゲットで追加ファイルを削除する] オプションを無効にするか、継続中のジョブを配置の前に停止できます。", + "loc.messages.FailedToFetchKuduAppSettings": "Kudu アプリ設定をフェッチできませんでした。エラー: %s", + "loc.messages.FailedToCreatePath": "Kudu からパス '%s' を作成することができませんでした。エラー: %s", + "loc.messages.FailedToDeleteFile": "Kudu からファイル '%s/%s' を削除することができませんでした。エラー: %s", + "loc.messages.FailedToUploadFile": "Kudu からファイル '%s/%s' をアップロードできませんでした。エラー: %s", + "loc.messages.FailedToGetFileContent": "Kudu からファイル コンテンツ '%s/%s' を取得できませんでした。エラー: %s", + "loc.messages.FailedToListPath": "Kudu からパス '%s' の一覧を取得できませんでした。エラー: %s", + "loc.messages.RetryToDeploy": "パッケージの配置を再試行しています。", + "loc.messages.FailedToGetAppServiceDetails": "App Service '%s' の詳細をフェッチできませんでした。エラー: %s", + "loc.messages.FailedToGetAppServicePublishingProfile": "App Service '%s' の発行プロファイルをフェッチできませんでした。エラー: %s", + "loc.messages.FailedToUpdateAppServiceMetadata": "App Service '%s' のメタデータの更新に失敗しました。エラー: %s", + "loc.messages.FailedToGetAppServiceMetadata": "App Service '%s' のメタデータの取得に失敗しました。エラー: %s", + "loc.messages.FailedToPatchAppServiceConfiguration": "App Service '%s' の構成を修正できませんでした。エラー: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "App Service '%s' 構成を更新できませんでした。エラー: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "App Service '%s' 構成を取得できませんでした。エラー: %s", + "loc.messages.FailedToGetAppServicePublishingCredentials": "App Service '%s' の発行資格情報をフェッチできませんでした。エラー: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "App Service '%s' アプリケーション設定を取得できませんでした。エラー: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "App Service '%s' アプリケーション設定を更新できませんでした。エラー: %s", + "loc.messages.UpdatingAppServiceConfigurationSettings": "App Service 構成の設定を更新しています。データ: %s", + "loc.messages.UpdatedAppServiceConfigurationSettings": "App Service 構成の設定が更新されました。", + "loc.messages.UpdatingAppServiceApplicationSettings": "App Service アプリケーション設定を更新しています。データ: %s", + "loc.messages.UpdatedAppServiceApplicationSettings": "App Service アプリケーション設定と Kudu アプリケーション設定が更新されました。", + "loc.messages.MultipleResourceGroupFoundForAppService": "App Service '%s' に複数のリソース グループが見つかりました。", + "loc.messages.PackageDeploymentUsingZipDeployFailed": "ZIP 配置を使用したパッケージ配置に失敗しました。詳細についてはログを参照してください。", + "loc.messages.PackageDeploymentInitiated": "ZIP 配置を使用したパッケージ配置を開始しました。", + "loc.messages.FailedToGetDeploymentLogs": "配置ログを取得できませんでした。エラー: %s", + "loc.messages.GoExeNameNotPresent": "Go exe 名が存在しません", + "loc.messages.WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier." +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/ko-KR/resources.resjson b/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/ko-KR/resources.resjson new file mode 100644 index 000000000000..a49262d066a7 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/ko-KR/resources.resjson @@ -0,0 +1,219 @@ +{ + "loc.friendlyName": "Azure App Service 배포", + "loc.helpMarkDown": "[자세한 정보](https://aka.ms/azurermwebdeployreadme)", + "loc.description": "웹 배포/Kudu REST API를 사용하여 Windows의 Azure WebApp Services, 기본 제공 이미지 또는 Docker 컨테이너를 포함하는 Linux의 웹앱, ASP.NET, .NET Core, PHP, Python 또는 노드 기반 웹 응용 프로그램, Function Apps, Mobile Apps, API 응용 프로그램, 웹 작업 업데이트", + "loc.instanceNameFormat": "Azure App Service 배포: $(WebAppName)", + "loc.releaseNotes": "버전 3.0의 새로운 기능:
  파일 변환 지원(XDT)
  변수 대체 지원(XML, JSON)
자세한 내용을 보려면 [여기](https://aka.ms/azurermwebdeployreadme)를 클릭하세요.", + "loc.group.displayName.FileTransformsAndVariableSubstitution": "파일 변환 및 변수 대체 옵션", + "loc.group.displayName.AdditionalDeploymentOptions": "추가 배포 옵션", + "loc.group.displayName.PostDeploymentAction": "배포 후 작업", + "loc.group.displayName.ApplicationAndConfigurationSettings": "응용 프로그램 및 구성 설정", + "loc.group.displayName.output": "출력", + "loc.input.label.ConnectedServiceName": "Azure 구독", + "loc.input.help.ConnectedServiceName": "배포에 대한 Azure Resource Manager 구독을 선택합니다.", + "loc.input.label.WebAppKind": "앱 유형", + "loc.input.help.WebAppKind": "배포할 웹앱 유형을 선택합니다.
참고: 기본 제공 플랫폼 이미지 또는 사용자 지정 컨테이너 이미지 배포에 사용할 Linux 웹앱을 선택합니다.", + "loc.input.label.WebAppName": "App Service 이름", + "loc.input.help.WebAppName": "기존 Azure App Service의 이름을 입력하거나 선택합니다. 선택한 앱 유형을 기반으로 하는 앱 서비스만 나열됩니다.", + "loc.input.label.DeployToSlotFlag": "슬롯에 배포", + "loc.input.help.DeployToSlotFlag": "프로덕션 슬롯이 아닌 기존 슬롯에 배포하는 옵션을 선택합니다. 이 옵션을 선택하지 않으면 Azure App Service가 프로덕션 슬롯에 배포됩니다.", + "loc.input.label.ResourceGroupName": "리소스 그룹", + "loc.input.help.ResourceGroupName": "위에 지정된 Azure App Service를 포함하는 Azure 리소스 그룹을 입력하거나 선택합니다.", + "loc.input.label.SlotName": "슬롯", + "loc.input.help.SlotName": "프로덕션 슬롯이 아닌 기존 슬롯을 입력하거나 선택합니다.", + "loc.input.label.ImageSource": "이미지 소스", + "loc.input.help.ImageSource": "Linux의 App Service는 응용 프로그램을 게시하는 두 가지 옵션을 제공합니다.
해당 옵션은 사용자 지정 이미지 배포 또는 기본 제공 플랫폼 이미지를 사용하는 앱 배포입니다. [자세한 정보](https://go.microsoft.com/fwlink/?linkid=862490)", + "loc.input.label.AzureContainerRegistry": "레지스트리", + "loc.input.help.AzureContainerRegistry": "특정 레지스트리의 전역적으로 고유한 최상위 도메인 이름입니다.
참고: 정규화된 이미지 이름은 '`<레지스트리`>/`<리포지토리`>:`<태그`>' 형식입니다. 예: 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.AzureContainerRegistryLoginServer": "레지스트리 로그인 서버 이름", + "loc.input.help.AzureContainerRegistryLoginServer": "Azure Container Registry 로그인 서버 이름을 입력하거나 선택합니다.", + "loc.input.label.AzureContainerRegistryImage": "이미지", + "loc.input.help.AzureContainerRegistryImage": "컨테이너 이미지가 저장된 리포지토리의 이름입니다.
참고: 정규화된 이미지 이름은 '`<레지스트리`>/`<리포지토리`>:`<태그`>' 형식입니다. 예: 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.AzureContainerRegistryTag": "태그", + "loc.input.help.AzureContainerRegistryTag": "태그는 선택 사항으로, 레지스트리에서 Docker 이미지에 버전을 지정하는 데 사용하는 메커니즘입니다.
참고: 정규화된 이미지 이름은 '`<레지스트리`>/`<리포지토리`>:`<태그`>' 형식입니다. 예: 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerRepositoryAccess": "리포지토리 액세스", + "loc.input.help.DockerRepositoryAccess": "Docker 리포지토리 액세스를 선택합니다.", + "loc.input.label.RegistryConnectedServiceName": "레지스트리 연결", + "loc.input.help.RegistryConnectedServiceName": "레지스트리 연결을 선택합니다.", + "loc.input.label.PrivateRegistryImage": "이미지", + "loc.input.help.PrivateRegistryImage": "컨테이너 이미지가 저장된 리포지토리의 이름입니다.
참고: 정규화된 이미지 이름은 '`<레지스트리`>/`<리포지토리`>:`<태그`>' 형식입니다. 예: 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.PrivateRegistryTag": "태그", + "loc.input.help.PrivateRegistryTag": "태그는 선택 사항으로, 레지스트리에서 Docker 이미지에 버전을 지정하는 데 사용하는 메커니즘입니다.
참고: 정규화된 이미지 이름은 '`<레지스트리`>/`<리포지토리`>:`<태그`>' 형식입니다. 예: 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerNamespace": "레지스트리 또는 네임스페이스", + "loc.input.help.DockerNamespace": "특정 레지스트리 또는 네임스페이스의 전역적으로 고유한 최상위 도메인 이름입니다.
참고: 정규화된 이미지 이름은 '`<레지스트리 또는 네임스페이스`>/`<리포지토리`>:`<태그`>' 형식입니다. 예: 'myregistry.azurecr.io/nginx:latest'", + "loc.input.label.DockerRepository": "이미지", + "loc.input.help.DockerRepository": "컨테이너 이미지가 저장된 리포지토리의 이름입니다.
참고: 정규화된 이미지 이름은 '`<레지스트리 또는 네임스페이스`>/`<리포지토리`>:`<태그`>' 형식입니다. 예: 'myregistry.azurecr.io/nginx:latest'", + "loc.input.label.DockerImageTag": "태그", + "loc.input.help.DockerImageTag": "태그는 선택 사항입니다. 태그는 레지스트리에서 Docker 이미지에 버전을 지정하는 데 사용하는 메커니즘입니다.
참고: 정규화된 이미지 이름은 '`<레지스트리 또는 네임스페이스`>/`<리포지토리`>:`<태그`>' 형식입니다. 예: 'myregistry.azurecr.io/nginx:latest'", + "loc.input.label.VirtualApplication": "가상 응용 프로그램", + "loc.input.help.VirtualApplication": "Azure Portal에서 구성된 가상 응용 프로그램의 이름을 지정합니다. App Service 루트에 배포할 경우 이 옵션은 필요하지 않습니다.", + "loc.input.label.Package": "패키지 또는 폴더", + "loc.input.help.Package": "MSBuild에서 생성된 앱 서비스 콘텐츠를 포함하는 패키지 또는 폴더나 압축된 zip 또는 war 파일의 파일 경로입니다.
변수([빌드](https://www.visualstudio.com/docs/build/define/variables) | [릴리스](https://www.visualstudio.com/docs/release/author-release-definition/understanding-tasks#predefvariables)), 와일드카드가 지원됩니다.
예: $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip 또는 $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.BuiltinLinuxPackage": "패키지 또는 폴더", + "loc.input.help.BuiltinLinuxPackage": "MSBuild에서 생성된 앱 서비스 콘텐츠를 포함하는 패키지 또는 폴더나 압축된 zip 또는 war 파일의 파일 경로입니다.
변수([빌드](https://www.visualstudio.com/docs/build/define/variables) | [릴리스](https://www.visualstudio.com/docs/release/author-release-definition/understanding-tasks#predefvariables)), 와일드카드가 지원됩니다.
예: $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip 또는 $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.RuntimeStack": "런타임 스택", + "loc.input.help.RuntimeStack": "프레임워크 및 버전을 선택합니다.", + "loc.input.label.StartupCommand": "시작 명령 ", + "loc.input.help.StartupCommand": "시작 명령을 입력합니다.", + "loc.input.label.WebAppUri": "App Service URL", + "loc.input.help.WebAppUri": "Azure App Service의 URL에 대해 생성되는 출력 변수의 이름을 지정합니다. 이 변수는 후속 작업에서 사용될 수 있습니다.", + "loc.input.label.ScriptType": "배포 스크립트 형식", + "loc.input.help.ScriptType": "작업이 배포를 완료한 후 Azure App Service에서 실행할 스크립트를 제공하여 배포를 사용자 지정합니다. 예를 들어 노드, PHP, Python 응용 프로그램용 패키지를 복원합니다. [자세한 정보](https://go.microsoft.com/fwlink/?linkid=843471).", + "loc.input.label.InlineScript": "인라인 스크립트", + "loc.input.label.ScriptPath": "배포 스크립트 경로", + "loc.input.label.GenerateWebConfig": "Web.config 생성", + "loc.input.help.GenerateWebConfig": "응용 프로그램에 표준 Web.config가 없는 경우 생성되고 Azure App Service에 배포됩니다. web.config의 값은 편집할 수 있으며 응용 프로그램 프레임워크에 따라 달라집니다. 예를 들어 node.js 응용 프로그램의 경우 web.config에는 시작 파일과 iis_node 모듈 값이 있습니다. [자세한 정보](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.WebConfigParameters": "Web.config 매개 변수", + "loc.input.help.WebConfigParameters": "생성된 web.config 파일에서 시작 파일과 같은 값을 편집합니다. 이 편집 기능은 생성된 web.config에만 사용하도록 설계되었습니다. [자세한 정보](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.AppSettings": "앱 설정", + "loc.input.help.AppSettings": "구문 -key 값 다음에 오는 웹앱 응용 프로그램 설정을 편집합니다. 공백이 포함되는 값은 큰따옴표로 묶어야 합니다.
: -Port 5000 -RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Eastern Standard Time\"", + "loc.input.label.ConfigurationSettings": "구성 설정", + "loc.input.help.ConfigurationSettings": "구문 -key 값 다음에 오는 웹앱 구성 설정을 편집합니다. 공백이 포함되는 값은 큰따옴표로 묶어야 합니다.
예 : -phpVersion 5.6 -linuxFxVersion: node|6.11", + "loc.input.label.TakeAppOfflineFlag": "앱을 오프라인으로 전환", + "loc.input.help.TakeAppOfflineFlag": "동기화 작업이 시작되기 전에 App Service의 루트 디렉터리에 app_offline.htm 파일을 배치하여 Azure App Service를 오프라인 상태로 전환하려면 이 옵션을 선택합니다. 이 파일은 동기화 작업이 완료된 후 제거됩니다.", + "loc.input.label.UseWebDeploy": "웹 배포를 사용하여 게시", + "loc.input.help.UseWebDeploy": "웹 배포 옵션을 사용한 게시는 Windows 에이전트를 사용할 경우에만 지원됩니다. 다른 플랫폼에서는 작업에서 [Kudu REST API](https://github.com/projectkudu/kudu/wiki/REST-API)를 사용하여 Azure App Service를 배포하며 다음 옵션이 지원되지 않습니다.", + "loc.input.label.SetParametersFile": "SetParameters 파일", + "loc.input.help.SetParametersFile": "옵션: 사용할 SetParameters.xml 파일의 위치입니다.", + "loc.input.label.RemoveAdditionalFilesFlag": "대상에서 추가 파일 제거", + "loc.input.help.RemoveAdditionalFilesFlag": "App Service 패키지 또는 폴더에 일치하는 파일이 없는 Azure App Service의 파일을 삭제하는 옵션을 선택합니다.

참고: 이 경우 Azure App Service에 설치된 확장과 관련된 모든 파일도 제거됩니다. 이를 방지하려면 'App_Data 폴더에서 파일 제외' 확인란을 선택합니다. ", + "loc.input.label.ExcludeFilesFromAppDataFlag": "App_Data 폴더의 파일 제외", + "loc.input.help.ExcludeFilesFromAppDataFlag": "App_Data 폴더의 파일이 Azure App Service에 배포되지 않게 하려면 이 옵션을 선택합니다.", + "loc.input.label.AdditionalArguments": "추가 인수", + "loc.input.help.AdditionalArguments": "구문 -key:value 다음에 오는 추가 웹 배포 인수입니다.
이 인수는 Azure App Service를 배포할 때 적용됩니다. 예: -disableLink:AppPoolExtension -disableLink:ContentExtension.
웹 배포 작업 설정의 추가 예제는 [여기](https://go.microsoft.com/fwlink/?linkid=838471)를 참조하세요.", + "loc.input.label.RenameFilesFlag": "잠겨 있는 파일 이름 바꾸기", + "loc.input.help.RenameFilesFlag": "Azure App Service 응용 프로그램 설정에서 msdeploy 플래그 MSDEPLOY_RENAME_LOCKED_FILES=1을 사용하도록 설정하려면 이 옵션을 선택합니다. 이 옵션을 설정하면 msdeploy에서 앱 배포 중 잠겨 있는 파일의 이름을 바꿀 수 있습니다.", + "loc.input.label.XmlTransformation": "XML 변환", + "loc.input.help.XmlTransformation": "`*.config 파일`에서 `*.Release.config` 및 `*..config`에 대한 구성 변환이 실행됩니다.
구성 변환은 변수 대체 전에 실행됩니다.
XML 변환은 Windows 플랫폼에서만 지원됩니다.", + "loc.input.label.XmlVariableSubstitution": "XML 변수 대체", + "loc.input.help.XmlVariableSubstitution": "빌드 또는 릴리스 정의에 정의된 변수는 모든 구성 파일과 parameters.xml의 appSettings, applicationSettings 및 connectionStrings 섹션에 있는 'key' 또는 'name' 항목과 대조됩니다. 변수 대체는 구성 변환 후에 실행됩니다.

참고: 릴리스 정의 및 환경에 동일한 변수가 정의된 경우에는 환경 변수가 릴리스 정의 변수를 대체합니다.
", + "loc.input.label.JSONFiles": "JSON 변수 대체", + "loc.input.help.JSONFiles": "변수 값을 대체할 JSON 파일을 줄 바꿈으로 구분된 목록으로 제공합니다. 파일 이름은 루트 폴더에 상대적으로 지정해야 합니다.
중첩되거나 계층적인 JSON 변수를 대체하려면 JSONPath 식을 사용하여 지정합니다.

예를 들어, 아래 샘플에서 ‘ConnectionString’ 값을 대체하려면 빌드/릴리스 정의(또는 릴리스 정의의 환경)에서 변수를 ‘Data.DefaultConnection.ConnectionString’으로 정의해야 합니다.
{
  \"Data\": {
    \"DefaultConnection\": {
      \"ConnectionString\": \"Server=(localdb)\\SQLEXPRESS;Database=MyDB;Trusted_Connection=True\"
    }
  }
}
변수 대체는 구성 변환 후 실행됩니다.

참고: 빌드/릴리스의 시스템 정의 변수는 대체에서 제외됩니다.", + "loc.messages.Invalidwebapppackageorfolderpathprovided": "잘못된 App Service 패키지 또는 폴더 경로를 제공했습니다. %s", + "loc.messages.SetParamFilenotfound0": "매개 변수 설정 파일을 찾을 수 없습니다. %s", + "loc.messages.XDTTransformationsappliedsuccessfully": "XML 변환을 적용했습니다.", + "loc.messages.GotconnectiondetailsforazureRMWebApp0": "Azure App Service '%s'에 대한 연결 정보를 가져왔습니다.", + "loc.messages.ErrorNoSuchDeployingMethodExists": "오류: 해당 배포 방법이 없습니다.", + "loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp": "Azure App Service %s에 대한 연결 정보를 검색할 수 없습니다. 상태 코드: %s(%s)", + "loc.messages.UnabletoretrieveResourceID": "Azure 리소스 '%s'에 대한 연결 정보를 가져올 수 없습니다. 상태 코드: %s", + "loc.messages.CouldnotfetchaccesstokenforAzureStatusCode": "Azure에 대한 액세스 토큰을 가져올 수 없습니다. 상태 코드: %s(%s)", + "loc.messages.Successfullyupdateddeploymenthistory": "%s에서 배포 기록을 업데이트했습니다.", + "loc.messages.Failedtoupdatedeploymenthistory": "배포 기록을 업데이트하지 못했습니다. 오류: %s", + "loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "경고: 배포 상태를 업데이트할 수 없습니다. 이 웹 사이트에는 SCM 끝점을 사용할 수 없습니다.", + "loc.messages.Unabletoretrievewebconfigdetails": "App Service 구성 정보를 검색할 수 없습니다. 상태 코드: '%s'", + "loc.messages.Unabletoretrievewebappsettings": "App Service 응용 프로그램 설정을 검색할 수 없습니다[상태 코드: '%s', 오류 메시지: '%s'].", + "loc.messages.Unabletoupdatewebappsettings": "App Service 응용 프로그램 설정을 업데이트할 수 없습니다. 상태 코드: '%s'", + "loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "배포 상태를 업데이트할 수 없습니다. 고유한 배포 ID를 검색할 수 없습니다.", + "loc.messages.PackageDeploymentSuccess": "웹 패키지를 App Service에 배포했습니다.", + "loc.messages.PackageDeploymentFailed": "웹 패키지를 App Service에 배포하지 못했습니다.", + "loc.messages.Runningcommand": "%s 명령을 실행하고 있습니다.", + "loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath": "웹 패키지 %s을(를) 가상 경로(실제 경로) %s(%s)에 배포하는 중입니다.", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Kudu 서비스를 사용하여 %s 패키지를 %s에 배포했습니다.", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Kudu 서비스를 사용하여 App Service 패키지를 배포하지 못했습니다. %s", + "loc.messages.Unabletodeploywebappresponsecode": "오류 코드로 인해 App Service를 배포할 수 없습니다. %s", + "loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "MSDeploy 생성 패키지는 Windows 플랫폼에만 지원됩니다.", + "loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "MSDeploy에 대해 지원되지 않는 설치된 버전 %s을(를) 찾았습니다. 버전은 3 이상이어야 합니다.", + "loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError": "컴퓨터의 레지스트리에서 MS 배포의 위치를 찾을 수 없습니다(오류: %s).", + "loc.messages.Nopackagefoundwithspecifiedpattern": "지정한 패턴을 가진 패키지 없음: %s", + "loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "지정한 패턴 %s과(와) 일치하는 패키지가 두 개 이상 있습니다. 검색 패턴을 제한하세요.", + "loc.messages.Trytodeploywebappagainwithappofflineoptionselected": "[응용 프로그램을 오프라인으로 만들기] 옵션을 선택하고 App Service를 다시 배포해 보세요.", + "loc.messages.Trytodeploywebappagainwithrenamefileoptionselected": "[잠겨 있는 파일 이름 바꾸기] 옵션을 선택하고 App Service를 다시 배포해 보세요.", + "loc.messages.NOJSONfilematchedwithspecificpattern": "특정 패턴과 일치하는 JSON 파일이 없음: %s", + "loc.messages.Configfiledoesntexists": "구성 파일 %s이(가) 없습니다.", + "loc.messages.Failedtowritetoconfigfilewitherror": "구성 파일 %s에 쓰지 못했습니다(오류: %s).", + "loc.messages.AppOfflineModeenabled": "앱 오프라인 모드를 사용하도록 설정했습니다.", + "loc.messages.Failedtoenableappofflinemode": "앱 오프라인 모드를 사용하도록 설정하지 못했습니다. 상태 코드: %s(%s)", + "loc.messages.AppOflineModedisabled": "앱 오프라인 모드를 사용하지 않도록 설정했습니다.", + "loc.messages.FailedtodisableAppOfflineMode": "앱 오프라인 모드를 사용하지 않도록 설정하지 못했습니다. 상태 코드: %s(%s)", + "loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform": "Windows가 아닌 플랫폼에서는 XML 변환을 수행할 수 없습니다.", + "loc.messages.XdtTransformationErrorWhileTransforming": "%s을(를) 변환(%s 사용)하는 동안 XML 변환 오류가 발생했습니다.", + "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "웹 배포 옵션을 사용한 게시는 Windows 에이전트를 사용할 경우에만 지원됩니다.", + "loc.messages.ResourceDoesntExist": "'%s' 리소스가 없습니다. 배포 전에 리소스가 있어야 합니다.", + "loc.messages.EncodeNotSupported": "%s 파일에 대한 파일 인코딩이 %s(으)로 검색되었습니다. 파일 인코딩 %s을(를) 사용할 경우 변수 대체가 지원되지 않습니다. 지원되는 인코딩은 UTF-8 및 UTF-16 LE입니다.", + "loc.messages.UnknownFileEncodeError": "%s 파일(typeCode: %s)에 대한 인코딩을 검색할 수 없습니다. 지원되는 인코딩은 UTF-8 및 UTF-16 LE입니다.", + "loc.messages.ShortFileBufferError": "파일 버퍼가 너무 짧아서 인코딩 형식을 검색할 수 없습니다. %s", + "loc.messages.FailedToUpdateAzureRMWebAppConfigDetails": "App Service 구성 정보를 업데이트하지 못했습니다. 오류: %s", + "loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails": "App Service 구성 정보를 업데이트했습니다.", + "loc.messages.RequestedURLforkuduphysicalpath": "Kudu 실제 경로의 요청된 URL: %s", + "loc.messages.Physicalpathalreadyexists": "실제 경로 '%s'이(가) 이미 있습니다.", + "loc.messages.KuduPhysicalpathCreatedSuccessfully": "Kudu 실제 경로를 만들었습니다. %s", + "loc.messages.FailedtocreateKuduPhysicalPath": "Kudu 실제 경로를 만들지 못했습니다. 오류: %s", + "loc.messages.FailedtocheckphysicalPath": "Kudu 실제 경로를 확인하지 못했습니다. 오류 코드: %s", + "loc.messages.VirtualApplicationDoesNotExist": "가상 응용 프로그램이 없습니다. %s", + "loc.messages.JSONParseError": "JSON 파일 %s을(를) 구문 분석할 수 없습니다. 오류: %s", + "loc.messages.JSONvariablesubstitutionappliedsuccessfully": "JSON 변수 대체를 적용했습니다.", + "loc.messages.XMLvariablesubstitutionappliedsuccessfully": "XML 변수 대체를 적용했습니다.", + "loc.messages.failedtoUploadFileToKudu": "%s 파일을 Kudu(%s)에 업로드할 수 없습니다. 상태 코드: %s", + "loc.messages.failedtoUploadFileToKuduError": "%s 파일을 Kudu(%s)에 업로드할 수 없습니다. 오류: %s", + "loc.messages.ExecuteScriptOnKudu": "Kudu 서비스에서 지정된 스크립트를 실행하는 중입니다.", + "loc.messages.FailedToRunScriptOnKuduError": "Kudu 서비스에서 스크립트를 실행할 수 없습니다. 오류: %s", + "loc.messages.FailedToRunScriptOnKudu": "Kudu에서 스크립트를 실행할 수 없음: %s. 상태 코드: %s", + "loc.messages.ScriptExecutionOnKuduSuccess": "Kudu에서 스크립트를 실행했습니다.", + "loc.messages.ScriptExecutionOnKuduFailed": "실행된 스크립트에서 반환 코드로 '%s'을(를) 반환했습니다. 오류: %s", + "loc.messages.FailedtoDeleteFileFromKudu": "%s 파일을 Kudu(%s)에서 삭제할 수 없습니다. 상태 코드: %s", + "loc.messages.FailedtoDeleteFileFromKuduError": "%s 파일을 Kudu(%s)에서 삭제할 수 없습니다. 오류: %s", + "loc.messages.ScriptFileNotFound": "스크립트 파일 '%s'을(를) 찾을 수 없습니다.", + "loc.messages.InvalidScriptFile": "잘못된 스크립트 파일 '%s'이(가) 제공되었습니다. 유효한 확장명은 Windows의 경우 .bat 및 .cmd이고, Linux의 경우 .sh입니다.", + "loc.messages.RetryForTimeoutIssue": "시간 초과 문제로 스크립트 실행에 실패했습니다. 다시 시도하는 중입니다.", + "loc.messages.stdoutFromScript": "스크립트의 표준 출력: ", + "loc.messages.stderrFromScript": "스크립트의 표준 오류: ", + "loc.messages.WebConfigAlreadyExists": "web.config 파일이 이미 있습니다. 생성하지 않습니다.", + "loc.messages.SuccessfullyGeneratedWebConfig": "web.config 파일을 생성했습니다.", + "loc.messages.FailedToGenerateWebConfig": "web.config를 생성하지 못했습니다. %s", + "loc.messages.FailedToGetKuduFileContent": "파일 콘텐츠 %s을(를) 가져오지 못했습니다. 상태 코드: %s(%s)", + "loc.messages.FailedToGetKuduFileContentError": "파일 콘텐츠 %s을(를) 가져오지 못했습니다. 오류: %s", + "loc.messages.ScriptStatusTimeout": "시간 초과로 인해 스크립트 상태를 페치할 수 없습니다.", + "loc.messages.PollingForFileTimeOut": "시간 초과로 인해 스크립트 상태를 페치할 수 없습니다. 'appservicedeploy.retrytimeout' 변수를 필요한 시간(분)으로 설정하여 시간 제한을 늘릴 수 있습니다.", + "loc.messages.InvalidPollOption": "잘못된 폴링 옵션이 제공됨: %s.", + "loc.messages.MissingAppTypeWebConfigParameters": "Web.config 매개 변수에 '-appType' 특성이 없습니다. '-appType'에 대해 유효한 값은 'python_Bottle', 'python_Django', 'python_Flask' 및 'node'입니다.
예: Python Bottle 프레임워크의 경우 '-appType python_Bottle' (sans-quotes)", + "loc.messages.AutoDetectDjangoSettingsFailed": "DJANGO_SETTINGS_MODULE 'settings.py' 파일 경로를 검색할 수 없습니다. 'settings.py' 파일이 존재하는지 확인하거나 Web.config 매개 변수 입력에 '-DJANGO_SETTINGS_MODULE .settings' 형식으로 올바른 경로를 제공하세요.", + "loc.messages.FailedToApplyTransformation": "지정된 패키지에 변환을 적용할 수 없습니다. 다음을 확인하세요.", + "loc.messages.FailedToApplyTransformationReason1": "1. 빌드 중 생성된 MSBuild 패키지에 대해 변환이 이미 적용되었는지 여부를 확인합니다. 그런 경우 csproj 파일에서 각 구성에 대해 태그를 제거하고 다시 빌드합니다. ", + "loc.messages.FailedToApplyTransformationReason2": "2. 구성 파일 및 변환 파일이 패키지 내의 동일한 폴더에 있는지 확인합니다.", + "loc.messages.AutoParameterizationMessage": "Web.config의 ConnectionString 특성은 기본적으로 매개 변수가 있습니다. 'Parameters.xml' 또는 'SetParameters.xml' 파일로 배포 중 값이 재정의되므로 변환은 connectionString 특성에 아무런 영향을 미치지 않습니다. MSBuild 패키지 생성 중 p:AutoParameterizationWebConfigConnectionStrings=False를 설정하여 자동 매개 변수화를 사용하지 않도록 설정할 수 있습니다.", + "loc.messages.UnsupportedAppType": "Web.config 생성에서 '%s' 앱 형식이 지원되지 않습니다. '-appType'에 대해 유효한 값은 'python_Bottle', 'python_Django', 'python_Flask' 및 'node'입니다.", + "loc.messages.UnableToFetchAuthorityURL": "기관 URL을 가져올 수 없습니다.", + "loc.messages.UnableToFetchActiveDirectory": "Active Directory 리소스 ID를 가져올 수 없습니다.", + "loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand": "런타임 스택 및 시작 명령을 업데이트했습니다.", + "loc.messages.FailedToUpdateRuntimeStackAndStartupCommand": "런타임 스택 및 시작 명령을 업데이트하지 못했습니다. 오류: %s.", + "loc.messages.SuccessfullyUpdatedWebAppSettings": "앱 설정을 업데이트했습니다.", + "loc.messages.FailedToUpdateAppSettingsInConfigDetails": "앱 설정을 업데이트하지 못했습니다. 오류: %s.", + "loc.messages.UnableToGetAzureRMWebAppMetadata": "AzureRM WebApp 메타데이터를 페치하지 못했습니다. 오류 코드: %s", + "loc.messages.UnableToUpdateAzureRMWebAppMetadata": "AzureRM WebApp 메타데이터를 업데이트할 수 없습니다. 오류 코드: %s", + "loc.messages.Unabletoretrieveazureregistrycredentials": "Azure Container Registry 자격 증명을 가져올 수 없습니다. [상태 코드: '%s']", + "loc.messages.UnableToReadResponseBody": "응답 본문을 읽을 수 없습니다. 오류: %s", + "loc.messages.UnableToUpdateWebAppConfigDetails": "WebApp 구성 정보를 업데이트할 수 없습니다. 상태 코드: '%s'", + "loc.messages.AddingReleaseAnnotation": "Application Insights 리소스 '%s'에 대한 릴리스 주석을 추가하는 중", + "loc.messages.SuccessfullyAddedReleaseAnnotation": "Application Insight에 릴리스 주석 추가함: %s", + "loc.messages.FailedAddingReleaseAnnotation": "릴리스 주석을 추가하지 못했습니다. %s", + "loc.messages.RenameLockedFilesEnabled": "App Service에 대해 잠긴 파일 이름 바꾸기를 사용할 수 있습니다.", + "loc.messages.FailedToEnableRenameLockedFiles": "잠긴 파일 이름 바꾸기를 사용하도록 설정하지 못했습니다. 오류: %s", + "loc.messages.WebJobsInProgressIssue": "실행 상태인 몇 개의 WebJob 때문에 배포에서 해당 파일을 제거할 수 없습니다. 배포 전에 '대상에서 추가 파일 제거' 옵션을 사용하지 않도록 설정하거나 연속 작업을 중지할 수 있습니다.", + "loc.messages.FailedToFetchKuduAppSettings": "Kudu 앱 설정을 페치하지 못했습니다. 오류: %s", + "loc.messages.FailedToCreatePath": "Kudu에서 '%s' 경로를 만들지 못했습니다. 오류: %s", + "loc.messages.FailedToDeleteFile": "Kudu에서 '%s/%s' 파일을 삭제하지 못했습니다. 오류: %s", + "loc.messages.FailedToUploadFile": "Kudu에서 '%s/%s' 파일을 업로드하지 못했습니다. 오류: %s", + "loc.messages.FailedToGetFileContent": "Kudu에서 파일 콘텐츠 '%s/%s'을(를) 가져오지 못했습니다. 오류: %s", + "loc.messages.FailedToListPath": "Kudu에서 '%s' 경로를 나열하지 못했습니다. 오류: %s", + "loc.messages.RetryToDeploy": "패키지 배포를 다시 시도하는 중입니다.", + "loc.messages.FailedToGetAppServiceDetails": "App Service '%s' 정보를 페치하지 못했습니다. 오류: %s", + "loc.messages.FailedToGetAppServicePublishingProfile": "App Service '%s' 게시 프로필을 페치하지 못했습니다. 오류: %s", + "loc.messages.FailedToUpdateAppServiceMetadata": "App Service '%s' 메타데이터를 업데이트하지 못했습니다. 오류: %s", + "loc.messages.FailedToGetAppServiceMetadata": "App Service '%s' 메타데이터를 가져오지 못했습니다. 오류: %s", + "loc.messages.FailedToPatchAppServiceConfiguration": "App Service '%s' 구성을 패치하지 못했습니다. 오류: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "App Service '%s' 구성을 업데이트하지 못했습니다. 오류: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "App Service '%s' 구성을 가져오지 못했습니다. 오류: %s", + "loc.messages.FailedToGetAppServicePublishingCredentials": "App Service '%s' 게시 자격 증명을 페치하지 못했습니다. 오류: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "App Service '%s' 응용 프로그램 설정을 가져오지 못했습니다. 오류: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "App Service '%s' 응용 프로그램 설정을 업데이트하지 못했습니다. 오류: %s", + "loc.messages.UpdatingAppServiceConfigurationSettings": "App Service 구성 설정을 업데이트하는 중입니다. 데이터: %s", + "loc.messages.UpdatedAppServiceConfigurationSettings": "App Service 구성 설정을 업데이트했습니다.", + "loc.messages.UpdatingAppServiceApplicationSettings": "App Service 응용 프로그램 설정을 업데이트하는 중입니다. 데이터: %s", + "loc.messages.UpdatedAppServiceApplicationSettings": "App Service 응용 프로그램 설정 및 Kudu 응용 프로그램 설정을 업데이트했습니다.", + "loc.messages.MultipleResourceGroupFoundForAppService": "App Service '%s'에 대한 리소스 그룹이 여러 개 있습니다.", + "loc.messages.PackageDeploymentUsingZipDeployFailed": "ZIP 배포를 사용한 패키지 배포에 실패했습니다. 자세한 내용은 로그를 참조하세요.", + "loc.messages.PackageDeploymentInitiated": "ZIP 배포를 사용한 패키지 배포가 시작되었습니다.", + "loc.messages.FailedToGetDeploymentLogs": "배포 로그를 가져오지 못했습니다. 오류: %s", + "loc.messages.GoExeNameNotPresent": "Go exe 이름이 없습니다.", + "loc.messages.WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier." +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/ru-RU/resources.resjson b/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/ru-RU/resources.resjson new file mode 100644 index 000000000000..f9d5ea8f37bc --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/ru-RU/resources.resjson @@ -0,0 +1,219 @@ +{ + "loc.friendlyName": "Развертывание службы приложений Azure", + "loc.helpMarkDown": "[Дополнительные сведения](https://aka.ms/azurermwebdeployreadme)", + "loc.description": "Вы можете обновлять веб-службы Azure в Windows, веб-приложения в Linux со встроенными образами или контейнерами Docker, веб-приложения на основе ASP.NET, .NET Core, PHP, Python или Node, приложения-функции, мобильные приложения, приложения API и веб-задания с использованием веб-развертывания или REST API Kudu", + "loc.instanceNameFormat": "Развертывание службы приложений Azure: $(WebAppName)", + "loc.releaseNotes": "Новые возможности в версии 3.0
  Поддержка преобразований файлов (XDT)
  Поддержка подстановок переменных (XML, JSON)
Подробнее см. [здесь](https://aka.ms/azurermwebdeployreadme).", + "loc.group.displayName.FileTransformsAndVariableSubstitution": "Параметры преобразования файлов и подстановки переменных", + "loc.group.displayName.AdditionalDeploymentOptions": "Дополнительные параметры развертывания", + "loc.group.displayName.PostDeploymentAction": "Действие после развертывания", + "loc.group.displayName.ApplicationAndConfigurationSettings": "Параметры приложения и конфигурации", + "loc.group.displayName.output": "Выход", + "loc.input.label.ConnectedServiceName": "Подписка Azure", + "loc.input.help.ConnectedServiceName": "Выберите подписку на Azure Resource Manager для развертывания.", + "loc.input.label.WebAppKind": "Тип приложения", + "loc.input.help.WebAppKind": "Выберите тип веб-приложения для развертывания.
Примечание. При развертывании встроенных образов платформы или пользовательских образов контейнера выберите \"Веб-приложение для Linux\".", + "loc.input.label.WebAppName": "Имя службы приложений", + "loc.input.help.WebAppName": "Введите или выберите имя существующей службы приложений Azure. Будут перечислены только службы приложений для выбранного типа приложения.", + "loc.input.label.DeployToSlotFlag": "Развертывание в слот", + "loc.input.help.DeployToSlotFlag": "Выберите этот параметр для развертывания в существующем слоте вместо рабочего слота. Если этот параметр не выбран, служба приложений Azure будет развернута в рабочем слоте.", + "loc.input.label.ResourceGroupName": "Группа ресурсов", + "loc.input.help.ResourceGroupName": "Введите или выберите имя группы ресурсов Azure, содержащей службу приложений Azure, указанную выше.", + "loc.input.label.SlotName": "Слот", + "loc.input.help.SlotName": "Введите или выберите существующий слот вместо рабочего слота.", + "loc.input.label.ImageSource": "Источник образа", + "loc.input.help.ImageSource": "Служба приложений в Linux предоставляет два различных варианта публикации приложения:
развертывание пользовательского образа и развертывание приложения с помощью встроенного образа платформы. [Дополнительные сведения](https://go.microsoft.com/fwlink/?linkid=862490)", + "loc.input.label.AzureContainerRegistry": "Реестр", + "loc.input.help.AzureContainerRegistry": "Глобально уникальное доменное имя верхнего уровня для реестра или пространства имен.
Примечание. Полное доменное имя имеет следующий формат: \"`<реестр или пространство имен`>/`<репозиторий`>:`<тег`>\". Например: \"myregistry.azurecr.io/nginx:latest\".", + "loc.input.label.AzureContainerRegistryLoginServer": "Имя сервера для входа в реестр", + "loc.input.help.AzureContainerRegistryLoginServer": "Введите или выберите имя сервера для входа в реестр контейнеров Azure.", + "loc.input.label.AzureContainerRegistryImage": "Образ", + "loc.input.help.AzureContainerRegistryImage": "Имя репозитория, в котором хранятся образы контейнера.
Примечание. Полное доменное имя образа имеет следующий формат: \"`<реестр или пространство имен`>/`<репозиторий`>:`\". Например: \"myregistry.azurecr.io/nginx:latest\".", + "loc.input.label.AzureContainerRegistryTag": "Тег", + "loc.input.help.AzureContainerRegistryTag": "Теги необязательны; они используются в реестрах для указания версий образов Docker.
Примечание. Полное доменное имя образа имеет следующий формат: \"`/`:`\". Например: \"myregistry.azurecr.io/nginx:latest\".", + "loc.input.label.DockerRepositoryAccess": "Доступ к репозиторию", + "loc.input.help.DockerRepositoryAccess": "Выберите доступ к репозиторию Docker.", + "loc.input.label.RegistryConnectedServiceName": "Подключение к реестру", + "loc.input.help.RegistryConnectedServiceName": "Выберите подключение к реестру.", + "loc.input.label.PrivateRegistryImage": "Образ", + "loc.input.help.PrivateRegistryImage": "Имя репозитория, в котором хранятся образы контейнера.
Примечание. Полное доменное имя образа имеет следующий формат: \"`<реестр или пространство имен`>/`<репозиторий`>:`\". Например: \"myregistry.azurecr.io/nginx:latest\".", + "loc.input.label.PrivateRegistryTag": "Тег", + "loc.input.help.PrivateRegistryTag": "Теги необязательны; они используются в реестрах для указания версий образов Docker.
Примечание. Полное доменное имя образа имеет следующий формат: \"`/`:`\". Например: \"myregistry.azurecr.io/nginx:latest\".", + "loc.input.label.DockerNamespace": "Реестр или пространство имен", + "loc.input.help.DockerNamespace": "Глобально уникальное доменное имя верхнего уровня для реестра или пространства имен.
Примечание. Полное доменное имя имеет следующий формат: \"`<реестр или пространство имен`>/`<репозиторий`>:`\". Например, \"myregistry.azurecr.io/nginx:latest\".", + "loc.input.label.DockerRepository": "Образ", + "loc.input.help.DockerRepository": "Имя репозитория, в котором хранятся образы контейнера.
Примечание. Полное доменное имя образа имеет следующий формат: \"`<реестр или пространство имен`>/`<репозиторий`>:`\". Например, \"myregistry.azurecr.io/nginx:latest\".", + "loc.input.label.DockerImageTag": "Тег", + "loc.input.help.DockerImageTag": "Теги необязательны, они используются в реестрах для указания версий образов Docker.
Примечание. Полное доменное имя образа имеет следующий формат: \"`<реестр или пространство имен`>/`<репозиторий`>:`\". Например, \"myregistry.azurecr.io/nginx:latest\".", + "loc.input.label.VirtualApplication": "Виртуальное приложение", + "loc.input.help.VirtualApplication": "Укажите имя виртуального приложения, настроенного на портале Azure. Параметр не является обязательным для развертываний в корне службы приложений.", + "loc.input.label.Package": "Пакет или папка", + "loc.input.help.Package": "Путь к файлу пакета или папке с содержимым службы приложений, созданным MSBuild, или к сжатому ZIP- или WAR-файлу.
Поддерживаются переменные ([Сборка](https://www.visualstudio.com/docs/build/define/variables) | [Выпуск](https://www.visualstudio.com/docs/release/author-release-definition/understanding-tasks#predefvariables)) и подстановочные знаки.
Например: $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip или $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.BuiltinLinuxPackage": "Пакет или папка", + "loc.input.help.BuiltinLinuxPackage": "Путь к файлу пакета или папке с содержимым службы приложений, созданным MSBuild, или к сжатому ZIP- или WAR-файлу.
Поддерживаются переменные ([Сборка](https://www.visualstudio.com/docs/build/define/variables) | [Выпуск](https://www.visualstudio.com/docs/release/author-release-definition/understanding-tasks#predefvariables)) и подстановочные знаки.
Например: $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip или $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.RuntimeStack": "Стек среды выполнения", + "loc.input.help.RuntimeStack": "Выберите платформу и версию.", + "loc.input.label.StartupCommand": "Команда запуска ", + "loc.input.help.StartupCommand": "Введите команду запуска.", + "loc.input.label.WebAppUri": "URL-адрес службы приложений", + "loc.input.help.WebAppUri": "Укажите имя выходной переменной, которая создается для URL-адреса службы приложений Azure. Эта переменная может использоваться в последующих задачах.", + "loc.input.label.ScriptType": "Тип сценария развертывания", + "loc.input.help.ScriptType": "Настройте развертывание, указав скрипт, который будет выполнен в службе приложений Azure по окончании развертывания. Например: восстановите пакеты для приложений Node, PHP и Python. [Дополнительные сведения](https://go.microsoft.com/fwlink/?linkid=843471).", + "loc.input.label.InlineScript": "Встроенный скрипт", + "loc.input.label.ScriptPath": "Путь к сценарию развертывания", + "loc.input.label.GenerateWebConfig": "Сгенерировать файл web.config", + "loc.input.help.GenerateWebConfig": "Если в приложении отсутствует стандартный файл web.config, он будет сгенерирован и развернут в службе приложений Azure. Значения в файле web.config можно изменить. Они могут меняться в зависимости от исполняющей среды. Например, в файле web.config приложения node.js имеются загрузочный файл и модульные значения iis_node. [Подробнее](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.WebConfigParameters": "Параметры web.config", + "loc.input.help.WebConfigParameters": "Измените значения в сгенерированном файле web.config (например, загрузочный файл). Данная функция изменения доступна только для сгенерированного файла web.config. [Подробнее](https://go.microsoft.com/fwlink/?linkid=843469).", + "loc.input.label.AppSettings": "Параметры приложения", + "loc.input.help.AppSettings": "Изменить параметры приложения веб-приложения синтаксис-значение ключа. Значение, которое содержит пробелы необходимо заключить в двойные кавычки.
Пример :-порт 5000 - RequestTimeout 5000
-WEBSITE_TIME_ZONE «Восточное время (зима)»", + "loc.input.label.ConfigurationSettings": "Параметры конфигурации", + "loc.input.help.ConfigurationSettings": "Изменить параметры конфигурации веб-приложения синтаксис-значение ключа. Значение, которое содержит пробелы необходимо заключить в двойные кавычки.
Пример: - phpVersion 5.6 - linuxFxVersion: узел|6.11", + "loc.input.label.TakeAppOfflineFlag": "Перевести приложение в автономный режим", + "loc.input.help.TakeAppOfflineFlag": "Выберите этот параметр, чтобы перевести службу приложений Azure в автономный режим путем размещения файла app_offline.htm в корневом каталоге службы приложений перед началом операции синхронизации. Файл будет удален после успешного завершения синхронизации.", + "loc.input.label.UseWebDeploy": "Опубликовать при помощи веб-развертывания", + "loc.input.help.UseWebDeploy": "Публикация с помощью параметров веб-развертывания поддерживается только при использовании агента для Windows. На других платформах для развертывания службы приложений Azure используются [API-интерфейсы REST Kudu](https://github.com/projectkudu/kudu/wiki/REST-API), и следующие параметры не поддерживаются.", + "loc.input.label.SetParametersFile": "Файл SetParameters", + "loc.input.help.SetParametersFile": "Дополнительно: расположение используемого файла SetParameters.xml.", + "loc.input.label.RemoveAdditionalFilesFlag": "Удалять дополнительные файлы в месте назначения", + "loc.input.help.RemoveAdditionalFilesFlag": "Выберите этот параметр, чтобы удалить файлы в службе приложений Azure, для которых отсутствуют соответствующие файлы или папки в службе приложений.

Примечание. При этом также будут удалены все файлы, связанные со всеми расширениями, установленными в этой службе приложений Azure App. Чтобы этого избежать, установите флажок \"Исключить файлы из папки App_Data\".", + "loc.input.label.ExcludeFilesFromAppDataFlag": "Исключить файлы из папки App_Data", + "loc.input.help.ExcludeFilesFromAppDataFlag": "Выберите этот параметр, чтобы заблокировать развертывание файлов из папки App_Data в службе приложений Azure.", + "loc.input.label.AdditionalArguments": "Дополнительные аргументы", + "loc.input.help.AdditionalArguments": "Дополнительные аргументы веб-развертывания, использующие синтаксис -ключ:значение.
Они будут применяться при развертывании службы приложений Azure, например -disableLink:AppPoolExtension -disableLink:ContentExtension.
Другие примеры рабочих параметров веб-развертывания см. [здесь](https://go.microsoft.com/fwlink/?linkid=838471).", + "loc.input.label.RenameFilesFlag": "Переименовывать заблокированные файлы", + "loc.input.help.RenameFilesFlag": "Выберите этот параметр, чтобы включить в msdeploy флаг MSDEPLOY_RENAME_LOCKED_FILES=1 в параметрах приложения службы приложений Azure. Если этот параметр установлен, msdeploy может переименовывать файлы, заблокированные во время развертывания приложения", + "loc.input.label.XmlTransformation": "XML-преобразование", + "loc.input.help.XmlTransformation": "Преобразования конфигурации будут выполнены для \"*.Release.config\" и \"*..config\" в файле \"*.config\".
Преобразования конфигурации запускаются перед подстановкой переменных.
XML-преобразования поддерживаются только на платформе Windows.", + "loc.input.label.XmlVariableSubstitution": "Подстановка XML-переменных", + "loc.input.help.XmlVariableSubstitution": "Переменные, заданные в определении сборки или выпуска, будут сопоставлены с записями \"key\" или \"name\" в разделах appSettings, applicationSettings и connectionStrings всех файлов конфигурации и parameters.xml. Подстановка переменных выполняется после преобразований конфигурации.

Примечание. Если одни и те же переменные заданы в определении выпуска и в среде, то переменные среды имеют приоритет над переменными из определения выпуска.
", + "loc.input.label.JSONFiles": "Подстановка переменных JSON", + "loc.input.help.JSONFiles": "Укажите разделенный переносами строки список JSON-файлов для подстановки значений переменных. Имена файлов следует указывать относительно корневой папки.
Чтобы подставить вложенные или иерархические JSON-переменные, укажите их с помощью выражений JSONPath.

Например, чтобы заменить значение \"ConnectionString\" в примере ниже, следует определить переменную как \"Data.DefaultConnection.ConnectionString\" в определении сборки и выпуска (или окружении определения выпуска).
{
  \"Data\": {
    \"DefaultConnection\": {
      \"ConnectionString\": \"Server=(localdb)\\SQLEXPRESS;Database=MyDB;Trusted_Connection=True\"
    }
  }
}
Подстановка переменных запускается после преобразований конфигураций.

Примечание. Переменные определений системы сборки и выпуска исключены из подстановки.", + "loc.messages.Invalidwebapppackageorfolderpathprovided": "Указан недопустимый путь к пакету службы приложений или папке: %s", + "loc.messages.SetParamFilenotfound0": "Заданный файл параметров не найден: %s", + "loc.messages.XDTTransformationsappliedsuccessfully": "XML-преобразования успешно применены.", + "loc.messages.GotconnectiondetailsforazureRMWebApp0": "Получены сведения о подключении службы приложений Azure: \"%s\".", + "loc.messages.ErrorNoSuchDeployingMethodExists": "Ошибка: такого метода развертывания не существует.", + "loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp": "Не удалось получить данные о подключении для службы приложений Azure: %s. Код состояния: %s (%s)", + "loc.messages.UnabletoretrieveResourceID": "Не удалось получить данные о подключении для ресурса Azure: \"%s\". Код состояния: %s", + "loc.messages.CouldnotfetchaccesstokenforAzureStatusCode": "Не удалось извлечь токен доступа для Azure. Код состояния: %s (%s)", + "loc.messages.Successfullyupdateddeploymenthistory": "Журнал развертывания (%s) успешно обновлен.", + "loc.messages.Failedtoupdatedeploymenthistory": "Не удалось обновить журнал развертывания. Ошибка: %s", + "loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "ПРЕДУПРЕЖДЕНИЕ: невозможно обновить состояние развертывания, конечная точка SCM не включена для этого веб-сайта.", + "loc.messages.Unabletoretrievewebconfigdetails": "Не удалось получить сведения о конфигурации службы приложений. Код состояния: \"%s\"", + "loc.messages.Unabletoretrievewebappsettings": "Не удалось извлечь параметры приложения службы приложений. [Код состояния: \"%s\", сообщение об ошибке: \"%s\"]", + "loc.messages.Unabletoupdatewebappsettings": "Не удалось обновить параметры приложения службы приложений. Код состояния: \"%s\"", + "loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "Не удается обновить состояние развертывания: не удается получить уникальный идентификатор развертывания.", + "loc.messages.PackageDeploymentSuccess": "Веб-пакет успешно развернут в службе приложений.", + "loc.messages.PackageDeploymentFailed": "Не удалось развернуть веб-пакет в службе приложений.", + "loc.messages.Runningcommand": "Запуск команды: %s", + "loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath": "Развертывание веб-пакета %s по виртуальному пути (физическому пути): %s (%s)", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "Пакет (%s) успешно развернут при помощи службы kudu (%s).", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "Не удалось развернуть пакет службы приложений при помощи службы kudu: %s", + "loc.messages.Unabletodeploywebappresponsecode": "Не удалось развернуть службу приложений из-за ошибки: %s", + "loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "Пакеты, созданные при помощи MSDeploy, поддерживаются только для платформы Windows.", + "loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "Установленная версия MSDeploy (%s) не поддерживается. Должна быть установлена версия 3 или более поздняя.", + "loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError": "Не удалось определить расположение MS Deploy при помощи реестра на компьютере (ошибка: %s).", + "loc.messages.Nopackagefoundwithspecifiedpattern": "Пакет с указанным шаблоном не найден: %s", + "loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "Указанному шаблону соответствует несколько пакетов: %s. Ограничьте шаблон поиска.", + "loc.messages.Trytodeploywebappagainwithappofflineoptionselected": "Попробуйте снова развернуть службу приложений, используя параметр \"Отключить приложение от сети\".", + "loc.messages.Trytodeploywebappagainwithrenamefileoptionselected": "Попробуйте снова развернуть службу приложений, используя параметр \"Переименовывать заблокированные файлы\".", + "loc.messages.NOJSONfilematchedwithspecificpattern": "Не найден файл JSON, соответствующий заданному шаблону: %s.", + "loc.messages.Configfiledoesntexists": "Файл конфигурации %s не существует.", + "loc.messages.Failedtowritetoconfigfilewitherror": "Сбой записи в файл конфигурации %s. Ошибка: %s.", + "loc.messages.AppOfflineModeenabled": "Автономный режим для приложения включен.", + "loc.messages.Failedtoenableappofflinemode": "Не удалось включить автономный режим для приложения. Код состояния: %s (%s).", + "loc.messages.AppOflineModedisabled": "Автономный режим для приложения отключен.", + "loc.messages.FailedtodisableAppOfflineMode": "Не удалось отключить автономный режим для приложения. Код состояния: %s (%s)", + "loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform": "Невозможно выполнить XML-преобразования на платформе, отличной от Windows.", + "loc.messages.XdtTransformationErrorWhileTransforming": "Ошибка XML-преобразования при преобразовании %s с помощью %s.", + "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Публикация при помощи веб-развертывания поддерживается только при использовании агента для Windows.", + "loc.messages.ResourceDoesntExist": "Ресурс \"%s\" не существует. Он должен существовать перед началом развертывания.", + "loc.messages.EncodeNotSupported": "Обнаруженная кодировка файла %s — %s. Подстановка переменных не поддерживается для кодировки %s. Поддерживаемые кодировки: UTF-8 и UTF-16 LE.", + "loc.messages.UnknownFileEncodeError": "Не удается определить кодировку файла %s (typeCode: %s). Поддерживаемые кодировки: UTF-8 и UTF-16 LE.", + "loc.messages.ShortFileBufferError": "Слишком короткий файловый буфер для обнаружения типа кодировки: %s.", + "loc.messages.FailedToUpdateAzureRMWebAppConfigDetails": "Не удалось изменить конфигурацию службы приложений. Ошибка: %s", + "loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails": "Конфигурация службы приложений успешно изменена.", + "loc.messages.RequestedURLforkuduphysicalpath": "Запрошенный URL-адрес для физического пути kudu: %s", + "loc.messages.Physicalpathalreadyexists": "Физический путь \"%s\" уже существует.", + "loc.messages.KuduPhysicalpathCreatedSuccessfully": "Физический путь kudu успешно создан: %s", + "loc.messages.FailedtocreateKuduPhysicalPath": "Не удалось создать физический путь Kudu. Ошибка: %s", + "loc.messages.FailedtocheckphysicalPath": "Не удалось проверить физический путь Kudu. Код ошибки: %s", + "loc.messages.VirtualApplicationDoesNotExist": "Виртуальное приложение не существует: %s", + "loc.messages.JSONParseError": "Не удалось проанализировать JSON-файл: %s. Ошибка: %s", + "loc.messages.JSONvariablesubstitutionappliedsuccessfully": "Подстановка переменных JSON успешно применена.", + "loc.messages.XMLvariablesubstitutionappliedsuccessfully": "Подстановка переменных XML применена.", + "loc.messages.failedtoUploadFileToKudu": "Не удалось отправить файл %s в Kudu (%s). Код состояния: %s", + "loc.messages.failedtoUploadFileToKuduError": "Не удалось передать файл %s в kudu (%s). Ошибка: %s", + "loc.messages.ExecuteScriptOnKudu": "Выполнение указанного скрипта в службе Kudu.", + "loc.messages.FailedToRunScriptOnKuduError": "Не удалось выполнить скрипт в службе Kudu. Ошибка: %s", + "loc.messages.FailedToRunScriptOnKudu": "Не удалось выполнить скрипт в службе Kudu: %s. Код состояния: %s", + "loc.messages.ScriptExecutionOnKuduSuccess": "Сценарий успешно выполнен в Kudu.", + "loc.messages.ScriptExecutionOnKuduFailed": "Выполненный сценарий вернул код \"%s\". Ошибка: %s", + "loc.messages.FailedtoDeleteFileFromKudu": "Не удалось удалить файл %s из Kudu (%s). Код состояния: %s", + "loc.messages.FailedtoDeleteFileFromKuduError": "Не удалось удалить файл %s из kudu (%s). Ошибка: %s", + "loc.messages.ScriptFileNotFound": "Файл сценария \"%s\" не найден.", + "loc.messages.InvalidScriptFile": "Указан недопустимый файл скрипта \"%s\". Допустимые расширения: .bat и .cmd в Windows, .sh в Linux", + "loc.messages.RetryForTimeoutIssue": "Сбои выполнения сценария из-за превышения времени ожидания. Выполняется повторная попытка.", + "loc.messages.stdoutFromScript": "Стандартные выходные данные сценария: ", + "loc.messages.stderrFromScript": "Стандартная ошибка сценария: ", + "loc.messages.WebConfigAlreadyExists": "Файл web.config уже существует. Он не будет сгенерирован.", + "loc.messages.SuccessfullyGeneratedWebConfig": "Файл web.config успешно сгенерирован.", + "loc.messages.FailedToGenerateWebConfig": "Не удалось сгенерировать файл web.config. %s", + "loc.messages.FailedToGetKuduFileContent": "Не удалось получить содержимое файла: %s. Код состояния: %s (%s)", + "loc.messages.FailedToGetKuduFileContentError": "Не удалось получить содержимое файла: %s. Ошибка: %s", + "loc.messages.ScriptStatusTimeout": "Не удалось получить состояние сценария, так как превышено время ожидания.", + "loc.messages.PollingForFileTimeOut": "Не удалось получить состояние сценария, так как превышено время ожидания. Чтобы увеличить время ожидания, задайте для переменной \"appservicedeploy.retrytimeout\" требуемое количество минут.", + "loc.messages.InvalidPollOption": "Указан недопустимый параметр опроса: %s.", + "loc.messages.MissingAppTypeWebConfigParameters": "Атрибут \"-appType\" отсутствует в параметрах Web.config. Допустимые значения для \"-appType\": \"python_Bottle\", \"python_Django\", \"python_Flask\" и \"node\".
Например, \"-appType python_Bottle\" (без кавычек), если используется платформа Python Bottle.", + "loc.messages.AutoDetectDjangoSettingsFailed": "Не удалось обнаружить путь к файлу \"settings.py\" DJANGO_SETTINGS_MODULE. Убедитесь, что файл \"settings.py\" существует, или укажите правильный путь во входных данных параметра Web.config в следующем формате: \"-DJANGO_SETTINGS_MODULE <имя_папки>.settings\".", + "loc.messages.FailedToApplyTransformation": "Не удается применить преобразование для указанного пакета. Проверьте следующее.", + "loc.messages.FailedToApplyTransformationReason1": "1. Применено ли преобразование к созданному пакету MSBuild во время сборки. Если это так, удалите тег для каждой конфигурации в CSPROJ-файле и повторите сборку. ", + "loc.messages.FailedToApplyTransformationReason2": "2. Убедитесь, что файлы конфигурации и преобразования находятся в одной и той же папке в пакете.", + "loc.messages.AutoParameterizationMessage": "Атрибуты ConnectionString в Web.config параметризованы по умолчанию. Обратите внимание, что преобразование не влияет на атрибуты connectionString, так как значение переопределяется во время развертывания файлом \"Parameters.xml\" или \"SetParameters.xml\". Вы можете отключить автоматическую параметризацию, задав /p:AutoParameterizationWebConfigConnectionStrings=False во время создания пакета MSBuild.", + "loc.messages.UnsupportedAppType": "Тип приложения \"%s\" не поддерживается при создании Web.config. Допустимые значения для \"-appType\": \"python_Bottle\", \"python_Django\", \"python_Flask\" и \"node\".", + "loc.messages.UnableToFetchAuthorityURL": "Не удается получить URL-адрес центра.", + "loc.messages.UnableToFetchActiveDirectory": "Не удается получить идентификатор ресурса Active Directory.", + "loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand": "Стек времени выполнения и команда запуска успешно обновлены.", + "loc.messages.FailedToUpdateRuntimeStackAndStartupCommand": "Не удалось обновить стек времени выполнения и команду запуска. Ошибка: %s.", + "loc.messages.SuccessfullyUpdatedWebAppSettings": "Параметры приложения успешно обновлены.", + "loc.messages.FailedToUpdateAppSettingsInConfigDetails": "Не удалось обновить параметры приложения. Ошибка: %s.", + "loc.messages.UnableToGetAzureRMWebAppMetadata": "Не удалось получить метаданные AzureRM WebApp. Код ошибки: %s", + "loc.messages.UnableToUpdateAzureRMWebAppMetadata": "Не удалось обновить метаданные AzureRM WebApp. Код ошибки: %s", + "loc.messages.Unabletoretrieveazureregistrycredentials": "Не удалось получить учетные данные реестра контейнеров Azure. [Код состояния: \"%s\"]", + "loc.messages.UnableToReadResponseBody": "Не удалось прочитать текст ответа. Ошибка: %s", + "loc.messages.UnableToUpdateWebAppConfigDetails": "Не удалось обновить сведения о конфигурации WebApp. StatusCode: \"%s\"", + "loc.messages.AddingReleaseAnnotation": "Добавление примечаний к выпуску для ресурса Application Insights \"%s\"", + "loc.messages.SuccessfullyAddedReleaseAnnotation": "Примечания к выпуску успешно добавлены в Application Insights: %s", + "loc.messages.FailedAddingReleaseAnnotation": "Не удалось добавить примечания к выпуску. %s", + "loc.messages.RenameLockedFilesEnabled": "Переименование заблокированных файлов для службы приложений включено.", + "loc.messages.FailedToEnableRenameLockedFiles": "Не удалось включить переименование заблокированных файлов. Ошибка: %s", + "loc.messages.WebJobsInProgressIssue": "Невозможно удалить файлы в развертывании, так как запущено несколько веб-заданий. Отключите параметр \"Удалить дополнительные файлы в месте назначения\" или остановите непрерывные задания перед развертыванием.", + "loc.messages.FailedToFetchKuduAppSettings": "Не удалось получить параметры приложения Kudu. Ошибка: %s", + "loc.messages.FailedToCreatePath": "Не удалось создать путь \"%s\" из Kudu. Ошибка: %s", + "loc.messages.FailedToDeleteFile": "Не удалось удалить файл \"%s/%s\" из Kudu. Ошибка: %s", + "loc.messages.FailedToUploadFile": "Не удалось отправить файл \"%s/%s\" из Kudu. Ошибка: %s", + "loc.messages.FailedToGetFileContent": "Не удалось получить содержимое файла \"%s/%s\" из Kudu. Ошибка: %s", + "loc.messages.FailedToListPath": "Не удалось получить список элементов для пути \"%s\" из Kudu. Ошибка: %s", + "loc.messages.RetryToDeploy": "Повторная попытка развертывания пакета.", + "loc.messages.FailedToGetAppServiceDetails": "Не удалось получить сведения о службе приложений \"%s\". Ошибка: %s", + "loc.messages.FailedToGetAppServicePublishingProfile": "Не удалось получить профиль публикации для службы приложений \"%s\". Ошибка: %s", + "loc.messages.FailedToUpdateAppServiceMetadata": "Не удалось обновить метаданные службы приложений \"%s\". Ошибка: %s", + "loc.messages.FailedToGetAppServiceMetadata": "Не удалось получить метаданные службы приложений \"%s\". Ошибка: %s", + "loc.messages.FailedToPatchAppServiceConfiguration": "Не удалось изменить конфигурацию службы приложений \"%s\". Ошибка: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "Не удалось обновить конфигурацию службы приложений \"%s\". Ошибка: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "Не удалось получить конфигурацию службы приложений \"%s\". Ошибка: %s", + "loc.messages.FailedToGetAppServicePublishingCredentials": "Не удалось получить учетные данные публикации для службы приложений \"%s\". Ошибка: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "Не удалось получить параметры приложения для службы приложений \"%s\". Ошибка: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "Не удалось обновить параметры приложения для службы приложений \"%s\". Ошибка: %s", + "loc.messages.UpdatingAppServiceConfigurationSettings": "Обновляются параметры конфигурации службы приложений. Данные: %s", + "loc.messages.UpdatedAppServiceConfigurationSettings": "Параметры конфигурации службы приложений обновлены.", + "loc.messages.UpdatingAppServiceApplicationSettings": "Обновляются параметры приложений службы приложений. Данные: %s", + "loc.messages.UpdatedAppServiceApplicationSettings": "Параметры приложений службы приложений и параметры приложений Kudu обновлены.", + "loc.messages.MultipleResourceGroupFoundForAppService": "Для службы приложений \"%s\" найдено несколько групп ресурсов.", + "loc.messages.PackageDeploymentUsingZipDeployFailed": "Не удалось выполнить развертывание пакета с помощью развертывания ZIP-файла. Дополнительные сведения см. в журналах.", + "loc.messages.PackageDeploymentInitiated": "Инициировано развертывание пакета с помощью развертывания ZIP-файла.", + "loc.messages.FailedToGetDeploymentLogs": "Не удалось получить журналы развертывания. Ошибка: %s", + "loc.messages.GoExeNameNotPresent": "Отсутствует имя go exe-файла", + "loc.messages.WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier." +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/zh-CN/resources.resjson b/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/zh-CN/resources.resjson new file mode 100644 index 000000000000..4d91bc096fd9 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/zh-CN/resources.resjson @@ -0,0 +1,219 @@ +{ + "loc.friendlyName": "Azure App Service 部署", + "loc.helpMarkDown": "[详细信息](https://aka.ms/azurermwebdeployreadme)", + "loc.description": "更新 Windows 上的 Azure WebApp 服务、 Linux 上带内置映像或 docker 容器的 Web 应用、基于 ASP.NET、.NET Core、PHP、Python 或 Node 的 Web 应用程序、Function Apps、移动应用、Api 应用程序、使用 Web 部署/ Kudu REST API 的 Web 作业", + "loc.instanceNameFormat": "Azure 应用服务部署: $(WebAppName)", + "loc.releaseNotes": "版本 3.0 中的新增功能:
  支持文件转换(XDT)
  支持变量替换(XML、JSON)
单击[此处](https://aka.ms/azurermwebdeployreadme)了解详细信息。", + "loc.group.displayName.FileTransformsAndVariableSubstitution": "文件转换和变量替换选项", + "loc.group.displayName.AdditionalDeploymentOptions": "其他部署选项", + "loc.group.displayName.PostDeploymentAction": "部署后操作", + "loc.group.displayName.ApplicationAndConfigurationSettings": "应用程序和配置设置", + "loc.group.displayName.output": "输出", + "loc.input.label.ConnectedServiceName": "Azure 订阅", + "loc.input.help.ConnectedServiceName": "为部署选择 Azure 资源管理器订阅。", + "loc.input.label.WebAppKind": "应用类型", + "loc.input.help.WebAppKind": "选择要部署的 web 应用的类型。
注意: 为内置平台映像或自定义容器映像部署选择 Linux Web 应用。", + "loc.input.label.WebAppName": "应用服务名称", + "loc.input.help.WebAppName": "输入或选择现有 Azure 应用服务的名称。只会列出基于所选应用类型的应用服务。", + "loc.input.label.DeployToSlotFlag": "部署到槽", + "loc.input.help.DeployToSlotFlag": "选择该选项以部署到生产槽以外的现有槽。如果不选择此选项,则将 Azure 应用服务部署到生产槽。", + "loc.input.label.ResourceGroupName": "资源组", + "loc.input.help.ResourceGroupName": "输入或选择包含以上指定 Azure 应用服务的 Azure 资源组。", + "loc.input.label.SlotName": "槽", + "loc.input.help.SlotName": "输入或选择生产槽以外的现有槽。", + "loc.input.label.ImageSource": "映像源", + "loc.input.help.ImageSource": "Linux 上的应用服务提供两个不同的选项来发布应用程序
自定义映像部署或使用内置平台映像的应用部署。[了解详细信息](https://go.microsoft.com/fwlink/?linkid=862490)", + "loc.input.label.AzureContainerRegistry": "注册表", + "loc.input.help.AzureContainerRegistry": "特定注册表的全局唯一顶级域名。
注意: 完全限定的映像名称格式为:“`/`:`”。例如,\"myregistry.azurecr.io/nginx:latest\"。", + "loc.input.label.AzureContainerRegistryLoginServer": "注册表登录服务器名称", + "loc.input.help.AzureContainerRegistryLoginServer": "输入或选择 Azure 容器注册表登录服务器名称。", + "loc.input.label.AzureContainerRegistryImage": "映像", + "loc.input.help.AzureContainerRegistryImage": "用于存储容器映像的存储库的名称。
注意: 完全限定的映像名称格式为:“`/`:` ”。例如,\"myregistry.azurecr.io/nginx:latest\"。", + "loc.input.label.AzureContainerRegistryTag": "标记", + "loc.input.help.AzureContainerRegistryTag": "标记为可选项,它是注册表用于为 Docker 映像提供版本的机制。
注意: 完全限定的映像名称格式为:“`/`:`”。例如,\"myregistry.azurecr.io/nginx:latest\"。", + "loc.input.label.DockerRepositoryAccess": "存储库访问", + "loc.input.help.DockerRepositoryAccess": "选择 Docker 存储库访问。", + "loc.input.label.RegistryConnectedServiceName": "注册表连接", + "loc.input.help.RegistryConnectedServiceName": "选择注册表连接。", + "loc.input.label.PrivateRegistryImage": "映像", + "loc.input.help.PrivateRegistryImage": "用于存储容器映像的存储库的名称。
注意: 完全限定的映像名称格式为:“`/`:` ”。例如,\"myregistry.azurecr.io/nginx:latest\"。", + "loc.input.label.PrivateRegistryTag": "标记", + "loc.input.help.PrivateRegistryTag": "标记为可选项,它是注册表用于为 Docker 映像提供版本的机制。
注意: 完全限定的映像名称格式为: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "loc.input.label.DockerNamespace": "注册表或命名空间", + "loc.input.help.DockerNamespace": "特定注册表或命名空间的全局唯一顶级域名。
注意: 完全限定的映像名称格式应为:“`<注册表或命名空间`>/`<存储库`>:`<标记`>”。例如,\"myregistry.azurecr.io/nginx:latest\"。", + "loc.input.label.DockerRepository": "映像", + "loc.input.help.DockerRepository": "用于存储容器映像的存储库的名称。
注意: 完全限定的映像名称格式应为:“`<注册表或命名空间`>/`<存储库`>:`<标记`>”。例如,\"myregistry.azurecr.io/nginx:latest\"。", + "loc.input.label.DockerImageTag": "标记", + "loc.input.help.DockerImageTag": "标记为可选项,它是注册表用以对 Docker 映像提供版本的机制。
注意: 完全限定的映射名称格式应为:“`<注册表或命名空间`>/`<存储库`>:`<标记`>”。例如,\"myregistry.azurecr.io/nginx:latest\"。", + "loc.input.label.VirtualApplication": "虚拟应用程序", + "loc.input.help.VirtualApplication": "指定 Azure 门户中已配置的虚拟应用程序的名称。对于以应用服务根目录为目标的部署,此选项并非必需。", + "loc.input.label.Package": "包或文件夹", + "loc.input.help.Package": "包、包含 MSBuild 生成的应用服务内容的文件夹,或 zip/war 压缩文件的文件路径。
变量( [生成](https://www.visualstudio.com/docs/build/define/variables) | [发布](https://www.visualstudio.com/docs/release/author-release-definition/understanding-tasks#predefvariables)),支持通配符。
例如,$(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip 或 $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.BuiltinLinuxPackage": "包或文件夹", + "loc.input.help.BuiltinLinuxPackage": "包、包含 MSBuild 生成的应用服务内容的文件夹,或 zip/war 压缩文件的文件路径。
变量( [生成](https://www.visualstudio.com/docs/build/define/variables) | [发布](https://www.visualstudio.com/docs/release/author-release-definition/understanding-tasks#predefvariables)),支持通配符。
例如,$(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip 或 $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war.", + "loc.input.label.RuntimeStack": "运行时堆栈", + "loc.input.help.RuntimeStack": "选择框架和版本。", + "loc.input.label.StartupCommand": "启动命令", + "loc.input.help.StartupCommand": "输入启动命令。", + "loc.input.label.WebAppUri": "应用服务 URL", + "loc.input.help.WebAppUri": "指定 Azure 应用服务的 URL 所生成的输出变量名。该变量可在后续任务中使用。", + "loc.input.label.ScriptType": "部署脚本类型", + "loc.input.help.ScriptType": "任务成功完成部署后,通过提供可在 Azure 应用服务上运行的脚本自定义部署。例如 Node、PHP 和 Python 应用程序的还原包。[了解详细信息](https://go.microsoft.com/fwlink/?linkid=843471)。", + "loc.input.label.InlineScript": "内联脚本", + "loc.input.label.ScriptPath": "部署脚本路径", + "loc.input.label.GenerateWebConfig": "生成 Web.config", + "loc.input.help.GenerateWebConfig": "如果应用程序中没有标准 Web.config,系统将生成标准 Web.config 并将其部署到 Azure 应用服务。Web.config 中的值可编辑,并且应用程序框架不同,值会有所不同。例如,针对 node.js 应用程序,web.config 将包含启动文件和 iis_node module 值。[了解详细信息](https://go.microsoft.com/fwlink/?linkid=843469)。", + "loc.input.label.WebConfigParameters": "Web.config 参数", + "loc.input.help.WebConfigParameters": "在所生成的 web.config 文件中编辑启动文件等值。此编辑功能仅适用于所生成的 web.config。[了解详细信息](https://go.microsoft.com/fwlink/?linkid=843469)。", + "loc.input.label.AppSettings": "应用设置", + "loc.input.help.AppSettings": "按照语法 -key 值编辑 Web 应用应用程序设置。包含空格的值应括在双引号中。
示例: -Port 5000 -RequestTimeout
-WEBSITE_TIME_ZONE \"Eastern Standard Time\"", + "loc.input.label.ConfigurationSettings": "配置设置", + "loc.input.help.ConfigurationSettings": "按照语法 -key 值编辑 Web 应用配置设置。包含空格的值应括在双引号中。
示例: -phpVersion 5.6 -linuxFxVersion: node|6.11", + "loc.input.label.TakeAppOfflineFlag": "使应用脱机", + "loc.input.help.TakeAppOfflineFlag": "选择该选项,通过在同步操作开始前将 app_offline.htm 文件放入应用服务的根目录而使 Azure 应用服务脱机。同步操作成功完成后,将删除该文件。", + "loc.input.label.UseWebDeploy": "使用 Web 部署发布", + "loc.input.help.UseWebDeploy": "仅当使用 Windows 代理时才支持使用 Web 部署选项进行发布。其他平台上,任务依赖于 [Kudu REST API](https://github.com/projectkudu/kudu/wiki/REST-API) 来部署 Azure 应用服务。以下选项不受支持", + "loc.input.label.SetParametersFile": "SetParameters 文件", + "loc.input.help.SetParametersFile": "可选: 要使用的 SetParameters.xml 文件的位置。", + "loc.input.label.RemoveAdditionalFilesFlag": "删除目标中的其他文件", + "loc.input.help.RemoveAdditionalFilesFlag": "选择该选项可删除 Azure 应用服务上在应用服务包或文件夹中没有匹配文件的文件。

注意: 这该将删除与安装在此 Azure 应用服务上的任何扩展相关的所有文件。为防止出现这种情况,请选中“从 App_Data 文件夹中排除文件”复选框。", + "loc.input.label.ExcludeFilesFromAppDataFlag": "排除 App_Data 文件夹中的文件", + "loc.input.help.ExcludeFilesFromAppDataFlag": "选择该选项以阻止将 App_Data 文件夹中的文件部署到 Azure 应用服务。", + "loc.input.label.AdditionalArguments": "其他参数", + "loc.input.help.AdditionalArguments": "语法 -key:value 后的其他 Web 部署参数。
部署 Azure 应用服务时将应用这些参数。例如: -disableLink:AppPoolExtension -disableLink:ContentExtension。
有关 Web 部署操作设置的更多示例,请参阅[此处](https://go.microsoft.com/fwlink/?linkid=838471)。", + "loc.input.label.RenameFilesFlag": "重命名锁定的文件", + "loc.input.help.RenameFilesFlag": "选择此选项可在 Azure 应用服务应用程序设置中启用 msdeploy 标志 MSDEPLOY_RENAME_LOCKED_FILES=1。如果设定,此选项可使 msdeploy 重命名在应用部署期间锁定的锁定文件", + "loc.input.label.XmlTransformation": "XML 转换", + "loc.input.help.XmlTransformation": "将在 \"*.config file\" 上为 \"*.Release.config\" 和 \"*..config\" 运行配置转换。
配置转换将在变量替换前运行。
仅 Windows 平台支持 XML 转换。", + "loc.input.label.XmlVariableSubstitution": "XML 变量替换", + "loc.input.help.XmlVariableSubstitution": "在生成或发布定义中定义的变量将根据任何配置文件和 parameters.xml 的 appSettings、applicationSettings 和 connectionStrings 部分中的“密钥”或“名称”条目进行匹配。变量替换在配置转换后运行。

注意: 如果在生成定义和环境中定义了相同的变量,则环境变量将取代发布定义变量。
", + "loc.input.label.JSONFiles": "JSON 变量替换", + "loc.input.help.JSONFiles": "提供 JSON 文件的新行分隔列表以替换变量值。将提供涉及根文件夹的文件名。
若要替换嵌套或分层 JSON 变量,请使用 JSONPath 表达式指定它们。

例如,若要替换下例中 \"ConnectionString\" 的值,需要在版本/发行定义(或发行定义环境)中将变量定义为 \"Data.DefaultConnection.ConnectionString\"。
{
  \"Data\": {
    \"DefaultConnection\": {
      \"ConnectionString\": \"Server=(localdb)\\SQLEXPRESS;Database=MyDB;Trusted_Connection=True\"
    }
  }
}
配置转换后运行变量替换。

注意: 替换中不包含内部版本/发行版的系统定义变量", + "loc.messages.Invalidwebapppackageorfolderpathprovided": "提供了无效的应用服务包或文件夹路径: %s", + "loc.messages.SetParamFilenotfound0": "设置的参数文件未找到: %s", + "loc.messages.XDTTransformationsappliedsuccessfully": "XML 转换已成功应用", + "loc.messages.GotconnectiondetailsforazureRMWebApp0": "已获取 Azure 应用服务 \"%s\" 的连接详细信息", + "loc.messages.ErrorNoSuchDeployingMethodExists": "错误: 不存在此种部署方法", + "loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp": "无法检索 Azure 应用服务 %s 的连接详细信息。状态代码: %s (%s)", + "loc.messages.UnabletoretrieveResourceID": "无法检索 Azure 资源“%s”的连接详细信息。状态代码: %s", + "loc.messages.CouldnotfetchaccesstokenforAzureStatusCode": "无法提取 Azure 的访问令牌。状态代码: %s (%s)", + "loc.messages.Successfullyupdateddeploymenthistory": "已成功在 %s 更新了部署历史记录", + "loc.messages.Failedtoupdatedeploymenthistory": "未能更新部署历史记录。错误: %s", + "loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "警告: 无法更新部署状态: SCM 终结点没有为此网站启用", + "loc.messages.Unabletoretrievewebconfigdetails": "无法检索应用配置详细信息。状态代码:“%s”", + "loc.messages.Unabletoretrievewebappsettings": "无法检索应用服务应用程序设置。[状态代码: %s, 错误消息: %s]", + "loc.messages.Unabletoupdatewebappsettings": "无法更新应用服务应用程序设置。状态代码:“%s”", + "loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "无法更新部署状态: 无法检索唯一部署 ID", + "loc.messages.PackageDeploymentSuccess": "已成功将 Web 包部署到应用服务。", + "loc.messages.PackageDeploymentFailed": "未能将 Web 包部署到应用服务。", + "loc.messages.Runningcommand": "正在运行命令: %s", + "loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath": "正在部署 Web 包 %s,部署位置: 虚拟路径 %s (物理路径 %s)", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "已成功部署了包 %s (通过在 %s 使用 kudu 服务)", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "未能使用 kudu 服务 %s 部署应用服务包", + "loc.messages.Unabletodeploywebappresponsecode": "错误代码 %s 导致无法部署应用服务", + "loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "MSDeploy 生成的包仅受 Windows 平台支持。", + "loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "为 MSDeploy 找到了不受支持的已安装版本 %s。版本应至少为 3 或以上", + "loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError": "无法从计算机的注册表上找到 MS 部署的位置(错误: %s)", + "loc.messages.Nopackagefoundwithspecifiedpattern": "使用指定模式 %s 未找到任何包", + "loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "指定的模式 %s 有多个匹配的包。请限制搜索模式。", + "loc.messages.Trytodeploywebappagainwithappofflineoptionselected": "再次尝试使用所选“使应用程序脱机”选项部署应用服务。", + "loc.messages.Trytodeploywebappagainwithrenamefileoptionselected": "再次尝试使用所选“重命名锁定文件”选项部署应用服务。", + "loc.messages.NOJSONfilematchedwithspecificpattern": "没有与特定模式 %s 匹配的 JSON 文件。", + "loc.messages.Configfiledoesntexists": "配置文件 %s 不存在。", + "loc.messages.Failedtowritetoconfigfilewitherror": "未能写入配置文件 %s,错误为 %s", + "loc.messages.AppOfflineModeenabled": "已启用应用脱机模式。", + "loc.messages.Failedtoenableappofflinemode": "未能启用应用脱机模式。状态代码: %s (%s)", + "loc.messages.AppOflineModedisabled": "已禁用应用脱机模式。", + "loc.messages.FailedtodisableAppOfflineMode": "未能禁用应用脱机模式。状态代码: %s (%s)", + "loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform": "无法在非 Windows 平台上执行 XML 转换。", + "loc.messages.XdtTransformationErrorWhileTransforming": "转换 %s (通过使用 %s)时出现 XML 转换错误。", + "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "仅当使用 Windows 代理时才支持使用 webdeploy 选项进行发布", + "loc.messages.ResourceDoesntExist": "资源“%s”不存在。资源应在部署前就已存在。", + "loc.messages.EncodeNotSupported": "检测到文件 %s 的文件编码为 %s。不支持使用文件编码 %s 进行变量替换。受支持的编码为 UTF-8 和 UTF-16 LE。", + "loc.messages.UnknownFileEncodeError": "无法检测文件 %s (类型代码: %s)的编码。受支持的编码为 UTF-8 和 UTF-16 LE。", + "loc.messages.ShortFileBufferError": "文件缓冲区太短,无法检测编码类型: %s", + "loc.messages.FailedToUpdateAzureRMWebAppConfigDetails": "未能更新应用服务配置详细信息。错误: %s", + "loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails": "已成功更新应用服务配置详细信息。", + "loc.messages.RequestedURLforkuduphysicalpath": "kudu 物理路径的请求 URL: %s", + "loc.messages.Physicalpathalreadyexists": "物理路径 \"%s\" 已存在", + "loc.messages.KuduPhysicalpathCreatedSuccessfully": "Kudu 物理路径已成功创建: %s", + "loc.messages.FailedtocreateKuduPhysicalPath": "未能创建 kudu 物理路径。错误: %s", + "loc.messages.FailedtocheckphysicalPath": "未能检查 kudu 物理路径。错误代码: %s", + "loc.messages.VirtualApplicationDoesNotExist": "不存在虚拟应用程序: %s", + "loc.messages.JSONParseError": "无法分析 JSON 文件: %s。错误: %s", + "loc.messages.JSONvariablesubstitutionappliedsuccessfully": "JSON 变量替换已成功应用。", + "loc.messages.XMLvariablesubstitutionappliedsuccessfully": "已成功应用 XML 变量替换。", + "loc.messages.failedtoUploadFileToKudu": "无法将文件 %s 上传到 Kudu (%s)。状态代码: %s", + "loc.messages.failedtoUploadFileToKuduError": "无法将文件 %s 上传到 Kudu (%s)。错误: %s", + "loc.messages.ExecuteScriptOnKudu": "正在 Kudu 服务上执行给定脚本。", + "loc.messages.FailedToRunScriptOnKuduError": "无法在 Kudu 服务上运行该脚本。错误: %s", + "loc.messages.FailedToRunScriptOnKudu": "无法在 Kudu 上运行该脚本: %s。状态代码: %s", + "loc.messages.ScriptExecutionOnKuduSuccess": "已成功在 Kudu 上执行脚本。", + "loc.messages.ScriptExecutionOnKuduFailed": "已执行的脚本返回了“%s”作为返回代码。错误: %s", + "loc.messages.FailedtoDeleteFileFromKudu": "无法从 Kudu (%s) 删除文件: %s。状态代码: %s", + "loc.messages.FailedtoDeleteFileFromKuduError": "无法删除文件 %s (位于 Kudu (%s)上)。错误: %s", + "loc.messages.ScriptFileNotFound": "找不到脚本文件“%s”。", + "loc.messages.InvalidScriptFile": "提供的脚本文件“%s”无效。有效的扩展名为 .bat 和 .cmd (对于 Windows)和 .sh (对于 Linux)", + "loc.messages.RetryForTimeoutIssue": "由于出现超时问题,脚本执行失败。请重试。", + "loc.messages.stdoutFromScript": "脚本中的标准输出:", + "loc.messages.stderrFromScript": "脚本中的标准错误:", + "loc.messages.WebConfigAlreadyExists": "web.config 文件已存在。不再生成。", + "loc.messages.SuccessfullyGeneratedWebConfig": "已成功生成 web.config 文件", + "loc.messages.FailedToGenerateWebConfig": "未能生成 web.config。%s", + "loc.messages.FailedToGetKuduFileContent": "无法获取文件内容: %s。状态代码: %s (%s)", + "loc.messages.FailedToGetKuduFileContentError": "无法获取文件内容: %s。错误: %s", + "loc.messages.ScriptStatusTimeout": "因为超时,无法提取脚本状态。", + "loc.messages.PollingForFileTimeOut": "因为超时,无法提取脚本状态。通过将 \"appservicedeploy.retrytimeout\" 变量设置为所需分钟数可以增加超时限制。", + "loc.messages.InvalidPollOption": "提供的轮询选项无效: %s。", + "loc.messages.MissingAppTypeWebConfigParameters": "Web.config 参数中缺少属性 \"-appType\"。\"-appType\" 的有效值为: \"python_Bottle\"、\"python_Django\"、\"python_Flask\" 和 \"node\"。
例如,\"-appType python_Bottle\" (sans-quotes)用于 Python Bottle 框架..", + "loc.messages.AutoDetectDjangoSettingsFailed": "无法检测 DJANGO_SETTINGS_MODULE \"settings.py\" 文件路径。请确保 \"settings.py\" 文件存在或采用格式 \"-DJANGO_SETTINGS_MODULE .settings\" 在 Web.config 参数输出中提供正确的路径", + "loc.messages.FailedToApplyTransformation": "无法对给定的包应用转换。请验证以下各项。", + "loc.messages.FailedToApplyTransformationReason1": "1. 在生成期间是否已对 MSBuild 生成的包应用转换。如果已应用,请删除 csproj 文件中每个配置的 标记,然后重新生成。", + "loc.messages.FailedToApplyTransformationReason2": "2. 确保配置文件和转换文件位于包内的同一个文件夹中。", + "loc.messages.AutoParameterizationMessage": "默认情况下,Web.config 中的 connectionString 属性已参数化。请注意,转换对 connectionString 属性无影响,因为在通过 \"Parameters.xml\" 或 \"SetParameters.xml\" 文件进行部署期间,该值将被重写。可通过在 MSBuild 包生成期间设置 /p:AutoParameterizationWebConfigConnectionStrings=False 来禁用自动参数化。", + "loc.messages.UnsupportedAppType": "Web.config 生成中不支持应用类型 \"%s\"。\"-appType\" 的有效值为: \"python_Bottle\"、\"python_Django\"、\"python_Flask\" 和 \"node\"", + "loc.messages.UnableToFetchAuthorityURL": "无法提取授权 URL。", + "loc.messages.UnableToFetchActiveDirectory": "无法提取 Active Directory 资源 ID。", + "loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand": "已成功更新运行时堆栈和启动命令。", + "loc.messages.FailedToUpdateRuntimeStackAndStartupCommand": "未能更新运行时堆栈和启动命令。错误: %s。", + "loc.messages.SuccessfullyUpdatedWebAppSettings": "已成功更新应用设置。", + "loc.messages.FailedToUpdateAppSettingsInConfigDetails": "未能更新应用设置。错误: %s。", + "loc.messages.UnableToGetAzureRMWebAppMetadata": "未能提取 AzureRM WebApp 元数据。错误代码: %s", + "loc.messages.UnableToUpdateAzureRMWebAppMetadata": "无法更新 AzureRM WebApp 元数据。错误代码: %s", + "loc.messages.Unabletoretrieveazureregistrycredentials": "无法检索 Azure 容器注册表凭据。[状态代码:“%s”]", + "loc.messages.UnableToReadResponseBody": "无法读取响应正文。错误: %s", + "loc.messages.UnableToUpdateWebAppConfigDetails": "无法更新 WebApp 配置详细信息。状态代码:“%s”", + "loc.messages.AddingReleaseAnnotation": "正在添加 Application Insights 资源“%s”的发布注释", + "loc.messages.SuccessfullyAddedReleaseAnnotation": "已成功向 Application Insights 添加发布注释: %s", + "loc.messages.FailedAddingReleaseAnnotation": "未能添加发布注释。%s", + "loc.messages.RenameLockedFilesEnabled": "已对应用服务启用“重命名已锁定文件”。", + "loc.messages.FailedToEnableRenameLockedFiles": "未能启用“重命名已锁定文件”。错误: %s", + "loc.messages.WebJobsInProgressIssue": "几个处于运行状态的 Web 作业阻止部署删除这些文件。可禁用“删除目标处的其他文件”选项或在部署前停止持续作业。", + "loc.messages.FailedToFetchKuduAppSettings": "未能提取 Kudu 应用设置。错误: %s", + "loc.messages.FailedToCreatePath": "未能从 Kudu 创建路径“%s”。错误: %s", + "loc.messages.FailedToDeleteFile": "未能从 Kudu 删除文件“%s/%s”。错误: %s", + "loc.messages.FailedToUploadFile": "未能从 Kudu 上传文件“%s/%s”。错误: %s", + "loc.messages.FailedToGetFileContent": "未能从 Kudu 获取文件内容“%s/%s”。错误: %s", + "loc.messages.FailedToListPath": "未能从 Kudu 列出路径“%s”。错误: %s", + "loc.messages.RetryToDeploy": "正在重新尝试部署包。", + "loc.messages.FailedToGetAppServiceDetails": "未能提取应用服务“%s”详细信息。错误: %s", + "loc.messages.FailedToGetAppServicePublishingProfile": "未能提取应用服务“%s”发布配置文件。错误: %s", + "loc.messages.FailedToUpdateAppServiceMetadata": "未能更新应用服务“%s”元数据。错误: %s", + "loc.messages.FailedToGetAppServiceMetadata": "未能获取应用服务“%s”元数据。错误: %s", + "loc.messages.FailedToPatchAppServiceConfiguration": "未能修补应用服务“%s”配置。错误: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "未能更新应用服务“%s”配置。错误: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "未能获取应用服务“%s”配置。错误: %s", + "loc.messages.FailedToGetAppServicePublishingCredentials": "未能提取应用服务“%s”发布凭据。错误: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "未能获取应用服务“%s”应用程序设置。错误: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "未能更新应用服务“%s”应用程序设置。错误: %s", + "loc.messages.UpdatingAppServiceConfigurationSettings": "正在更新应用服务配置设置。数据: %s", + "loc.messages.UpdatedAppServiceConfigurationSettings": "已更新应用服务配置设置。", + "loc.messages.UpdatingAppServiceApplicationSettings": "正在更新应用服务应用程序设置。数据: %s", + "loc.messages.UpdatedAppServiceApplicationSettings": "已更新应用服务应用程序设置和 Kudu 应用程序设置。", + "loc.messages.MultipleResourceGroupFoundForAppService": "找到了应用服务“%s”的多个资源组。", + "loc.messages.PackageDeploymentUsingZipDeployFailed": "使用 ZIP 部署的包部署失败。有关更多详细信息,请参阅日志。", + "loc.messages.PackageDeploymentInitiated": "已启动使用 ZIP 部署的包部署。", + "loc.messages.FailedToGetDeploymentLogs": "未能获取部署日志。错误: %s", + "loc.messages.GoExeNameNotPresent": "Go exe 名称不存在", + "loc.messages.WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier." +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/zh-TW/resources.resjson b/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/zh-TW/resources.resjson new file mode 100644 index 000000000000..804f77f302b0 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Strings/resources.resjson/zh-TW/resources.resjson @@ -0,0 +1,219 @@ +{ + "loc.friendlyName": "Azure App Service 部署", + "loc.helpMarkDown": "[詳細資訊](https://aka.ms/azurermwebdeployreadme)", + "loc.description": "使用 Web Deploy/Kudu REST API,來更新 Windows 上的 Azure WebApp 服務、Linux 上具內建映像或 Docker 容器的 Web App、.NET Core、PHP、Python 或節點 Web 應用程式、函數應用程式、行動應用程式、API 應用程式、WebJob", + "loc.instanceNameFormat": "Azure App Service 部署: $(WebAppName)", + "loc.releaseNotes": "3.0 版的新功能:
  支援檔案轉換 (XDT)
  支援變數替代 (XML、JSON)
如需詳細資訊,請按一下[這裡](https://aka.ms/azurermwebdeployreadme)。", + "loc.group.displayName.FileTransformsAndVariableSubstitution": "檔案轉換及變數替代選項", + "loc.group.displayName.AdditionalDeploymentOptions": "其他部署選項", + "loc.group.displayName.PostDeploymentAction": "部署後動作", + "loc.group.displayName.ApplicationAndConfigurationSettings": "應用程式和組態設定", + "loc.group.displayName.output": "輸出", + "loc.input.label.ConnectedServiceName": "Azure 訂用帳戶", + "loc.input.help.ConnectedServiceName": "選取部署的 Azure Resource Manager 訂用帳戶。", + "loc.input.label.WebAppKind": "應用程式類型", + "loc.input.help.WebAppKind": "選取要部署的 Web 應用程式類型。
注意: 請為內建平台映像或自訂容器映像部署選取 Linux Web 應用程式。", + "loc.input.label.WebAppName": "App Service 名稱", + "loc.input.help.WebAppName": "輸入或選取現有 Azure App Service 的名稱。僅依選取的應用程式類型列出應用程式服務。", + "loc.input.label.DeployToSlotFlag": "部署到位置", + "loc.input.help.DeployToSlotFlag": "選取此選項可部署到現有的位置,而不是生產位置。若未選取此選項,Azure App Service 會部署到生產位置。", + "loc.input.label.ResourceGroupName": "資源群組", + "loc.input.help.ResourceGroupName": "輸入或選取包含上列指定之 Azure App Service 的 Azure 資源群組。", + "loc.input.label.SlotName": "位置", + "loc.input.help.SlotName": "請輸入或選取現有的位置,而不是生產位置。", + "loc.input.label.ImageSource": "映像來源", + "loc.input.help.ImageSource": "Linux 上的 App Service 提供兩種不同選項讓您發佈應用程式
使用內建平台映像自訂映像部署或應用程式部署。[深入了解](https://go.microsoft.com/fwlink/?linkid=862490)", + "loc.input.label.AzureContainerRegistry": "登錄", + "loc.input.help.AzureContainerRegistry": "您特定登錄專用的全域唯一頂層網域名稱。
注意: 完整映像名稱的格式為: '`<登錄`>/`<存放庫`>:`<標籤`>'。例如,'myregistry.azurecr.io/nginx:latest'。", + "loc.input.label.AzureContainerRegistryLoginServer": "登錄登入伺服器名稱", + "loc.input.help.AzureContainerRegistryLoginServer": "輸入或選取 Azure Container Registry 登入伺服器名稱。", + "loc.input.label.AzureContainerRegistryImage": "映像", + "loc.input.help.AzureContainerRegistryImage": "容器映像儲存所在的存放庫名稱。
注意: 完整映像名稱的格式為: '`<登錄>/`<存放庫`>:`<標籤`>'。例如,'myregistry.azurecr.io/nginx:latest'。", + "loc.input.label.AzureContainerRegistryTag": "標籤", + "loc.input.help.AzureContainerRegistryTag": "標籤為選擇性項目,這是登錄提供版本給 Docker 映像時使用的機制。
注意: 完整映像名稱的格式為: '`<登錄`>/`<存放庫`>:`<標籤`>'。例如,'myregistry.azurecr.io/nginx:latest'。", + "loc.input.label.DockerRepositoryAccess": "存放庫存取", + "loc.input.help.DockerRepositoryAccess": "選取 Docker 存放庫存取。", + "loc.input.label.RegistryConnectedServiceName": "登錄連線", + "loc.input.help.RegistryConnectedServiceName": "選取登錄連線。", + "loc.input.label.PrivateRegistryImage": "映像", + "loc.input.help.PrivateRegistryImage": "容器映像儲存所在的存放庫名稱。
注意: 完整映像名稱的格式為: '`<登錄>/`<存放庫`>:`<標籤`>'。例如,'myregistry.azurecr.io/nginx:latest'。", + "loc.input.label.PrivateRegistryTag": "標籤", + "loc.input.help.PrivateRegistryTag": "標籤為選擇性項目,這是登錄提供版本給 Docker 映像時使用的機制。
注意: 完整映像名稱的格式為: '`<登錄`>/`<存放庫`>:`<標籤`>'。例如,'myregistry.azurecr.io/nginx:latest'。", + "loc.input.label.DockerNamespace": "登錄或命名空間", + "loc.input.help.DockerNamespace": "您的特定登錄或命名空間的全域唯一頂層網域名稱。
注意: 完整映像名稱的格式為: '`<登錄或命名空間`>/`<存放庫`>:`<標記`>。例如,'myregistry.azurecr.io/nginx:latest'。", + "loc.input.label.DockerRepository": "映像", + "loc.input.help.DockerRepository": "容器映像儲存所在的存放庫名稱。
注意: 完整映像名稱的格式為: '`<登錄或命名空間`>/`<存放庫`>:`<標記`>'。例如,'myregistry.azurecr.io/nginx:latest'。", + "loc.input.label.DockerImageTag": "標記", + "loc.input.help.DockerImageTag": "標記是選擇項,這是登錄提供版本給 Docker 映像時所使用的機制。
注意: 完整映像名稱的格式為: '`<登錄或命名空間`>/`<存放庫`>:`<標記`>'。例如,'myregistry.azurecr.io/nginx:latest'。", + "loc.input.label.VirtualApplication": "虛擬應用程式", + "loc.input.help.VirtualApplication": "指定在 Azure 入口網站中設定的虛擬應用程式名稱。若要部署到 App Service 的根目錄,則無須使用此選項。", + "loc.input.label.Package": "套件或資料夾", + "loc.input.help.Package": "套件或資料夾 (內含 MSBuild 或壓縮的 ZIP 或 WAR 檔案所產生之 App Service 內容) 的檔案路徑。
支援變數 ( [Build](https://www.visualstudio.com/docs/build/define/variables) | [Release](https://www.visualstudio.com/docs/release/author-release-definition/understanding-tasks#predefvariables))、萬用字元。
例如 $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip 或 $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war。", + "loc.input.label.BuiltinLinuxPackage": "套件或資料夾", + "loc.input.help.BuiltinLinuxPackage": "套件或資料夾 (內含 MSBuild 或壓縮的 ZIP 或 WAR 檔案所產生之 App Service 內容) 的檔案路徑。
支援變數 ( [Build](https://www.visualstudio.com/docs/build/define/variables) | [Release](https://www.visualstudio.com/docs/release/author-release-definition/understanding-tasks#predefvariables))、萬用字元。
例如 $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip 或 $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war。", + "loc.input.label.RuntimeStack": "執行階段堆疊", + "loc.input.help.RuntimeStack": "選取架構及版本。", + "loc.input.label.StartupCommand": "啟動命令 ", + "loc.input.help.StartupCommand": "輸入啟動命令。", + "loc.input.label.WebAppUri": "App Service URL", + "loc.input.help.WebAppUri": "指定替 Azure App Service 的 URL 所產生的輸出變數名稱。後續工作可使用該變數。", + "loc.input.label.ScriptType": "部署指令碼類型", + "loc.input.help.ScriptType": "當工作已成功完成部署時,就提供將在 Azure App Service 上執行的指令碼以自訂部署。例如,還原 Node、PHP、Python 應用程式的套件。[深入了解](https://go.microsoft.com/fwlink/?linkid=843471)。", + "loc.input.label.InlineScript": "內嵌指令碼", + "loc.input.label.ScriptPath": "部署指令碼路徑", + "loc.input.label.GenerateWebConfig": "產生 Web.config", + "loc.input.help.GenerateWebConfig": "若應用程式不具標準的 Web.config,將會為其產生,然後部署到 Azure App Service。web.config 中的值可以編輯,但會隨應用程式架構而不同。例如 node.js 應用程式的 web.config 將會包含啟動檔案及 iis_node 模組值。[深入了解](https://go.microsoft.com/fwlink/?linkid=843469)。", + "loc.input.label.WebConfigParameters": "Web.config 參數", + "loc.input.help.WebConfigParameters": "編輯所產生之 web.config 檔案中的值,例如啟動檔案。此功能只適用於所產生的 web.config。[深入了解](https://go.microsoft.com/fwlink/?linkid=843469)。", + "loc.input.label.AppSettings": "應用程式設定", + "loc.input.help.AppSettings": "編輯 web 應用程式應用程式設定,請使用下列語法-機碼值。包含空白的值應以雙引號括住。
範例:-5000,連接埠 5000-RequestTimeout
-WEBSITE_TIME_ZONE\"美國東部標準時間\"", + "loc.input.label.ConfigurationSettings": "組態設定", + "loc.input.help.ConfigurationSettings": "編輯 web 應用程式組態設定,請使用下列語法-機碼值。包含空白的值應以雙引號括住。
範例:-phpVersion 5.6 linuxFxVersion: 節點|6.11", + "loc.input.label.TakeAppOfflineFlag": "將應用程式設為離線", + "loc.input.help.TakeAppOfflineFlag": "選取此選項可在同步作業開始之前,將 app_offline.htm 檔案置於 App Service 的根目錄中而使此 Azure App Service 離線。此檔案將會在同步作業成功完成後移除。", + "loc.input.label.UseWebDeploy": "使用 Web Deploy 發佈", + "loc.input.help.UseWebDeploy": "僅限在使用 Windows 代理程式時才支援使用 [Web Deploy] 選項發佈。工作在其他平台上依賴 [Kudu REST API](https://github.com/projectkudu/kudu/wiki/REST-API) 部署 Azure App Service,且不支援下列選項", + "loc.input.label.SetParametersFile": "SetParameters 檔案", + "loc.input.help.SetParametersFile": "選擇性: 要使用之 SetParameters.xml 檔案的位置。", + "loc.input.label.RemoveAdditionalFilesFlag": "移除目的地的其他檔案", + "loc.input.help.RemoveAdditionalFilesFlag": "選取此選項可刪除在 Azure App Service 上,於 App Service 套件或資料夾中沒有任何相符檔案的檔案。

注意: 這也會移除與此 Azure App Service 上所安裝之任何延伸模組相關的所有檔案。若要避免,請選取 'Exclude files from App_Data folder' 核取方塊。 ", + "loc.input.label.ExcludeFilesFromAppDataFlag": "排除 App_Data 資料夾內的檔案", + "loc.input.help.ExcludeFilesFromAppDataFlag": "選取此選項可避免將 App_Data 資料夾下的檔案部署到 Azure App Service。", + "loc.input.label.AdditionalArguments": "其他引數", + "loc.input.help.AdditionalArguments": "其他 Web Deploy 引數,接在 -key:value 語法後方。
部署 Azure App Service 時會加以套用。例如: -disableLink:AppPoolExtension -disableLink:ContentExtension。
如需其他 Web Deploy 作業設定範例,請參閱[這裡](https://go.microsoft.com/fwlink/?linkid=838471)。", + "loc.input.label.RenameFilesFlag": "重新命名鎖定的檔案", + "loc.input.help.RenameFilesFlag": "選取此選項可在 Azure App Service 應用程式設定中啟用 MSDeploy 旗標 MSDEPLOY_RENAME_LOCKED_FILES=1。若設定此選項,MSDeploy 即可為鎖定於應用程式部署期間的鎖定檔案重新命名", + "loc.input.label.XmlTransformation": "XML 轉換", + "loc.input.help.XmlTransformation": "將為 `*.config file` 上 `*.Release.config` 及 `*.<環境名稱>.config` 執行的組態轉換。
將會在變數替代前執行組態轉換。
只有在 Windows 平台上才支援 XML 轉換。", + "loc.input.label.XmlVariableSubstitution": "XML 變數替代", + "loc.input.help.XmlVariableSubstitution": "組建或發行定義中定義的變數,會與組態檔及 parameters.xml 中之 appSettings、applicationSettings 及 connectionStrings 的 'key' 或 'name' 項目進行比對。變數替代會在組態轉換後執行。

注意: 若發行定義與環境所定義的變數相同,則環境變數會取代發行定義變數。
", + "loc.input.label.JSONFiles": "JSON 變數替代", + "loc.input.help.JSONFiles": "提供 JSON 檔案的換行分隔清單以替代變數值。檔案名稱將相對於根資料夾予以提供。
若要替代巢狀或階層式 JSON 變數,請使用 JSONPath 運算式加以指定。

例如,若要取代下方範例中 ‘ConnectionString’ 的值,您需要在組建/發行定義 (或發行定義的環境) 中將變數定義為 ‘Data.DefaultConnection.ConnectionString’。
{
  \"Data\": {
    \"DefaultConnection\": {
      \"ConnectionString\": \"Server=(localdb)\\SQLEXPRESS;Database=MyDB;Trusted_Connection=True\"
    }
  }
}
變數替代會在組態轉換後執行。

注意: 組建/發行的系統定義會排除在替代之外", + "loc.messages.Invalidwebapppackageorfolderpathprovided": "提供的 App Service 套件或資料夾路徑無效: %s", + "loc.messages.SetParamFilenotfound0": "找不到設定參數檔案: %s", + "loc.messages.XDTTransformationsappliedsuccessfully": "已成功套用 XML 轉換", + "loc.messages.GotconnectiondetailsforazureRMWebApp0": "取得 Azure App Service 的連線詳細資料: '%s'", + "loc.messages.ErrorNoSuchDeployingMethodExists": "錯誤: 此類部署方法不存在", + "loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp": "無法擷取 Azure App Service 的連線詳細資料: %s。狀態碼: %s (%s)", + "loc.messages.UnabletoretrieveResourceID": "無法擷取 Azure 資源的連線詳細資料: '%s'。狀態碼: %s", + "loc.messages.CouldnotfetchaccesstokenforAzureStatusCode": "無法擷取 Azure 的存取權杖。狀態碼: %s (%s)", + "loc.messages.Successfullyupdateddeploymenthistory": "已成功於 %s 更新部署歷程記錄", + "loc.messages.Failedtoupdatedeploymenthistory": "無法更新部署歷程記錄。錯誤: %s", + "loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "警告: 無法更新部署狀態: 此網站未啟用 SCM 端點", + "loc.messages.Unabletoretrievewebconfigdetails": "無法擷取 App Service 組態詳細資料。狀態碼: '%s'", + "loc.messages.Unabletoretrievewebappsettings": "無法擷取 App Service 應用程式設定。[狀態碼: '%s',錯誤訊息: '%s']", + "loc.messages.Unabletoupdatewebappsettings": "無法更新 App Service 應用程式設定。狀態碼: '%s'", + "loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "無法更新部署狀態: 無法擷取唯一部署識別碼", + "loc.messages.PackageDeploymentSuccess": "已成功將 Web 套件部署到 App Service。", + "loc.messages.PackageDeploymentFailed": "無法將 Web 套件部署到 App Service。", + "loc.messages.Runningcommand": "正在執行命令: %s", + "loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath": "正於虛擬路徑 (實體路徑) 部署網頁套件 %s: %s (%s)", + "loc.messages.Successfullydeployedpackageusingkuduserviceat": "已成功使用 Kudu 服務部署套件 %s 於 %s ", + "loc.messages.Failedtodeploywebapppackageusingkuduservice": "無法部署使用 Kudu 服務的 App Service 套件: %s", + "loc.messages.Unabletodeploywebappresponsecode": "因以下錯誤碼而無法部署 App Service: %s", + "loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "僅 Windows 平台支援 MSDeploy 產生的套件。", + "loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "發現對 MSDeploy 安裝了不受支援的版本: %s。版本至少應為 3 (含) 以上", + "loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError": "電腦上的登錄找不到 MS 部署的位置 (錯誤: %s)", + "loc.messages.Nopackagefoundwithspecifiedpattern": "找不到具指定模式的套件: %s", + "loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "有多個套件與指定模式相符: %s。請縮小搜尋模式範圍。", + "loc.messages.Trytodeploywebappagainwithappofflineoptionselected": "請先選取 [讓應用程式成為離線狀態] 選項,然後嘗試再次部署 App Service。", + "loc.messages.Trytodeploywebappagainwithrenamefileoptionselected": "請先選取 [重新命名鎖定的檔案] 選項,然後嘗試再次部署 App Service。", + "loc.messages.NOJSONfilematchedwithspecificpattern": "沒有符合特定模式 %s 的 JSON 檔案。", + "loc.messages.Configfiledoesntexists": "組態檔 %s 不存在。", + "loc.messages.Failedtowritetoconfigfilewitherror": "無法寫入組態檔 %s,錯誤為: %s", + "loc.messages.AppOfflineModeenabled": "已啟用 [應用程式離線] 模式。", + "loc.messages.Failedtoenableappofflinemode": "無法啟用 [應用程式離線] 模式。狀態碼: %s (%s)", + "loc.messages.AppOflineModedisabled": "已停用 [應用程式離線] 模式。", + "loc.messages.FailedtodisableAppOfflineMode": "無法停用 [應用程式離線] 模式。狀態碼: %s (%s)", + "loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform": "無法在非 Windows 平台執行 XML 轉換。", + "loc.messages.XdtTransformationErrorWhileTransforming": "轉換 %s (使用 %s) 時發生 XML 轉換錯誤。", + "loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "僅限使用 Windows 代理程式時才可使用 webdeploy 選項發佈", + "loc.messages.ResourceDoesntExist": "資源 '%s' 不存在。應具備資源才可部署。", + "loc.messages.EncodeNotSupported": "偵測到檔案 %s 的檔案編碼為 %s。檔案編碼 %s 不支援變數替代。支援的編碼為 UTF-8 及 UTF-16 LE。", + "loc.messages.UnknownFileEncodeError": "無法偵測檔案 %s 的編碼 (typeCode: %s)。支援的編碼為 UTF-8 及 UTF-16 LE。", + "loc.messages.ShortFileBufferError": "檔案緩衝區太短而無法偵測編碼類型: %s", + "loc.messages.FailedToUpdateAzureRMWebAppConfigDetails": "無法更新 App Service 組態詳細資料。錯誤: %s", + "loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails": "已成功更新 App Service 組態詳細資料", + "loc.messages.RequestedURLforkuduphysicalpath": "Kudu 實體路徑的要求 URL: %s", + "loc.messages.Physicalpathalreadyexists": "實體路徑 '%s' 已存在", + "loc.messages.KuduPhysicalpathCreatedSuccessfully": "已成功建立 Kudu 實體路徑: %s", + "loc.messages.FailedtocreateKuduPhysicalPath": "無法建立 Kudu 實體路徑。錯誤 : %s", + "loc.messages.FailedtocheckphysicalPath": "無法檢查 Kudu 實體路徑。錯誤碼: %s", + "loc.messages.VirtualApplicationDoesNotExist": "虛擬應用程式不存在: %s", + "loc.messages.JSONParseError": "無法剖析 JSON 檔案: %s。錯誤: %s", + "loc.messages.JSONvariablesubstitutionappliedsuccessfully": "已成功套用 JSON 變數替代。", + "loc.messages.XMLvariablesubstitutionappliedsuccessfully": "已成功套用替代的 XML 變數。", + "loc.messages.failedtoUploadFileToKudu": "無法將檔案 %s 上傳到 Kudu (%s)。狀態碼: %s", + "loc.messages.failedtoUploadFileToKuduError": "無法將檔案 %s 上傳到 Kudu (%s)。錯誤: %s", + "loc.messages.ExecuteScriptOnKudu": "正在於 Kudu 服務上執行指定的指令碼。", + "loc.messages.FailedToRunScriptOnKuduError": "無法在 Kudu 服務上執行指令碼。錯誤: %s", + "loc.messages.FailedToRunScriptOnKudu": "無法在 Kudu 上執行指令碼: %s。狀態碼: %s", + "loc.messages.ScriptExecutionOnKuduSuccess": "已成功在 Kudu 上執行指令碼。", + "loc.messages.ScriptExecutionOnKuduFailed": "執行的指令碼傳回了下列傳回碼: '%s'。錯誤: %s", + "loc.messages.FailedtoDeleteFileFromKudu": "無法從 Kudu (%s) 刪除檔案 %s。狀態碼: %s", + "loc.messages.FailedtoDeleteFileFromKuduError": "無法從下列 Kudu 刪除檔案 %s: %s。錯誤: %s", + "loc.messages.ScriptFileNotFound": "找不到指令碼檔案 '%s'。", + "loc.messages.InvalidScriptFile": "提供的指令檔 '%s' 無效。有效的副檔名為 .bat 與 .cmd (Windows),以及 .sh (Linux)", + "loc.messages.RetryForTimeoutIssue": "因為逾時,導致指令碼執行失敗。請重試。", + "loc.messages.stdoutFromScript": "指令碼的標準輸出:", + "loc.messages.stderrFromScript": "指令碼的標準錯誤:", + "loc.messages.WebConfigAlreadyExists": "已有 web.config 檔案。未產生任何檔案。", + "loc.messages.SuccessfullyGeneratedWebConfig": "已成功產生 web.config 檔案", + "loc.messages.FailedToGenerateWebConfig": "無法產生 web.config。%s", + "loc.messages.FailedToGetKuduFileContent": "無法取得檔案內容: %s。狀態碼: %s (%s)", + "loc.messages.FailedToGetKuduFileContentError": "無法取得檔案內容: %s。錯誤: %s", + "loc.messages.ScriptStatusTimeout": "因為逾時,所以無法擷取指令碼狀態。", + "loc.messages.PollingForFileTimeOut": "因為逾時,所以無法擷取指令碼狀態。您可以將 'appservicedeploy.retrytimeout' 變數設定為所需的分鐘數來提高逾時限制。", + "loc.messages.InvalidPollOption": "提供的輪詢選項無效: %s。", + "loc.messages.MissingAppTypeWebConfigParameters": "Web.config 參數中遺漏屬性 '-appType'。'-appType' 的有效值是: 'python_Bottle'、'python_Django'、'python_Flask' 與 'node'。
例如,Python Bottle 架構會需要 '-appType python_Bottle' (無引號)。", + "loc.messages.AutoDetectDjangoSettingsFailed": "偵測不到 DJANGO_SETTINGS_MODULE 'settings.py' 檔案路徑。請確定 'settings.py' 檔案存在,或依下列格式在 Web.config 參數輸入中提供正確的路徑: '-DJANGO_SETTINGS_MODULE <資料夾名稱>.settings'", + "loc.messages.FailedToApplyTransformation": "無法對指定的套件套用轉換。請確認下列事項。", + "loc.messages.FailedToApplyTransformationReason1": "1. 是否已對建置期間由 MSBuild 產生的套件套用轉換。若已套用,請移除 csproj 檔案中每項設定的 標記,然後重建。", + "loc.messages.FailedToApplyTransformationReason2": "2. 確認組態檔與轉換檔皆位於套件內的同一個資料夾中。", + "loc.messages.AutoParameterizationMessage": "根據預設,Web.config 中的 ConnectionString 屬性已經過參數化。請注意,轉換對 connectionString 屬性無效,因為 'Parameters.xml' 或 'SetParameters.xml' 檔案已於部署期間覆寫該值。您可在產生 MSBuild 套件期間設定 /p:AutoParameterizationWebConfigConnectionStrings=False,停用自動參數化。", + "loc.messages.UnsupportedAppType": "產生 Web.config 時不支援應用程式類型 '%s'。'-appType' 的有效值為: 'python_Bottle'、'python_Django'、'python_Flask' 與 'node'", + "loc.messages.UnableToFetchAuthorityURL": "無法擷取授權單位 URL。", + "loc.messages.UnableToFetchActiveDirectory": "無法擷取 Active Directory 資源識別碼。", + "loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand": "已成功更新執行階段堆疊與啟動命令。", + "loc.messages.FailedToUpdateRuntimeStackAndStartupCommand": "無法更新執行階段堆疊與啟動命令。錯誤: %s。", + "loc.messages.SuccessfullyUpdatedWebAppSettings": "已成功更新應用程式設定。", + "loc.messages.FailedToUpdateAppSettingsInConfigDetails": "無法更新應用程式設定。錯誤: %s。", + "loc.messages.UnableToGetAzureRMWebAppMetadata": "無法擷取 AzureRM WebApp 中繼資料。錯誤碼: %s", + "loc.messages.UnableToUpdateAzureRMWebAppMetadata": "無法更新 AzureRM WebApp 中繼資料。錯誤碼: %s", + "loc.messages.Unabletoretrieveazureregistrycredentials": "無法擷取 Azure Container Registry 認證。[狀態碼: '%s']", + "loc.messages.UnableToReadResponseBody": "無法讀取回應主體。錯誤: %s", + "loc.messages.UnableToUpdateWebAppConfigDetails": "無法更新 WebApp 組態詳細資料。StatusCode: '%s'", + "loc.messages.AddingReleaseAnnotation": "正在新增 Application Insights 資源 '%s' 的版本註釋", + "loc.messages.SuccessfullyAddedReleaseAnnotation": "已成功將版本註釋新增至 Application Insights: %s", + "loc.messages.FailedAddingReleaseAnnotation": "無法新增版本註釋。%s", + "loc.messages.RenameLockedFilesEnabled": "將為 App Service 啟用的已鎖定檔案重新命名。", + "loc.messages.FailedToEnableRenameLockedFiles": "無法允許已鎖定重新命名的檔案。錯誤: %s", + "loc.messages.WebJobsInProgressIssue": "數個 WebJob 處於執行中的狀態,導致部署無法移除檔案。您可以在部署之前停用 [Remove additional files at destinaton] 選項或停止持續作業。", + "loc.messages.FailedToFetchKuduAppSettings": "無法擷取 Kudu 應用程式設定。錯誤: %s", + "loc.messages.FailedToCreatePath": "無法從 Kudu 建立路徑 '%s'。錯誤: %s", + "loc.messages.FailedToDeleteFile": "無法從 Kudu 刪除檔案 '%s/%s'。錯誤: %s", + "loc.messages.FailedToUploadFile": "無法從 Kudu 上傳檔案 '%s/%s'。錯誤: %s", + "loc.messages.FailedToGetFileContent": "無法從 Kudu 取得檔案內容 '%s/%s'。錯誤: %s", + "loc.messages.FailedToListPath": "無法從 Kudu 列出路徑 '%s'。錯誤: %s", + "loc.messages.RetryToDeploy": "正在重試部署套件。", + "loc.messages.FailedToGetAppServiceDetails": "無法擷取 App Service '%s' 詳細資料。錯誤: %s", + "loc.messages.FailedToGetAppServicePublishingProfile": "無法擷取 App Service '%s' 發行設定檔。錯誤: %s", + "loc.messages.FailedToUpdateAppServiceMetadata": "無法更新 App Service '%s' 中繼資料。錯誤: %s", + "loc.messages.FailedToGetAppServiceMetadata": "無法取得 App Service '%s' 中繼資料。錯誤: %s", + "loc.messages.FailedToPatchAppServiceConfiguration": "無法修補 App Service '%s' 組態。錯誤: %s", + "loc.messages.FailedToUpdateAppServiceConfiguration": "無法更新 App Service '%s' 組態。錯誤: %s", + "loc.messages.FailedToGetAppServiceConfiguration": "無法取得 App Service '%s' 組態。錯誤: %s", + "loc.messages.FailedToGetAppServicePublishingCredentials": "無法擷取 App Service '%s' 發行認證。錯誤: %s", + "loc.messages.FailedToGetAppServiceApplicationSettings": "無法取得 App Service '%s' 應用程式設定。錯誤: %s", + "loc.messages.FailedToUpdateAppServiceApplicationSettings": "無法更新 App Service '%s' 應用程式設定。錯誤: %s", + "loc.messages.UpdatingAppServiceConfigurationSettings": "正在更新 App Service 組態設定。資料: %s", + "loc.messages.UpdatedAppServiceConfigurationSettings": "已更新 App Service 組態設定。", + "loc.messages.UpdatingAppServiceApplicationSettings": "正在更新 App Service 應用程式設定。資料: %s", + "loc.messages.UpdatedAppServiceApplicationSettings": "已更新 App Service 應用程式設定與 Kudu 應用程式設定。", + "loc.messages.MultipleResourceGroupFoundForAppService": "找到 App Service '%s' 的多個資源群組。", + "loc.messages.PackageDeploymentUsingZipDeployFailed": "使用 ZIP Deploy 的套件部署失敗。如需詳細資料,請查看記錄。", + "loc.messages.PackageDeploymentInitiated": "使用 ZIP Deploy 的套件部署已起始。", + "loc.messages.FailedToGetDeploymentLogs": "無法取得部署記錄。錯誤: %s", + "loc.messages.GoExeNameNotPresent": "請移 exe 名稱不存在", + "loc.messages.WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier." +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0.ts new file mode 100644 index 000000000000..47663e758b1f --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0.ts @@ -0,0 +1,125 @@ +import * as path from 'path'; +import * as assert from 'assert'; +import * as ttm from 'vsts-task-lib/mock-test'; +import tl = require('vsts-task-lib'); +var ltx = require('ltx'); +import fs = require('fs'); + +var AppServiceTests = require("../node_modules/azure-arm-rest/Tests/L0-azure-arm-app-service.js"); +var KuduServiceTests = require("../node_modules/azure-arm-rest/Tests/L0-azure-arm-app-service-kudu-tests.js"); +var ApplicationInsightsTests = require("../node_modules/azure-arm-rest/Tests/L0-azure-arm-appinsights-tests.js"); + + +describe('AzureRmWebAppDeployment Suite', function() { + + this.timeout(60000); + + before((done) => { + if(!tl.exist(path.join(__dirname, '..', 'node_modules/azure-arm-rest/Tests/node_modules'))) { + tl.cp(path.join( __dirname, 'node_modules'), path.join(__dirname, '..', 'node_modules/azure-arm-rest/Tests'), '-rf', true); + } + + tl.cp(path.join(__dirname, "..", "node_modules", "webdeployment-common", "Tests", 'L1XmlVarSub', 'Web.config'), path.join(__dirname, "..", "node_modules", "webdeployment-common", "Tests", 'L1XmlVarSub', 'Web_test.config'), '-f', false); + tl.cp(path.join(__dirname, "..", "node_modules", "webdeployment-common", "Tests", 'L1XmlVarSub', 'Web.Debug.config'), path.join(__dirname, "..", "node_modules", "webdeployment-common", "Tests", 'L1XmlVarSub', 'Web_test.Debug.config'), '-f', false); + tl.cp(path.join(__dirname, "..", "node_modules", "webdeployment-common", "Tests", 'L1XmlVarSub', 'parameters.xml'), path.join(__dirname, "..", "node_modules", "webdeployment-common", "Tests", 'L1XmlVarSub', 'parameters_test.xml'), '-f', false); + tl.cp(path.join(__dirname, "..", "node_modules","webdeployment-common","Tests", 'L1XdtTransform', 'Web.config'), path.join(__dirname, "..", "node_modules","webdeployment-common","Tests", 'L1XdtTransform', 'Web_test.config'), '-f', false); + done(); + }); + after(function() { + try { + tl.rmRF(path.join(__dirname, "..", "node_modules", "webdeployment-common", "Tests", 'L1XmlVarSub', 'parameters_test.xml')); + } + catch(error) { + tl.debug(error); + } + }); + + ApplicationInsightsTests.ApplicationInsightsTests(); + AppServiceTests.AzureAppServiceMockTests(); + KuduServiceTests.KuduServiceTests(); + + if (tl.osType().match(/^Win/)) { + it('Runs successfully with XML Transformation (L1)', (done:MochaDone) => { + this.timeout(parseInt(process.env.TASK_TEST_TIMEOUT) || 20000); + + let tp = path.join(__dirname, "..", "node_modules","webdeployment-common","Tests","L1XdtTransform.js"); + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + var resultFile = ltx.parse(fs.readFileSync(path.join(__dirname, "..", "node_modules","webdeployment-common","Tests", 'L1XdtTransform', 'Web_test.config'))); + var expectFile = ltx.parse(fs.readFileSync(path.join(__dirname, "..", "node_modules","webdeployment-common","Tests", 'L1XdtTransform','Web_Expected.config'))); + assert(ltx.equal(resultFile, expectFile) , 'Should Transform attributes on Web.config'); + done(); + }); + } + else { + + } + + it('Runs successfully with XML variable substitution', (done:MochaDone) => { + let tp = path.join(__dirname, "..", "node_modules", "webdeployment-common", "Tests", 'L1XmlVarSub.js'); + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + var resultFile = ltx.parse(fs.readFileSync(path.join(__dirname, "..", "node_modules","webdeployment-common","Tests", 'L1XmlVarSub', 'Web_test.config'))); + var expectFile = ltx.parse(fs.readFileSync(path.join(__dirname, "..", "node_modules","webdeployment-common","Tests", 'L1XmlVarSub', 'Web_Expected.config'))); + assert(ltx.equal(resultFile, expectFile) , 'Should have substituted variables in Web.config file'); + var resultFile = ltx.parse(fs.readFileSync(path.join(__dirname, "..", "node_modules", "webdeployment-common", "Tests", 'L1XmlVarSub', 'Web_test.Debug.config'))); + var expectFile = ltx.parse(fs.readFileSync(path.join(__dirname, "..", "node_modules", "webdeployment-common", "Tests", 'L1XmlVarSub', 'Web_Expected.Debug.config'))); + assert(ltx.equal(resultFile, expectFile) , 'Should have substituted variables in Web.Debug.config file'); + var resultParamFile = ltx.parse(fs.readFileSync(path.join(__dirname, "..", "node_modules","webdeployment-common","Tests", 'L1XmlVarSub', 'parameters_test.xml'))); + var expectParamFile = ltx.parse(fs.readFileSync(path.join(__dirname, "..", "node_modules","webdeployment-common","Tests", 'L1XmlVarSub', 'parameters_Expected.xml'))); + assert(ltx.equal(resultParamFile, expectParamFile) , 'Should have substituted variables in parameters.xml file'); + + done(); + }); + + it('Runs successfully with JSON variable substitution', (done:MochaDone) => { + let tp = path.join(__dirname, "..", "node_modules", "webdeployment-common", "Tests", 'L1JsonVarSub.js'); + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.stdout.search('JSON - eliminating object variables validated') > 0, 'JSON - eliminating object variables validation error'); + assert(tr.stdout.search('JSON - simple string change validated') > 0,'JSON -simple string change validation error' ); + assert(tr.stdout.search('JSON - system variable elimination validated') > 0, 'JSON -system variable elimination validation error'); + assert(tr.stdout.search('JSON - special variables validated') > 0, 'JSON - special variables validation error'); + assert(tr.stdout.search('JSON - variables with dot character validated') > 0, 'JSON variables with dot character validation error'); + assert(tr.stdout.search('JSON - substitute inbuilt JSON attributes validated') > 0, 'JSON inbuilt variable substitution validation error'); + assert(tr.stdout.search('VALID JSON COMMENTS TESTS PASSED') > 0, 'VALID JSON COMMENTS TESTS PASSED'); + assert(tr.stdout.search('INVALID JSON COMMENTS TESTS PASSED') > 0, 'INVALID JSON COMMENTS TESTS PASSED'); + assert(tr.succeeded, 'task should have succeeded'); + done(); + }); + + it('Validate File Encoding', (done:MochaDone) => { + let tp = path.join(__dirname, "..", "node_modules", "webdeployment-common", "Tests", 'L1ValidateFileEncoding.js'); + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.stdout.search('UTF-8 with BOM validated') >= 0, 'Should have validated UTF-8 with BOM'); + assert(tr.stdout.search('UTF-16LE with BOM validated') >= 0, 'Should have validated UTF-16LE with BOM'); + assert(tr.stdout.search('UTF-16BE with BOM validated') >= 0, 'Should have validated UTF-16BE with BOM'); + assert(tr.stdout.search('UTF-32LE with BOM validated') >= 0, 'Should have validated UTF-32LE with BOM'); + assert(tr.stdout.search('UTF-32BE with BOM validated') >= 0, 'Should have validated UTF-32BE with BOM'); + + assert(tr.stdout.search('UTF-8 without BOM validated') >= 0, 'Should have validated UTF-8 without BOM'); + assert(tr.stdout.search('UTF-16LE without BOM validated') >= 0, 'Should have validated UTF-16LE without BOM'); + assert(tr.stdout.search('UTF-16BE without BOM validated') >= 0, 'Should have validated UTF-16BE without BOM'); + assert(tr.stdout.search('UTF-32LE without BOM validated') >= 0, 'Should have validated UTF-32LE without BOM'); + assert(tr.stdout.search('UTF-32BE without BOM validated') >= 0, 'Should have validated UTF-32BE without BOM'); + + assert(tr.stdout.search('Short File Buffer Error') >= 0, 'Should have validated short Buffer'); + assert(tr.stdout.search('Unknown encoding type') >= 0, 'Should throw for Unknown File Buffer'); + done(); + }); + + it('Validate webdeployment-common.utility.copyDirectory()', (done:MochaDone) => { + let tp = path.join(__dirname, "..", "node_modules", "webdeployment-common", "Tests", 'L0CopyDirectory.js'); + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.stdout.search('## Copy Files Successful ##') >=0, 'should have copied the files'); + assert(tr.stdout.search('## mkdir Successful ##') >= 0, 'should have created dir including dest folder'); + done(); + }); +}); diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0GenerateWebConfigForNode.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0GenerateWebConfigForNode.ts new file mode 100644 index 000000000000..9c7202b0ea43 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0GenerateWebConfigForNode.ts @@ -0,0 +1,283 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'webAppPkg.zip'); +tr.setInput('UseWebDeploy', 'true'); +tr.setInput('GenerateWebConfig','true'); +tr.setInput('WebConfigParameters','-appType node -Handler iisnode -NodeStartFile server.js'); +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = 1, +process.env["RELEASE_RELEASEID"] = 1; +process.env["BUILD_BUILDNUMBER"] = 1; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; + +// provide answers for task mock +let a: ma.TaskLibAnswers = { + "which": { + "msdeploy": "msdeploy" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + } + }, + "osType": { + "osType": "Windows" + }, + "checkPath": { + "webAppPkg.zip": true, + "webAppPkg": true, + "msdeploy": true + }, + "exec": { + "msdeploy -verb:getParameters -source:package=\'DefaultWorkingDirectory\\temp_web_package.zip\'": { + "code": 0, + "stdout": "Executed Successfully" + }, + "msdeploy -verb:sync -source:package=\'DefaultWorkingDirectory\\temp_web_package.zip\' -dest:auto,ComputerName=\'https://mytestappKuduUrl/msdeploy.axd?site=mytestapp\',UserName=\'$mytestapp\',Password=\'mytestappPwd\',AuthType=\'Basic\' -setParam:name=\'IIS Web Application Name\',value=\'mytestapp\' -enableRule:DoNotDeleteRule -userAgent:TFS_useragent": { + "code": 0, + "stdout": "Executed Successfully" + } + }, + "rmRF": { + "temp_web_package_random_path": { + "success": true + }, + "DefaultWorkingDirectory\\temp_web_package.zip": { + "success": true + } + }, + "exist": { + "webAppPkg.zip": true, + "webAppPkg": true, + "temp_web_package_random_path/web.config": false + }, + "glob": { + "webAppPkgPattern" : ["webAppPkg1", "webAppPkg2"], + "Invalid_webAppPkg" : [], + "webAppPkg.zip": ["webAppPkg.zip"], + "webAppPkg": ["webAppPkg"] + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "AZURE_HTTP_USER_AGENT": "TFS_useragent", + "System.DefaultWorkingDirectory": "DefaultWorkingDirectory", + "build.sourceVersion": "46da24f35850f455185b9188b4742359b537076f", + "build.buildId": 1, + "release.releaseId": 1, + "build.buildNumber": 1, + "release.releaseName": "Release-1", + "build.repository.provider": "TfsGit", + "build.repository.name": "MyFirstProject", + "system.TeamFoundationCollectionUri": "https://abc.visualstudio.com/", + "system.teamProject": "MyFirstProject", + "build.sourceVersionAuthor": "author", + "release.releaseUri": "vstfs:///ReleaseManagement/Release/1", + "agent.name": "agent" + } +} + +import mockTask = require('vsts-task-lib/mock-task'); +tr.registerMock('webdeployment-common/ziputility.js', { + getArchivedEntries: function(webDeployPkg) { + return { + "entries":[ + "systemInfo.xml", + "parameters.xml" + ] + }; + } +}); +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); + +tr.registerMock('./msdeployutility.js', { + getMSDeployCmdArgs : msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath : function() { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + testAzureWebAppAvailability: function() { + console.log('App Service availability check.'); + }, + getAzureRMWebAppPublishProfile: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if(deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + getAzureRMWebAppConfigDetails: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [ ['Object'], ['Object'], ['Object'] ], + scmType: "None" + } + } + + return config; + }, + updateDeploymentStatus: function(publishingProfile, isDeploymentSuccess, customMessage) { + if(isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess, customMessage); + requestDetails["requestBody"].author = 'author'; + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + getWebAppAppSettings : function (SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string){ + var appSettings = { + properties : { + MSDEPLOY_RENAME_LOCKED_FILES : '1' + } + }; + return appSettings; + }, + updateWebAppAppSettings : function (){ + return true; + }, + updateAzureRMWebAppConfigDetails: function() { + console.log("Successfully updated scmType to VSTSRM"); + }, + getAzureRMWebAppMetadata: function() { + return { + properties: {} + } + }, + updateAzureRMWebAppMetadata: function() { + console.log("Successfully updated Web App metadata"); + } +}); + +tr.registerMock('webdeployment-common/ziputility.js', { + getArchivedEntries: function(webDeployPkg) { + return { + "entries":[ + "systemInfo.xml", + "parameters.xml" + ] + }; + } +}); + +tr.registerMock('webdeployment-common/utility.js', { + isInputPkgIsFolder: function() { + return false; + }, + fileExists: function() { + return true; + }, + canUseWebDeploy: function() { + return true; + }, + findfiles: function() { + return ['webDeployPkg'] + }, + generateTemporaryFolderForDeployment: function() { + return 'temp_web_package_random_path'; + }, + archiveFolderForDeployment: function() { + return { + "webDeployPkg": "DefaultWorkingDirectory\\temp_web_package.zip", + "tempPackagePath": "DefaultWorkingDirectory\\temp_web_package.zip" + }; + } +}); + +tr.registerMock('./parameterparser', { + parse: function (data) { + return { + "appType": { + "value": "node" + }, + "Handler": { + "value": "iisnode" + }, + "NodeStartFile": { + "value": "server.js" + } + } + } +}); + +var fs = require('fs'); +tr.registerMock('fs', { + createWriteStream: function (filePath, options) { + return { + "isWriteStreamObj": true, + "on": (event) => { + console.log("event: " + event + " has occurred"); + }, + "end" : () => { return true } + }; + }, + ReadStream: fs.ReadStream, + WriteStream: fs.WriteStream, + readFileSync: function(webConfigPath,options) { + return ""; + }, + openSync: function (fd, options) { + return true; + }, + closeSync: function (fd) { + return true; + }, + fsyncSync: function(fd) { + return true; + } +}); + +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0LinuxBuiltinImage.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0LinuxBuiltinImage.ts new file mode 100644 index 000000000000..61d20ecbfae3 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0LinuxBuiltinImage.ts @@ -0,0 +1,240 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +import tl = require('vsts-task-lib'); +import trm = require('vsts-task-lib/toolrunner'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'webAppPkg.zip'); +tr.setInput('UseWebDeploy', 'false'); +tr.setInput('ImageSource', "Builtin Image"); +tr.setInput('WebAppKind', "applinux"); +tr.setInput('RuntimeStack', "dummy|version"); +tr.setInput('BuiltinLinuxPackage', 'webAppPkg.zip'); + +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = 1, +process.env["RELEASE_RELEASEID"] = 1; +process.env["BUILD_BUILDNUMBER"] = 1; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; + +// provide answers for task mock +let a: ma.TaskLibAnswers = { + "which": { + "cmd": "cmd" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + } + }, + "osType": { + "osType": "Linux" + }, + "checkPath": { + "cmd": true, + "webAppPkg.zip": true, + "webAppPkg": true + }, + "exec": { + "cmd /C DefaultWorkingDirectory\\msDeployCommand.bat": { + "code": 0, + "stdout": "Executed Successfully" + }, + "cmd /C DefaultWorkingDirectory\\msDeployParam.bat": { + "code": 0, + "stdout": "Executed Successfully" + } + }, + "exist": { + "webAppPkg.zip": true, + "webAppPkg": true + }, + "glob": { + "webAppPkgPattern" : ["webAppPkg1", "webAppPkg2"], + "Invalid_webAppPkg" : [], + "webAppPkg.zip": ["webAppPkg.zip"], + "webAppPkg": ["webAppPkg"] + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "AZURE_HTTP_USER_AGENT": "TFS_useragent", + "System.DefaultWorkingDirectory": "DefaultWorkingDirectory", + "build.sourceVersion": "46da24f35850f455185b9188b4742359b537076f", + "build.buildId": 1, + "release.releaseId": 1, + "build.buildNumber": 1, + "release.releaseName": "Release-1", + "build.repository.provider": "TfsGit", + "build.repository.name": "MyFirstProject", + "system.TeamFoundationCollectionUri": "https://abc.visualstudio.com/", + "system.teamProject": "MyFirstProject", + "build.sourceVersionAuthor": "author", + "release.releaseUri": "vstfs:///ReleaseManagement/Release/1", + "agent.name": "agent" + } +} + + +import mockTask = require('vsts-task-lib/mock-task'); +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); +tr.registerMock('./msdeployutility.js', { + getMSDeployCmdArgs : msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath : function() { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + testAzureWebAppAvailability: function(Url, port) { + console.log("Testing availability of the webApp"); + }, + getAzureRMWebAppPublishProfile: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if(deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + updateDeploymentStatus: function(publishingProfile, isDeploymentSuccess ) { + if(isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess); + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getAzureRMWebAppConfigDetails: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [ ['Object'], ['Object'], ['Object'] ], + scmType: "None" + } + } + + return config; + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + updateAzureRMWebAppConfigDetails: function() { + console.log("Successfully updated web app config details"); + }, + getAzureRMWebAppMetadata: function() { + return { + properties: {} + } + }, + updateAzureRMWebAppMetadata: function() { + console.log("Successfully updated Web App metadata"); + }, + getWebAppAppSettings: function (SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var appSettings = { + properties: { + } + }; + return appSettings; + }, + updateWebAppAppSettings: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName){ + console.log("Successfully updated webApp app-settings"); + } +}); +tr.registerMock('webdeployment-common/utility.js', { + isInputPkgIsFolder: function () { + return false; + }, + canUseWebDeploy: function () { + return false; + }, + findfiles: function () { + return ['linuxPkg']; + }, + isMSDeployPackage: function () { + return false; + } +}); +tr.registerMock('./kuduutility.js', { + deployWebAppPackage: function(webAppPackage, webAppZipFile) { + console.log ('Deployed using KuduDeploy'); + }, + getVirtualAndPhysicalPaths: function (virtualApplication, virtualApplicationMappings) { + // construct URL depending on virtualApplication or root of webapplication + var physicalPath = "/site/wwwroot"; + var virtualPath = "/"; + if (virtualApplication) { + virtualPath = "/" + virtualApplication; + } + for (var index in virtualApplicationMappings) { + var mapping = virtualApplicationMappings[index]; + if (mapping.virtualPath == virtualPath) { + physicalPath = mapping.physicalPath; + break; + } + } + return [virtualPath, physicalPath]; + }, + containsParamFile: function (webAppPackage) { + var isParamFilePresent = false; + return isParamFilePresent; + } +}); + +tr.registerMock("webdeployment-common/ziputility.js",{ + getArchivedEntries: function(webDeployPkg) { + return { + "entries": [ + "systemInfo.xml", + ] + }; + } +}); + +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0NonWindowsDefault.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0NonWindowsDefault.ts new file mode 100644 index 000000000000..49ad4c193bec --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0NonWindowsDefault.ts @@ -0,0 +1,221 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +import tl = require('vsts-task-lib'); +import trm = require('vsts-task-lib/toolrunner'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'webAppPkg.zip'); +tr.setInput('UseWebDeploy', 'false'); + +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = 1, +process.env["RELEASE_RELEASEID"] = 1; +process.env["BUILD_BUILDNUMBER"] = 1; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; + +// provide answers for task mock +let a: ma.TaskLibAnswers = { + "which": { + "cmd": "cmd" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + } + }, + "osType": { + "osType": "Linux" + }, + "checkPath": { + "cmd": true, + "webAppPkg.zip": true, + "webAppPkg": true + }, + "exec": { + "cmd /C DefaultWorkingDirectory\\msDeployCommand.bat": { + "code": 0, + "stdout": "Executed Successfully" + }, + "cmd /C DefaultWorkingDirectory\\msDeployParam.bat": { + "code": 0, + "stdout": "Executed Successfully" + } + }, + "exist": { + "webAppPkg.zip": true, + "webAppPkg": true + }, + "glob": { + "webAppPkgPattern" : ["webAppPkg1", "webAppPkg2"], + "Invalid_webAppPkg" : [], + "webAppPkg.zip": ["webAppPkg.zip"], + "webAppPkg": ["webAppPkg"] + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "AZURE_HTTP_USER_AGENT": "TFS_useragent", + "System.DefaultWorkingDirectory": "DefaultWorkingDirectory", + "build.sourceVersion": "46da24f35850f455185b9188b4742359b537076f", + "build.buildId": 1, + "release.releaseId": 1, + "build.buildNumber": 1, + "release.releaseName": "Release-1", + "build.repository.provider": "TfsGit", + "build.repository.name": "MyFirstProject", + "system.TeamFoundationCollectionUri": "https://abc.visualstudio.com/", + "system.teamProject": "MyFirstProject", + "build.sourceVersionAuthor": "author", + "release.releaseUri": "vstfs:///ReleaseManagement/Release/1", + "agent.name": "agent" + } +} + + +import mockTask = require('vsts-task-lib/mock-task'); +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); +tr.registerMock('./msdeployutility.js', { + getMSDeployCmdArgs : msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath : function() { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + getAzureRMWebAppPublishProfile: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if(deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + updateDeploymentStatus: function(publishingProfile, isDeploymentSuccess ) { + if(isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess); + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getAzureRMWebAppConfigDetails: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [ ['Object'], ['Object'], ['Object'] ], + scmType: "None" + } + } + + return config; + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + getWebAppAppSettings : function (SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string){ + var appSettings = { + properties : { + MSDEPLOY_RENAME_LOCKED_FILES : '1' + } + }; + return appSettings; + }, + updateWebAppAppSettings : function (){ + return true; + }, + updateAzureRMWebAppConfigDetails: function() { + console.log("Successfully updated scmType to VSTSRM"); + }, + getAzureRMWebAppMetadata: function() { + return { + properties: {} + } + }, + updateAzureRMWebAppMetadata: function() { + console.log("Successfully updated Web App metadata"); + } +}); + +tr.registerMock('./kuduutility.js', { + deployWebAppPackage: function(webAppPackage, webAppZipFile) { + console.log ('Deployed using KuduDeploy'); + }, + getVirtualAndPhysicalPaths: function (virtualApplication, virtualApplicationMappings) { + // construct URL depending on virtualApplication or root of webapplication + var physicalPath = "/site/wwwroot"; + var virtualPath = "/"; + if (virtualApplication) { + virtualPath = "/" + virtualApplication; + } + for (var index in virtualApplicationMappings) { + var mapping = virtualApplicationMappings[index]; + if (mapping.virtualPath == virtualPath) { + physicalPath = mapping.physicalPath; + break; + } + } + return [virtualPath, physicalPath]; + }, + containsParamFile: function (webAppPackage) { + var isParamFilePresent = false; + return isParamFilePresent; + } +}); + +tr.registerMock("webdeployment-common/ziputility.js",{ + getArchivedEntries: function(webDeployPkg) { + return { + "entries": [ + "systemInfo.xml", + ] + }; + } +}); + +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0NonWindowsFailArchive.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0NonWindowsFailArchive.ts new file mode 100644 index 000000000000..c300f4c5f28f --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0NonWindowsFailArchive.ts @@ -0,0 +1,231 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'webAppPkg'); +tr.setInput('UseWebDeploy', 'false'); + +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = 1, +process.env["RELEASE_RELEASEID"] = 1; +process.env["BUILD_BUILDNUMBER"] = 1; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; + +// provide answers for task mock +let a: ma.TaskLibAnswers = { + "which": { + "cmd": "cmd" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + } + }, + "osType": { + "osType": "Linux" + }, + "checkPath": { + "cmd": true, + "webAppPkg.zip": true, + "webAppPkg": true + }, + "exec": { + "cmd /C DefaultWorkingDirectory\\msDeployCommand.bat": { + "code": 0, + "stdout": "Executed Successfully" + }, + "cmd /C DefaultWorkingDirectory\\msDeployParam.bat": { + "code": 0, + "stdout": "Executed Successfully" + } + }, + "exist": { + "webAppPkg.zip": true, + "webAppPkg": true + }, + "glob": { + "webAppPkgPattern" : ["webAppPkg1", "webAppPkg2"], + "Invalid_webAppPkg" : [], + "webAppPkg.zip": ["webAppPkg.zip"], + "webAppPkg": ["webAppPkg"] + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "AZURE_HTTP_USER_AGENT": "TFS_useragent", + "System.DefaultWorkingDirectory": "DefaultWorkingDirectory", + "build.sourceVersion": "46da24f35850f455185b9188b4742359b537076f", + "build.buildId": 1, + "release.releaseId": 1, + "build.buildNumber": 1, + "release.releaseName": "Release-1", + "build.repository.provider": "TfsGit", + "build.repository.name": "MyFirstProject", + "system.TeamFoundationCollectionUri": "https://abc.visualstudio.com/", + "system.teamProject": "MyFirstProject", + "build.sourceVersionAuthor": "author", + "release.releaseUri": "vstfs:///ReleaseManagement/Release/1", + "agent.name": "agent" + }, + "rmRF": { + "temp_web_package_random_path": { + "success": true + } + } +} + + +import mockTask = require('vsts-task-lib/mock-task'); +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); +tr.registerMock('./msdeployutility.js', { + getMSDeployCmdArgs : msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath : function() { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + getAzureRMWebAppPublishProfile: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if(deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + updateDeploymentStatus: function(publishingProfile, isDeploymentSuccess ) { + if(isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess); + requestDetails["requestBody"].author = 'author'; + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getAzureRMWebAppConfigDetails: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [ ['Object'], ['Object'], ['Object'] ], + scmType: "None" + } + } + + return config; + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + getWebAppAppSettings : function (SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string){ + var appSettings = { + properties : { + MSDEPLOY_RENAME_LOCKED_FILES : '1' + } + }; + return appSettings; + }, + updateWebAppAppSettings : function (){ + return true; + }, + updateAzureRMWebAppConfigDetails: function() { + console.log("Successfully updated scmType to VSTSRM"); + } +}); + +tr.registerMock('./kuduutility.js', { + getVirtualAndPhysicalPaths: function (virtualApplication, virtualApplicationMappings) { + // construct URL depending on virtualApplication or root of webapplication + var physicalPath = "/site/wwwroot"; + var virtualPath = "/"; + if (virtualApplication) { + virtualPath = "/" + virtualApplication; + } + for (var index in virtualApplicationMappings) { + var mapping = virtualApplicationMappings[index]; + if (mapping.virtualPath == virtualPath) { + physicalPath = mapping.physicalPath; + break; + } + } + return [virtualPath, physicalPath]; + }, + containsParamFile: function (webAppPackage) { + var isParamFilePresent = true; + return isParamFilePresent; + } +}); + +var zipUtility = require('webdeployment-common/ziputility.js'); +tr.registerMock('webdeployment-common/ziputility.js', { + archiveFolder: function(webAppPackage, webAppZipFile) { + throw new Error('Folder Archiving Failed'); + }, + unzip: zipUtility.unzip, + getArchivedEntries: zipUtility.getArchivedEntries +}); + + +tr.registerMock('webdeployment-common/utility.js', { + isInputPkgIsFolder: function() { + return true; + }, + fileExists: function() { + return true; + }, + canUseWebDeploy: function() { + return false; + }, + findfiles: function() { + return ['webDeployPkg'] + }, + generateTemporaryFolderOrZipPath: function() { + return 'temp_web_package_random_path'; + } +}); + +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0NonWindowsFailParamPkg.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0NonWindowsFailParamPkg.ts new file mode 100644 index 000000000000..eea521471f07 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0NonWindowsFailParamPkg.ts @@ -0,0 +1,213 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'webAppPkg.zip'); +tr.setInput('UseWebDeploy', 'false'); + +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = 1, +process.env["RELEASE_RELEASEID"] = 1; +process.env["BUILD_BUILDNUMBER"] = 1; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; + +// provide answers for task mock +let a: ma.TaskLibAnswers = { + "which": { + "cmd": "cmd" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + } + }, + "osType": { + "osType": "Linux" + }, + "checkPath": { + "cmd": true, + "webAppPkg.zip": true, + "webAppPkg": true + }, + "exec": { + "cmd /C DefaultWorkingDirectory\\msDeployCommand.bat": { + "code": 0, + "stdout": "Executed Successfully" + }, + "cmd /C DefaultWorkingDirectory\\msDeployParam.bat": { + "code": 0, + "stdout": "Executed Successfully" + } + }, + "exist": { + "webAppPkg.zip": true, + "webAppPkg": true + }, + "glob": { + "webAppPkgPattern" : ["webAppPkg1", "webAppPkg2"], + "Invalid_webAppPkg" : [], + "webAppPkg.zip": ["webAppPkg.zip"], + "webAppPkg": ["webAppPkg"] + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "AZURE_HTTP_USER_AGENT": "TFS_useragent", + "System.DefaultWorkingDirectory": "DefaultWorkingDirectory", + "build.sourceVersion": "46da24f35850f455185b9188b4742359b537076f", + "build.buildId": 1, + "release.releaseId": 1, + "build.buildNumber": 1, + "release.releaseName": "Release-1", + "build.repository.provider": "TfsGit", + "build.repository.name": "MyFirstProject", + "system.TeamFoundationCollectionUri": "https://abc.visualstudio.com/", + "system.teamProject": "MyFirstProject", + "build.sourceVersionAuthor": "author", + "release.releaseUri": "vstfs:///ReleaseManagement/Release/1", + "agent.name": "agent" + } +} + + + +import mockTask = require('vsts-task-lib/mock-task'); +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); +tr.registerMock('./msdeployutility.js', { + getMSDeployCmdArgs : msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath : function() { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + }, + containsParamFile: function(webAppPackage: string) { + var taskResult = mockTask.execSync("cmd", ['/C',"DefaultWorkingDirectory\\msDeployParam.bat"]); + return true; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + getAzureRMWebAppPublishProfile: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if(deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + updateDeploymentStatus: function(publishingProfile, isDeploymentSuccess ) { + if(isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess); + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getAzureRMWebAppConfigDetails: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [ ['Object'], ['Object'], ['Object'] ], + scmType: "None" + } + } + + return config; + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + getWebAppAppSettings : function (SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string){ + var appSettings = { + properties : { + MSDEPLOY_RENAME_LOCKED_FILES : '1' + } + }; + return appSettings; + }, + updateWebAppAppSettings : function (){ + return true; + }, + updateAzureRMWebAppConfigDetails: function() { + console.log("Successfully updated scmType to VSTSRM"); + } +}); + +tr.registerMock('./kuduutility.js', { + deployWebAppPackage: function(webAppPackage, webAppZipFile) { + throw new Error('Folder Archiving Failed'); + }, + getVirtualAndPhysicalPaths: function (virtualApplication, virtualApplicationMappings) { + // construct URL depending on virtualApplication or root of webapplication + var physicalPath = "/site/wwwroot"; + var virtualPath = "/"; + if (virtualApplication) { + virtualPath = "/" + virtualApplication; + } + for (var index in virtualApplicationMappings) { + var mapping = virtualApplicationMappings[index]; + if (mapping.virtualPath == virtualPath) { + physicalPath = mapping.physicalPath; + break; + } + } + return [virtualPath, physicalPath]; + } +}); + +tr.registerMock("webdeployment-common/ziputility.js", { + getArchivedEntries: function( webDeployPkg) { + return { + "entries": [ + "systemInfo.xml", + "parameters.xml" + ] + }; + } +}); + + +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0NonWindowsFolderPkg.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0NonWindowsFolderPkg.ts new file mode 100644 index 000000000000..adefdf561a6b --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0NonWindowsFolderPkg.ts @@ -0,0 +1,238 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'webAppPkg'); +tr.setInput('UseWebDeploy', 'false'); + +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = 1, +process.env["RELEASE_RELEASEID"] = 1; +process.env["BUILD_BUILDNUMBER"] = 1; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; + +// provide answers for task mock +let a: ma.TaskLibAnswers = { + "which": { + "cmd": "cmd" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + } + }, + "osType": { + "osType": "Linux" + }, + "checkPath": { + "cmd": true, + "webAppPkg.zip": true, + "webAppPkg": true + }, + "exec": { + "cmd /C DefaultWorkingDirectory\\msDeployCommand.bat": { + "code": 0, + "stdout": "Executed Successfully" + }, + "cmd /C DefaultWorkingDirectory\\msDeployParam.bat": { + "code": 0, + "stdout": "Executed Successfully" + } + }, + "exist": { + "webAppPkg.zip": true, + "webAppPkg": true + }, + "glob": { + "webAppPkgPattern" : ["webAppPkg1", "webAppPkg2"], + "Invalid_webAppPkg" : [], + "webAppPkg.zip": ["webAppPkg.zip"], + "webAppPkg": ["webAppPkg"] + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "AZURE_HTTP_USER_AGENT": "TFS_useragent", + "System.DefaultWorkingDirectory": "DefaultWorkingDirectory", + "build.sourceVersion": "46da24f35850f455185b9188b4742359b537076f", + "build.buildId": 1, + "release.releaseId": 1, + "build.buildNumber": 1, + "release.releaseName": "Release-1", + "build.repository.provider": "TfsGit", + "build.repository.name": "MyFirstProject", + "system.TeamFoundationCollectionUri": "https://abc.visualstudio.com/", + "system.teamProject": "MyFirstProject", + "build.sourceVersionAuthor": "author", + "release.releaseUri": "vstfs:///ReleaseManagement/Release/1", + "agent.name": "agent" + }, + "rmRF": { + "temp_web_package_random_path": { + "success": true + } + } +} + + +import mockTask = require('vsts-task-lib/mock-task'); +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); +tr.registerMock('./msdeployutility.js', { + getMSDeployCmdArgs : msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath : function() { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + getAzureRMWebAppPublishProfile: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if(deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + updateDeploymentStatus: function(publishingProfile, isDeploymentSuccess ) { + if(isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess); + requestDetails["requestBody"].author = 'author'; + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getAzureRMWebAppConfigDetails: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [ ['Object'], ['Object'], ['Object'] ], + scmType: "None" + } + } + + return config; + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + getWebAppAppSettings : function (SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string){ + var appSettings = { + properties : { + MSDEPLOY_RENAME_LOCKED_FILES : '1' + } + }; + return appSettings; + }, + updateWebAppAppSettings : function (){ + return true; + }, + updateAzureRMWebAppConfigDetails: function() { + console.log("Successfully updated scmType to VSTSRM"); + }, + getAzureRMWebAppMetadata: function() { + return { + properties: {} + } + }, + updateAzureRMWebAppMetadata: function() { + console.log("Successfully updated Web App metadata"); + } +}); + +tr.registerMock('./kuduutility.js', { + deployWebAppPackage: function(webAppPackage, webAppZipFile) { + console.log ('Deployed using KuduDeploy'); + }, + getVirtualAndPhysicalPaths: function (virtualApplication, virtualApplicationMappings) { + // construct URL depending on virtualApplication or root of webapplication + var physicalPath = "/site/wwwroot"; + var virtualPath = "/"; + if (virtualApplication) { + virtualPath = "/" + virtualApplication; + } + for (var index in virtualApplicationMappings) { + var mapping = virtualApplicationMappings[index]; + if (mapping.virtualPath == virtualPath) { + physicalPath = mapping.physicalPath; + break; + } + } + return [virtualPath, physicalPath]; + }, + containsParamFile: function (webAppPackage) { + var isParamFilePresent = false; + return isParamFilePresent; + } +}); + +tr.registerMock('webdeployment-common/ziputility.js', { + archiveFolder : function() { + console.log('Folder Archiving Successful'); + } +}); + +tr.registerMock('webdeployment-common/utility.js', { + isInputPkgIsFolder: function() { + return true; + }, + fileExists: function() { + return true; + }, + canUseWebDeploy: function() { + return false; + }, + findfiles: function() { + return ['webDeployPkg'] + }, + generateTemporaryFolderOrZipPath: function() { + return 'temp_web_package_random_path'; + } +}); + +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0NonWindowsParamFileinPkg.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0NonWindowsParamFileinPkg.ts new file mode 100644 index 000000000000..a78e69dc7ccc --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0NonWindowsParamFileinPkg.ts @@ -0,0 +1,211 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'webAppPkg.zip'); +tr.setInput('UseWebDeploy', 'false'); +tr.setInput('SetParametersFile', 'parameterFilePresent.xml'); + +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = '1', +process.env["RELEASE_RELEASEID"] = '1'; +process.env["BUILD_BUILDNUMBER"] = '1'; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; + +let a: ma.TaskLibAnswers = { + "which": { + "cmd": "cmd" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + }, + "parameterFilePresent.xml": { + "isFile" : true + }, + "parameterFileUser.xml": { + "isFile" : true + } + }, + "checkPath": { + "cmd" : true, + "webAppPkg.zip": true, + "webAppPkg": true + }, + "osType": { + "osType": "Linux" + }, + "exec": { + "cmd /C DefaultWorkingDirectory\\msDeployCommand.bat": { + "code" : 0, + "stdout": "Executed Successfully" + }, + "cmd /C DefaultWorkingDirectory\\msDeployParam.bat": { + "code" : 0, + "stdout": "Executed Successfully" + } + }, + "exist": { + "webAppPkg.zip": true + }, + "glob": { + "webAppPkg.zip": ["webAppPkg.zip"], + "webAppPkg": ["webAppPkg"] + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "SYSTEM_DEFAULTWORKINGDIRECTORY": "defaultWorkingDirectory", + "AZURE_HTTP_USER_AGENT": "TFS_useragent", + "System.DefaultWorkingDirectory" : "DefaultWorkingDirectory", + "build.sourcesDirectory": "DefaultWorkingDirectory" + } +}; + + +import mockTask = require('vsts-task-lib/mock-task'); +tr.registerMock('webdeployment-common/ziputility.js', { + getArchivedEntries: function(webDeployPkg) { + return { + "entries":[ + "systemInfo.xml" + ] + }; + } +}); +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); +tr.registerMock('./msdeployutility.js', { + getMSDeployCmdArgs : msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath : function() { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + getAzureRMWebAppPublishProfile: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if(deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + updateDeploymentStatus: function(publishingProfile, isDeploymentSuccess ) { + if(isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess); + requestDetails["requestBody"].author = 'author'; + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getAzureRMWebAppConfigDetails: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [ ['Object'], ['Object'], ['Object'] ], + scmType: "None" + } + } + + return config; + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + getWebAppAppSettings : function (SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string){ + var appSettings = { + properties : { + MSDEPLOY_RENAME_LOCKED_FILES : '1' + } + }; + return appSettings; + }, + updateWebAppAppSettings : function (){ + return true; + }, + updateAzureRMWebAppConfigDetails: function() { + console.log("Successfully updated scmType to VSTSRM"); + }, + getAzureRMWebAppMetadata: function() { + return { + properties: {} + } + }, + updateAzureRMWebAppMetadata: function() { + console.log("Successfully updated Web App metadata"); + } +}); + +tr.registerMock('./kuduutility.js', { + deployWebAppPackage: function(webAppPackage, webAppZipFile) { + console.log ('Deployed using KuduDeploy'); + }, + getVirtualAndPhysicalPaths: function (virtualApplication, virtualApplicationMappings) { + // construct URL depending on virtualApplication or root of webapplication + var physicalPath = "/site/wwwroot"; + var virtualPath = "/"; + if (virtualApplication) { + virtualPath = "/" + virtualApplication; + } + for (var index in virtualApplicationMappings) { + var mapping = virtualApplicationMappings[index]; + if (mapping.virtualPath == virtualPath) { + physicalPath = mapping.physicalPath; + break; + } + } + return [virtualPath, physicalPath]; + }, + containsParamFile: function (webAppPackage) { + var isParamFilePresent = false; + return isParamFilePresent; + } +}); + +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0NonWindowsXdtTransformationFail.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0NonWindowsXdtTransformationFail.ts new file mode 100644 index 000000000000..0d248309b5d3 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0NonWindowsXdtTransformationFail.ts @@ -0,0 +1,186 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'webAppPkg.zip'); +tr.setInput('UseWebDeploy', 'false'); +tr.setInput('XmlTransformation', 'true'); + +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = 1, +process.env["RELEASE_RELEASEID"] = 1; +process.env["BUILD_BUILDNUMBER"] = 1; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; + +// provide answers for task mock +let a: ma.TaskLibAnswers = { + "which": { + "cmd": "cmd" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + } + }, + "osType": { + "osType": "linux" + }, + "checkPath": { + "cmd": true, + "webAppPkg.zip": true, + "webAppPkg": true + }, + "exec": { + "cmd /C DefaultWorkingDirectory\\msDeployCommand.bat": { + "code": 0, + "stdout": "Executed Successfully" + }, + "cmd /C DefaultWorkingDirectory\\msDeployParam.bat": { + "code": 0, + "stdout": "Executed Successfully" + } + }, + "exist": { + "webAppPkg.zip": true, + "webAppPkg": true + }, + "glob": { + "webAppPkgPattern" : ["webAppPkg1", "webAppPkg2"], + "Invalid_webAppPkg" : [], + "webAppPkg.zip": ["webAppPkg.zip"], + "webAppPkg": ["webAppPkg"], + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "AZURE_HTTP_USER_AGENT": "TFS_useragent", + "System.DefaultWorkingDirectory": "DefaultWorkingDirectory", + "build.sourceVersion": "46da24f35850f455185b9188b4742359b537076f", + "build.buildId": 1, + "release.releaseId": 1, + "build.buildNumber": 1, + "release.releaseName": "Release-1", + "build.repository.provider": "TfsGit", + "build.repository.name": "MyFirstProject", + "system.TeamFoundationCollectionUri": "https://abc.visualstudio.com/", + "system.teamProject": "MyFirstProject", + "build.sourceVersionAuthor": "author", + "release.releaseUri": "vstfs:///ReleaseManagement/Release/1", + "agent.name": "agent" + } +}; + +import mockTask = require('vsts-task-lib/mock-task'); +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); +tr.registerMock('./msdeployutility.js', { + getMSDeployCmdArgs : msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath : function() { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + getAzureRMWebAppPublishProfile: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if(deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + updateDeploymentStatus: function(publishingProfile, isDeploymentSuccess ) { + if(isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess); + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getAzureRMWebAppConfigDetails: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [ ['Object'], ['Object'], ['Object'] ], + scmType: "None" + } + } + + return config; + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + getWebAppAppSettings : function (SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string){ + var appSettings = { + properties : { + MSDEPLOY_RENAME_LOCKED_FILES : '1' + } + }; + return appSettings; + }, + updateWebAppAppSettings : function (){ + return true; + }, + updateAzureRMWebAppConfigDetails: function() { + console.log("Successfully updated scmType to VSTSRM"); + } +}); +tr.registerMock('webdeployment-common/ziputility.js', { + unzip: function() { + + }, + archiveFolder: function() { + return "DefaultWorkingDirectory\\temp_web_package.zip" + }, + getArchivedEntries: function() { + return { + entries: ['Web.config', 'Web.debug.config'] + } + } +}); + +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0RunPostDeploymentScript.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0RunPostDeploymentScript.ts new file mode 100644 index 000000000000..83feff02a4ea --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0RunPostDeploymentScript.ts @@ -0,0 +1,207 @@ +var mockery = require('mockery'); +var path = require('path'); +mockery.enable({ + useCleanCache: true, + warnOnReplace: false, + warnOnUnregistered: false +}); + +mockery.registerMock('typed-rest-client/HttpClient', { + HttpClient: function() { + return { + get: function(url, headers) { + url = url.substring(0, url.lastIndexOf('_')) + path.extname(url); + var getUrlMap = { + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/stdout.txt': 'stdout content', + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/stderr.txt': 'sterr content', + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/script_result.txt': '0' + }; + + if(getUrlMap[url]) { + console.log('GET:' + url); + return { + then: function(handler) { + handler({ + message: { + statusCode: 200, + statusMessage: "Success" + }, + readBody: function() { + return getUrlMap[url]; + } + }); + } + }; + } + throw Error('Unknown verb or URL - GET'); + }, + del: function(url, headers) { + url = url.substring(0, url.lastIndexOf('_')) + path.extname(url); + + var deleteUrlArray = [ + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/kuduPostDeploymentScript.cmd', + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/mainCmdFile.cmd' + ]; + + if (deleteUrlArray.indexOf(url) != -1) { + console.log("DELETED:" + url); + return; + } + + throw Error('Unknown verb or URL - GET'); + }, + post: function(url, data, headers) { + if (url == 'https://mytestappKuduUrl/api/command') { + console.log('POST:https://mytestappKuduUrl/api/command'); + return; + } + throw Error('Unknown verb or URL - SEND'); + }, + sendStream: function(verb, url) { + url = url.substring(0, url.lastIndexOf('_')) + path.extname(url); + var urlArray = [ + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/kuduPostDeploymentScript.cmd', + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/mainCmdFile.cmd', + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/delete_log_file.cmd' + ]; + + if(verb == 'PUT' && urlArray.indexOf(url) != -1) { + console.log('PUT:' + url); + return; + } + throw Error('Unknown verb or URL - sendStream'); + } + } + } +}); + +mockery.registerMock('typed-rest-client/RestClient', { + RestClient: function() { + return { + get: function(url, options) { + url = url.substring(0, url.lastIndexOf('_')) + path.extname(url); + var getUrlMap = { + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/stdout.txt': 'stdout content', + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/stderr.txt': 'sterr content', + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/script_result.txt': '0' + }; + + if(getUrlMap[url]) { + console.log('GET:' + url); + return getUrlMap[url]; + } + + throw Error('Unknown verb or URL - GET'); + }, + del: function(url, options) { + url = url.substring(0, url.lastIndexOf('_')) + path.extname(url); + + var deleteUrlArray = [ + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/kuduPostDeploymentScript.cmd', + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/mainCmdFile.cmd' + ]; + + if (deleteUrlArray.indexOf(url) != -1) { + console.log("DELETED:" + url); + return { + then: function() { + } + }; + } + + throw Error('Unknown verb or URL - GET'); + }, + create: function(url, resources, options) { + if (url == 'https://mytestappKuduUrl/api/command') { + console.log('POST:https://mytestappKuduUrl/api/command'); + return { + then: function() { + } + }; + } + throw Error('Unknown verb or URL - SEND'); + }, + uploadStream: function(verb, url) { + url = url.substring(0, url.lastIndexOf('_')) + path.extname(url); + var urlArray = [ + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/kuduPostDeploymentScript.cmd', + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/mainCmdFile.cmd', + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/delete_log_file.cmd' + ]; + + if(verb == 'PUT' && urlArray.indexOf(url) != -1) { + console.log('PUT:' + url); + return { + then: function() { + } + }; + } + throw Error('Unknown verb or URL - sendStream'); + } + } + } +}); + +mockery.registerMock('vsts-task-lib/task', { + exist: function() { + return true; + }, + getVariable: function(variable) { + if(variable == "agent.proxyurl") { + return null; + } + return 'workingDirectory'; + }, + debug: function(message) { + console.log('##debug : ' + message); + }, + loc: function(message, argument) { + console.log('##LOC: ' + message + ' : ' + argument); + }, + writeFile: function(fileName, content) { + console.log('##FileWrite: ' + fileName); + }, + rmRF: function(fileName) { + console.log('##rmRF: ' + fileName); + } + +}); +mockery.registerMock('q', { + 'defer': function() { + return { + promise: { + 'content': '0' + }, + resolve: function(result) { + return result; + } + }; + } +}); + +var fs = require('fs'); +mockery.registerMock('fs', { + 'createReadStream': function() { + return ''; + }, + statSync: fs.statSync, + writeFileSync: fs.writeFileSync, + readFileSync: fs.readFileSync +}); +var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' +}; + +var kuduUtility = require('../kuduutility.js'); +kuduUtility.runPostDeploymentScript(mockPublishProfile, 'site/wwwroot', "File Path", null, 'myscript.cmd', false, false); diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0RunPostDeploymentScriptForLinux.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0RunPostDeploymentScriptForLinux.ts new file mode 100644 index 000000000000..3d97fe3644a7 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0RunPostDeploymentScriptForLinux.ts @@ -0,0 +1,207 @@ +var mockery = require('mockery'); +var path = require('path'); +mockery.enable({ + useCleanCache: true, + warnOnReplace: false, + warnOnUnregistered: false +}); + +mockery.registerMock('typed-rest-client/HttpClient', { + HttpClient: function() { + return { + get: function(url, headers) { + url = url.substring(0, url.lastIndexOf('_')) + path.extname(url); + var getUrlMap = { + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/stdout.txt': 'stdout content', + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/stderr.txt': 'sterr content', + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/script_result.txt': '0' + }; + + if(getUrlMap[url]) { + console.log('GET:' + url); + return { + then: function(handler) { + handler({ + message: { + statusCode: 200, + statusMessage: "Success" + }, + readBody: function() { + return getUrlMap[url]; + } + }); + } + }; + } + throw Error('Unknown verb or URL - GET'); + }, + del: function(url, headers) { + url = url.substring(0, url.lastIndexOf('_')) + path.extname(url); + + var deleteUrlArray = [ + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/kuduPostDeploymentScript.sh', + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/mainCmdFile.sh' + ]; + + if (deleteUrlArray.indexOf(url) != -1) { + console.log("DELETED:" + url); + return; + } + + throw Error('Unknown verb or URL - GET'); + }, + post: function(url, data, headers) { + if (url == 'https://mytestappKuduUrl/api/command') { + console.log('POST:https://mytestappKuduUrl/api/command'); + return; + } + throw Error('Unknown verb or URL - SEND'); + }, + sendStream: function(verb, url) { + url = url.substring(0, url.lastIndexOf('_')) + path.extname(url); + var urlArray = [ + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/kuduPostDeploymentScript.sh', + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/mainCmdFile.sh', + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/delete_log_file.sh' + ]; + + if(verb == 'PUT' && urlArray.indexOf(url) != -1) { + console.log('PUT:' + url); + return; + } + throw Error('Unknown verb or URL - sendStream'); + } + } + } +}); + +mockery.registerMock('typed-rest-client/RestClient', { + RestClient: function() { + return { + get: function(url, options) { + url = url.substring(0, url.lastIndexOf('_')) + path.extname(url); + var getUrlMap = { + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/stdout.txt': 'stdout content', + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/stderr.txt': 'sterr content', + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/script_result.txt': '0' + }; + + if(getUrlMap[url]) { + console.log('GET:' + url); + return getUrlMap[url]; + } + + throw Error('Unknown verb or URL - GET'); + }, + del: function(url, options) { + url = url.substring(0, url.lastIndexOf('_')) + path.extname(url); + + var deleteUrlArray = [ + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/kuduPostDeploymentScript.sh', + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/mainCmdFile.sh' + ]; + + if (deleteUrlArray.indexOf(url) != -1) { + console.log("DELETED:" + url); + return { + then: function() { + } + }; + } + + throw Error('Unknown verb or URL - GET'); + }, + create: function(url, resources, options) { + if (url == 'https://mytestappKuduUrl/api/command') { + console.log('POST:https://mytestappKuduUrl/api/command'); + return { + then: function() { + } + }; + } + throw Error('Unknown verb or URL - SEND'); + }, + uploadStream: function(verb, url) { + url = url.substring(0, url.lastIndexOf('_')) + path.extname(url); + var urlArray = [ + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/kuduPostDeploymentScript.sh', + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/mainCmdFile.sh', + 'https://mytestappKuduUrl/api/vfs/site/wwwroot/delete_log_file.sh' + ]; + + if(verb == 'PUT' && urlArray.indexOf(url) != -1) { + console.log('PUT:' + url); + return { + then: function() { + } + }; + } + throw Error('Unknown verb or URL - sendStream'); + } + } + } +}); + +mockery.registerMock('vsts-task-lib/task', { + exist: function() { + return true; + }, + getVariable: function(variable) { + if(variable == "agent.proxyurl") { + return null; + } + return 'workingDirectory'; + }, + debug: function(message) { + console.log('##debug : ' + message); + }, + loc: function(message, argument) { + console.log('##LOC: ' + message + ' : ' + argument); + }, + writeFile: function(fileName, content) { + console.log('##FileWrite: ' + fileName); + }, + rmRF: function(fileName) { + console.log('##rmRF: ' + fileName); + } + +}); +mockery.registerMock('q', { + 'defer': function() { + return { + promise: { + 'content': '0' + }, + resolve: function(result) { + return result; + } + }; + } +}); + +var fs = require('fs'); +mockery.registerMock('fs', { + 'createReadStream': function() { + return ''; + }, + statSync: fs.statSync, + writeFileSync: fs.writeFileSync, + readFileSync: fs.readFileSync +}); +var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' +}; + +var kuduUtility = require('../kuduutility.js'); +kuduUtility.runPostDeploymentScript(mockPublishProfile, 'site/wwwroot', "Inline Script", "run command xyz", null, false, true); diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsAllInput.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsAllInput.ts new file mode 100644 index 000000000000..4be5a6728a3d --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsAllInput.ts @@ -0,0 +1,233 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'webAppPkg.zip'); +tr.setInput('UseWebDeploy', 'true'); +tr.setInput('RemoveAdditionalFilesFlag', 'true'); +tr.setInput('ExcludeFilesFromAppDataFlag', 'true'); +tr.setInput('TakeAppOfflineFlag', 'false'); +tr.setInput('VirtualApplication', 'virtualApp'); +tr.setInput('AdditionalArguments', 'additionalArguments'); +tr.setInput('WebAppUri', 'someuri'); + +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = '1', +process.env["RELEASE_RELEASEID"] = '1'; +process.env["BUILD_BUILDNUMBER"] = '1'; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; + +// provide answers for task mock +let a: ma.TaskLibAnswers = { + "which": { + "msdeploy": "msdeploy" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + } + }, + "osType": { + "osType": "Windows" + }, + "checkPath": { + "webAppPkg.zip": true, + "webAppPkg": true, + "msdeploy": true + }, + "exec": { + "msdeploy -verb:getParameters -source:package=\'webAppPkg.zip\'": { + "code": 0, + "stdout": "Executed Successfully" + }, + "msdeploy -verb:sync -source:package=\'webAppPkg.zip\' -dest:auto,ComputerName=\'https://mytestappKuduUrl/msdeploy.axd?site=mytestapp\',UserName=\'$mytestapp\',Password=\'mytestappPwd\',AuthType=\'Basic\' -setParam:name=\'IIS Web Application Name\',value=\'mytestapp/virtualApp\' -skip:Directory=App_Data additionalArguments -userAgent:TFS_useragent": { + "code": 0, + "stdout": "Executed Successfully" + } + }, + "exist": { + "webAppPkg.zip": true, + "webAppPkg": true + }, + "glob": { + "webAppPkgPattern" : ["webAppPkg1", "webAppPkg2"], + "Invalid_webAppPkg" : [], + "webAppPkg.zip": ["webAppPkg.zip"], + "webAppPkg": ["webAppPkg"] + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "AZURE_HTTP_USER_AGENT": "TFS_useragent", + "System.DefaultWorkingDirectory": "DefaultWorkingDirectory", + "build.sourceVersion": "46da24f35850f455185b9188b4742359b537076f", + "build.buildId": '1', + "release.releaseId": '1', + "build.buildNumber": '1', + "release.releaseName": "Release-1", + "build.repository.provider": "TfsGit", + "build.repository.name": "MyFirstProject", + "system.TeamFoundationCollectionUri": "https://abc.visualstudio.com/", + "system.teamProject": "MyFirstProject", + "build.sourceVersionAuthor": "author", + "release.releaseUri": "vstfs:///ReleaseManagement/Release/1", + "agent.name": "agent" + } +} + + +import mockTask = require('vsts-task-lib/mock-task'); +tr.registerMock('webdeployment-common/ziputility.js', { + getArchivedEntries: function(webDeployPkg) { + return { + "entries":[ + "systemInfo.xml", + "parameters.xml" + ] + }; + } +}); +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); +tr.registerMock('./msdeployutility.js', { + getMSDeployCmdArgs : msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath : function() { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + } +}); + +tr.registerMock('./kuduutility.js', { + getVirtualAndPhysicalPaths : function() { + return ["/virtualApp", "/test/path"] + }, + ensurePhysicalPathExists: function() { + return true; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + appInsightsInstrumentationKeyAppSetting: "APPINSIGHTS_INSTRUMENTATIONKEY", + getAzureRMWebAppPublishProfile: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if(deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + getAzureRMWebAppConfigDetails: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [ ['Object'], ['Object'], ['Object'] ], + scmType: "None" + } + } + + return config; + }, + updateDeploymentStatus: function(publishingProfile, isDeploymentSuccess ) { + if(isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess); + requestDetails["requestBody"].author = 'author'; + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + getWebAppAppSettings : function (SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string){ + var appSettings = { + properties : { + MSDEPLOY_RENAME_LOCKED_FILES : '1' + } + }; + return appSettings; + }, + updateWebAppAppSettings : function (){ + return true; + }, + updateAzureRMWebAppConfigDetails: function() { + console.log("Successfully updated scmType to VSTSRM"); + }, + getAzureRMWebAppMetadata: function() { + return { + properties: {} + } + }, + updateAzureRMWebAppMetadata: function() { + console.log("Successfully updated Web App metadata"); + } +}); + +var fs = require('fs'); +tr.registerMock('fs', { + createWriteStream: function (filePath, options) { + return { + "isWriteStreamObj": true, + "on": (event) => { + console.log("event: " + event + " has occurred"); + }, + "end" : () => { return true } + }; + }, + ReadStream: fs.ReadStream, + WriteStream: fs.WriteStream, + openSync: function (fd, options) { + return true; + }, + closeSync: function (fd) { + return true; + }, + fsyncSync: function(fd) { + return true; + } +}); + +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsDefault.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsDefault.ts new file mode 100644 index 000000000000..4e40f872b15e --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsDefault.ts @@ -0,0 +1,229 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'webAppPkg.zip'); +tr.setInput('UseWebDeploy', 'true'); + +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = 1, +process.env["RELEASE_RELEASEID"] = 1; +process.env["BUILD_BUILDNUMBER"] = 1; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["SYSTEM_TEAMPROJECTID"] = 1; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; + +// provide answers for task mock +let a: ma.TaskLibAnswers = { + "which": { + "msdeploy": "msdeploy" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + } + }, + "osType": { + "osType": "Windows" + }, + "checkPath": { + "webAppPkg.zip": true, + "webAppPkg": true, + "msdeploy": true + }, + "exec": { + "msdeploy -verb:sync -source:package='webAppPkg.zip' -dest:auto,ComputerName='https://mytestappKuduUrl/msdeploy.axd?site=mytestapp',UserName='$mytestapp',Password='mytestappPwd',AuthType='Basic' -setParam:name='IIS Web Application Name',value='mytestapp' -enableRule:DoNotDeleteRule -userAgent:TFS_useragent": { + "code": 0, + "stdout": "Executed Successfully" + }, + "msdeploy -verb:getParameters -source:package=\'webAppPkg.zip\'": { + "code": 0, + "stdout": "Executed Successfully" + } + }, + "exist": { + "webAppPkg.zip": true, + "webAppPkg": true + }, + "glob": { + "webAppPkgPattern" : ["webAppPkg1", "webAppPkg2"], + "Invalid_webAppPkg" : [], + "webAppPkg.zip": ["webAppPkg.zip"], + "webAppPkg": ["webAppPkg"] + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "AZURE_HTTP_USER_AGENT": "TFS_useragent", + "System.DefaultWorkingDirectory": "DefaultWorkingDirectory", + "build.sourceVersion": "46da24f35850f455185b9188b4742359b537076f", + "build.buildId": 1, + "release.releaseId": 1, + "build.buildNumber": 1, + "release.releaseName": "Release-1", + "build.repository.provider": "TfsGit", + "build.repository.name": "MyFirstProject", + "system.TeamFoundationCollectionUri": "https://abc.visualstudio.com/", + "system.teamProject": "MyFirstProject", + "build.sourceVersionAuthor": "author", + "release.releaseUri": "vstfs:///ReleaseManagement/Release/1", + "agent.name": "agent" + } +} + +import mockTask = require('vsts-task-lib/mock-task'); +tr.registerMock('webdeployment-common/ziputility.js', { + getArchivedEntries: function(webDeployPkg) { + return { + "entries":[ + "systemInfo.xml", + "parameters.xml" + ] + }; + } +}); +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); + +tr.registerMock('./msdeployutility.js', { + getMSDeployCmdArgs : msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath : function() { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + appInsightsInstrumentationKeyAppSetting: "APPINSIGHTS_INSTRUMENTATIONKEY", + getAzureRMWebAppPublishProfile: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if(deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + getAzureRMWebAppConfigDetails: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [ ['Object'], ['Object'], ['Object'] ], + scmType: "None" + } + } + + return config; + }, + updateDeploymentStatus: function(publishingProfile, isDeploymentSuccess, customMessage) { + if(isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess, customMessage); + requestDetails["requestBody"].author = 'author'; + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + getWebAppAppSettings : function (SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string){ + var appSettings = { + properties : { + MSDEPLOY_RENAME_LOCKED_FILES: '1', + APPINSIGHTS_INSTRUMENTATIONKEY: "00000000-0000-0000-0000-000000000000" + } + }; + return appSettings; + }, + updateWebAppAppSettings : function (){ + return true; + }, + updateAzureRMWebAppConfigDetails: function() { + console.log("Successfully updated scmType to VSTSRM"); + }, + getAzureRMWebAppMetadata: function() { + return { + properties: {} + } + }, + updateAzureRMWebAppMetadata: function() { + console.log("Successfully updated Web App metadata"); + }, + getApplicationInsightsResources: () => { + return [{ + name: "ApplicationInsights", + id: "ApplicationInsightsResourceId", + InstrumentationKey: "00000000-0000-0000-0000-000000000000" + }]; + }, + addReleaseAnnotation: () => { + return { }; + } +}); + +var fs = require('fs'); +tr.registerMock('fs', { + createWriteStream: function (filePath, options) { + return { + "isWriteStreamObj": true, + "on": (event) => { + console.log("event: " + event + " has occurred"); + }, + "end" : () => { return true } + }; + }, + ReadStream: fs.ReadStream, + WriteStream: fs.WriteStream, + openSync: function (fd, options) { + return true; + }, + closeSync: function (fd) { + return true; + }, + fsyncSync: function(fd) { + return true; + } +}); + +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsDefaultReleaseAnnotationFail.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsDefaultReleaseAnnotationFail.ts new file mode 100644 index 000000000000..0145f0d6f8f8 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsDefaultReleaseAnnotationFail.ts @@ -0,0 +1,229 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'webAppPkg.zip'); +tr.setInput('UseWebDeploy', 'true'); + +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = 1, + process.env["RELEASE_RELEASEID"] = 1; +process.env["BUILD_BUILDNUMBER"] = 1; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["SYSTEM_TEAMPROJECTID"] = 1; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; + +// provide answers for task mock +let a: ma.TaskLibAnswers = { + "which": { + "msdeploy": "msdeploy" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + } + }, + "osType": { + "osType": "Windows" + }, + "checkPath": { + "webAppPkg.zip": true, + "webAppPkg": true, + "msdeploy": true + }, + "exec": { + "msdeploy -verb:sync -source:package='webAppPkg.zip' -dest:auto,ComputerName='https://mytestappKuduUrl/msdeploy.axd?site=mytestapp',UserName='$mytestapp',Password='mytestappPwd',AuthType='Basic' -setParam:name='IIS Web Application Name',value='mytestapp' -enableRule:DoNotDeleteRule -userAgent:TFS_useragent": { + "code": 0, + "stdout": "Executed Successfully" + }, + "msdeploy -verb:getParameters -source:package=\'webAppPkg.zip\'": { + "code": 0, + "stdout": "Executed Successfully" + } + }, + "exist": { + "webAppPkg.zip": true, + "webAppPkg": true + }, + "glob": { + "webAppPkgPattern": ["webAppPkg1", "webAppPkg2"], + "Invalid_webAppPkg": [], + "webAppPkg.zip": ["webAppPkg.zip"], + "webAppPkg": ["webAppPkg"] + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "AZURE_HTTP_USER_AGENT": "TFS_useragent", + "System.DefaultWorkingDirectory": "DefaultWorkingDirectory", + "build.sourceVersion": "46da24f35850f455185b9188b4742359b537076f", + "build.buildId": 1, + "release.releaseId": 1, + "build.buildNumber": 1, + "release.releaseName": "Release-1", + "build.repository.provider": "TfsGit", + "build.repository.name": "MyFirstProject", + "system.TeamFoundationCollectionUri": "https://abc.visualstudio.com/", + "system.teamProject": "MyFirstProject", + "build.sourceVersionAuthor": "author", + "release.releaseUri": "vstfs:///ReleaseManagement/Release/1", + "agent.name": "agent" + } +} + +import mockTask = require('vsts-task-lib/mock-task'); +tr.registerMock('webdeployment-common/ziputility.js', { + getArchivedEntries: function (webDeployPkg) { + return { + "entries": [ + "systemInfo.xml", + "parameters.xml" + ] + }; + } +}); +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); + +tr.registerMock('./msdeployutility.js', { + getMSDeployCmdArgs: msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath: function () { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + appInsightsInstrumentationKeyAppSetting: "APPINSIGHTS_INSTRUMENTATIONKEY", + getAzureRMWebAppPublishProfile: function (SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if (deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + getAzureRMWebAppConfigDetails: function (SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [['Object'], ['Object'], ['Object']], + scmType: "None" + } + } + + return config; + }, + updateDeploymentStatus: function (publishingProfile, isDeploymentSuccess, customMessage) { + if (isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess, customMessage); + requestDetails["requestBody"].author = 'author'; + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + getWebAppAppSettings: function (SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string) { + var appSettings = { + properties: { + MSDEPLOY_RENAME_LOCKED_FILES: '1', + APPINSIGHTS_INSTRUMENTATIONKEY: "00000000-0000-0000-0000-000000000000" + } + }; + return appSettings; + }, + updateWebAppAppSettings: function () { + return true; + }, + updateAzureRMWebAppConfigDetails: function () { + console.log("Successfully updated scmType to VSTSRM"); + }, + getAzureRMWebAppMetadata: function () { + return { + properties: {} + } + }, + updateAzureRMWebAppMetadata: function () { + console.log("Successfully updated Web App metadata"); + }, + getApplicationInsightsResources: () => { + return [{ + name: "ApplicationInsights", + id: "ApplicationInsightsResourceId", + InstrumentationKey: "00000000-0000-0000-0000-000000000000" + }]; + }, + addReleaseAnnotation: () => { + throw "Random error"; + } +}); + +var fs = require('fs'); +tr.registerMock('fs', { + createWriteStream: function (filePath, options) { + return { + "isWriteStreamObj": true, + "on": (event) => { + console.log("event: " + event + " has occurred"); + }, + "end": () => { return true } + }; + }, + ReadStream: fs.ReadStream, + WriteStream: fs.WriteStream, + openSync: function (fd, options) { + return true; + }, + closeSync: function (fd) { + return true; + }, + fsyncSync: function (fd) { + return true; + } +}); + +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsFailDefault.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsFailDefault.ts new file mode 100644 index 000000000000..8428548d55d6 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsFailDefault.ts @@ -0,0 +1,211 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'webAppPkg.zip'); +tr.setInput('UseWebDeploy', 'true'); + +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = '1', +process.env["RELEASE_RELEASEID"] = '1'; +process.env["BUILD_BUILDNUMBER"] = '1'; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["SYSTEM_TEAMPROJECTID"] = 1; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; + +// provide answers for task mock +let a: any = { + "which": { + "msdeploy": "msdeploy" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + } + }, + "osType": { + "osType": "Windows" + }, + "checkPath": { + "webAppPkg.zip": true, + "webAppPkg": true, + "msdeploy": true + }, + "exec": { + "msdeploy -verb:getParameters -source:package=\'webAppPkg.zip\'": { + "code": 0, + "stdout": "Executed Successfully" + }, + "msdeploy -verb:sync -source:package=\'webAppPkg.zip\' -dest:auto,ComputerName=\'https://mytestappKuduUrl/msdeploy.axd?site=mytestapp\',UserName=\'$mytestapp\',Password=\'mytestappPwd\',AuthType=\'Basic\' -setParam:name=\'IIS Web Application Name\',value=\'mytestapp\' -enableRule:DoNotDeleteRule -userAgent:TFS_useragent": { + "code": 1, + "stdout": "Failed to Deploy WebSite" + } + }, + "exist": { + "webAppPkg.zip": true, + "DefaultWorkingDirectory\\error.txt": true + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "SYSTEM_DEFAULTWORKINGDIRECTORY" : "defaultWorkingDirectory", + "AZURE_HTTP_USER_AGENT" : "TFS_useragent", + "System.DefaultWorkingDirectory" : "DefaultWorkingDirectory", + "release.releaseId": '1', + "release.releaseName": "Release-1", + "system.TeamFoundationCollectionUri": "https://abc.visualstudio.com/", + "system.teamProject": "MyFirstProject", + "release.releaseUri": "vstfs:///ReleaseManagement/Release/1", + "agent.name": "agent" + }, + "rmRF": { + "DefaultWorkingDirectory\\error.txt": true + } +}; + +import mockTask = require('vsts-task-lib/mock-task'); +tr.registerMock('webdeployment-common/ziputility.js', { + getArchivedEntries: function(webDeployPkg) { + return { + "entries":[ + "systemInfo.xml", + "parameters.xml" + ] + }; + } +}); +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); +tr.registerMock('./msdeployutility.js', { + shouldRetryMSDeploy: msDeployUtility.shouldRetryMSDeploy, + redirectMSDeployErrorToConsole : msDeployUtility.redirectMSDeployErrorToConsole, + getMSDeployCmdArgs : msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath : function() { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + getAzureRMWebAppPublishProfile: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if(deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + getAzureRMWebAppConfigDetails: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [ ['Object'], ['Object'], ['Object'] ], + scmType: "None" + } + } + + return config; + }, + updateDeploymentStatus: function(publishingProfile, isDeploymentSuccess, customMessage ) { + if(isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess, customMessage); + requestDetails["requestBody"].author = 'author'; + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + getWebAppAppSettings : function (SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string){ + var appSettings = { + properties : { + MSDEPLOY_RENAME_LOCKED_FILES : '1' + } + }; + return appSettings; + }, + updateWebAppAppSettings : function (){ + return true; + }, + updateAzureRMWebAppConfigDetails: function() { + console.log("Successfully updated scmType to VSTSRM"); + } +}); + +var fs = require('fs'); +tr.registerMock('fs', { + createWriteStream: function (filePath, options) { + var retryFunction; + return { + "isWriteStreamObj": true, + "on": (name, functionOnFinish) => { retryFunction = functionOnFinish;}, + "end" : () => { + if(retryFunction != null) { + retryFunction(); + } + return true; + } + }; + }, + ReadStream: fs.ReadStream, + WriteStream: fs.WriteStream, + readFileSync: function(msDeployErrorFilePath) { + console.log("reading the error file"); + return "ERROR DEPLOYING WEBSITE"; + }, + openSync: function (fd, options) { + return true; + }, + closeSync: function (fd) { + return true; + }, + fsyncSync: function(fd) { + return true; + } +}); + +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsFailSetParamFile.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsFailSetParamFile.ts new file mode 100644 index 000000000000..f539d5dd4f4d --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsFailSetParamFile.ts @@ -0,0 +1,168 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'webAppPkg.zip'); +tr.setInput('UseWebDeploy', 'true'); +tr.setInput('SetParametersFile', 'invalidparameterFile.xml'); + +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = '1', +process.env["RELEASE_RELEASEID"] = '1'; +process.env["BUILD_BUILDNUMBER"] = '1'; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; + +let a: ma.TaskLibAnswers = { + "which": { + "msdeploy": "msdeploy" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + }, + "invalidparameterFile.xml": { + "isFile" : false + }, + "parameterFileUser.xml": { + "isFile" : true + } + }, + "checkPath": { + "webAppPkg.zip": true, + "webAppPkg": true, + "msdeploy": true + }, + "osType": { + "osType": "Windows" + }, + "exec": { + "cmd /C DefaultWorkingDirectory\\msDeployCommand.bat": { + "code" : 0, + "stdout": "Executed Successfully" + }, + "cmd /C DefaultWorkingDirectory\\msDeployParam.bat": { + "code" : 0, + "stdout": "Executed Successfully" + } + }, + "exist": { + "webAppPkg.zip": true + }, + "findMatch": { + "webAppPkg.zip": ["webAppPkg.zip"], + "webAppPkg": ["webAppPkg"] + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "SYSTEM_DEFAULTWORKINGDIRECTORY": "defaultWorkingDirectory", + "AZURE_HTTP_USER_AGENT": "TFS_useragent", + "System.DefaultWorkingDirectory" : "DefaultWorkingDirectory", + "build.sourcesDirectory": "DefaultWorkingDirectory" + } +}; + + +import mockTask = require('vsts-task-lib/mock-task'); +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); +tr.registerMock('./msdeployutility.js', { + getMSDeployCmdArgs : msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath : function() { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + getAzureRMWebAppPublishProfile: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if(deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + getAzureRMWebAppConfigDetails: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [ ['Object'], ['Object'], ['Object'] ], + scmType: "None" + } + } + + return config; + }, + updateDeploymentStatus: function(publishingProfile, isDeploymentSuccess ) { + if(isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess); + requestDetails["requestBody"].author = 'author'; + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + getWebAppAppSettings : function (SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string){ + var appSettings = { + properties : { + MSDEPLOY_RENAME_LOCKED_FILES : '1' + } + }; + return appSettings; + }, + updateWebAppAppSettings : function (){ + return true; + }, + updateAzureRMWebAppConfigDetails: function() { + console.log("Successfully updated scmType to VSTSRM"); + } +}); + +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsFolderPkg.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsFolderPkg.ts new file mode 100644 index 000000000000..20aab23f6933 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsFolderPkg.ts @@ -0,0 +1,211 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'webAppPkg'); +tr.setInput('UseWebDeploy', 'true'); + +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = 1, +process.env["RELEASE_RELEASEID"] = 1; +process.env["BUILD_BUILDNUMBER"] = 1; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; + +// provide answers for task mock +let a: ma.TaskLibAnswers = { + "which": { + "msdeploy": "msdeploy" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + } + }, + "osType": { + "osType": "Windows" + }, + "checkPath": { + "msdeploy": true, + "webAppPkg.zip": true, + "webAppPkg": true + }, + "exec": { + "msdeploy -verb:getParameters -source:package=\'webAppPkg.zip\'": { + "code": 0, + "stdout": "Executed Successfully" + }, + "msdeploy -verb:sync -source:IisApp=\'webAppPkg\' -dest:iisApp=\'mytestapp\',ComputerName=\'https://mytestappKuduUrl/msdeploy.axd?site=mytestapp\',UserName=\'$mytestapp\',Password=\'mytestappPwd\',AuthType=\'Basic\' -enableRule:DoNotDeleteRule -userAgent:TFS_useragent":{ + "code": 0, + "stdout": "Executed Successfully" + } + }, + "exist": { + "webAppPkg.zip": true, + "webAppPkg": true + }, + "glob": { + "webAppPkgPattern" : ["webAppPkg1", "webAppPkg2"], + "Invalid_webAppPkg" : [], + "webAppPkg.zip": ["webAppPkg.zip"], + "webAppPkg": ["webAppPkg"] + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "AZURE_HTTP_USER_AGENT": "TFS_useragent", + "System.DefaultWorkingDirectory": "DefaultWorkingDirectory", + "build.sourceVersion": "46da24f35850f455185b9188b4742359b537076f", + "build.buildId": 1, + "release.releaseId": 1, + "build.buildNumber": 1, + "release.releaseName": "Release-1", + "build.repository.provider": "TfsGit", + "build.repository.name": "MyFirstProject", + "system.TeamFoundationCollectionUri": "https://abc.visualstudio.com/", + "system.teamProject": "MyFirstProject", + "build.sourceVersionAuthor": "author", + "release.releaseUri": "vstfs:///ReleaseManagement/Release/1", + "agent.name": "agent" + } +} + +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); +tr.registerMock('./msdeployutility.js', { + getMSDeployCmdArgs : msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath : function() { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + getAzureRMWebAppPublishProfile: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if(deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + getAzureRMWebAppConfigDetails: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [ ['Object'], ['Object'], ['Object'] ], + scmType: "None" + } + } + + return config; + }, + updateDeploymentStatus: function(publishingProfile, isDeploymentSuccess ) { + if(isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess); + requestDetails["requestBody"].author = 'author'; + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + getWebAppAppSettings : function (SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string){ + var appSettings = { + properties : { + MSDEPLOY_RENAME_LOCKED_FILES : '1' + } + }; + return appSettings; + }, + updateWebAppAppSettings : function (){ + return true; + }, + updateAzureRMWebAppConfigDetails: function() { + console.log("Successfully updated scmType to VSTSRM"); + }, + getAzureRMWebAppMetadata: function() { + return { + properties: {} + } + }, + updateAzureRMWebAppMetadata: function() { + console.log("Successfully updated Web App metadata"); + } +}); + +var fs = require('fs'); +tr.registerMock('fs', { + createWriteStream: function (filePath, options) { + return { + "isWriteStreamObj": true, + "on": (event) => { + console.log("event: " + event + " has been triggered"); + }, + "end" : () => { return true; } + }; + }, + ReadStream: fs.ReadStream, + WriteStream: fs.WriteStream, + openSync: function (fd, options) { + return true; + }, + closeSync: function (fd) { + return true; + }, + fsyncSync: function(fd) { + return true; + }, + fstat: fs.fstat, + read: fs.read, + open: fs.open, + writeFile: fs.writeFile, + symlink: fs.symlink, + stat: fs.stat +}); + +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsManyPackage.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsManyPackage.ts new file mode 100644 index 000000000000..c341c320d1f5 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsManyPackage.ts @@ -0,0 +1,181 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'C:/pattern/**/*.zip'); +tr.setInput('UseWebDeploy', 'true'); + +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = 1, +process.env["RELEASE_RELEASEID"] = 1; +process.env["BUILD_BUILDNUMBER"] = 1; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; + +// provide answers for task mock +let a: ma.TaskLibAnswers = { + "which": { + "cmd": "cmd" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + } + }, + "osType": { + "osType": "Windows" + }, + "checkPath": { + "cmd": true, + "webAppPkg.zip": true, + "webAppPkg": true + }, + "match": { + "C:/pattern/**/*.zip":["webAppPkg1", "webAppPkg2"] + }, + "find" : { + "C:/pattern/":["C:/pattern/webAppPkg.zip", "C:/pattern/webAppPkg1.zip"] + }, + "exec": { + "cmd /C DefaultWorkingDirectory\\msDeployCommand.bat": { + "code": 0, + "stdout": "Executed Successfully" + }, + "cmd /C DefaultWorkingDirectory\\msDeployParam.bat": { + "code": 0, + "stdout": "Executed Successfully" + } + }, + "exist": { + "webAppPkg.zip": true, + "webAppPkg": true + }, + "glob": { + "webAppPkgPattern" : ["webAppPkg1", "webAppPkg2"], + "Invalid_webAppPkg" : [], + "webAppPkg.zip": ["webAppPkg.zip"], + "webAppPkg": ["webAppPkg"] + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "AZURE_HTTP_USER_AGENT": "TFS_useragent", + "System.DefaultWorkingDirectory": "DefaultWorkingDirectory", + "build.sourceVersion": "46da24f35850f455185b9188b4742359b537076f", + "build.buildId": 1, + "release.releaseId": 1, + "build.buildNumber": 1, + "release.releaseName": "Release-1", + "build.repository.provider": "TfsGit", + "build.repository.name": "MyFirstProject", + "system.TeamFoundationCollectionUri": "https://abc.visualstudio.com/", + "system.teamProject": "MyFirstProject", + "build.sourceVersionAuthor": "author", + "release.releaseUri": "vstfs:///ReleaseManagement/Release/1", + "agent.name": "agent" + } +} + + +import mockTask = require('vsts-task-lib/mock-task'); +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); +tr.registerMock('./msdeployutility.js', { + getMSDeployCmdArgs : msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath : function() { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + getAzureRMWebAppPublishProfile: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if(deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + getAzureRMWebAppConfigDetails: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [ ['Object'], ['Object'], ['Object'] ], + scmType: "None" + } + } + + return config; + }, + updateDeploymentStatus: function(publishingProfile, isDeploymentSuccess ) { + if(isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess); + requestDetails["requestBody"].author = 'author'; + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + getWebAppAppSettings : function (SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string){ + var appSettings = { + properties : { + MSDEPLOY_RENAME_LOCKED_FILES : '1' + } + }; + return appSettings; + }, + updateWebAppAppSettings : function (){ + return true; + }, + updateAzureRMWebAppConfigDetails: function() { + console.log("Successfully updated scmType to VSTSRM"); + } +}); + +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsNoPackage.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsNoPackage.ts new file mode 100644 index 000000000000..b823093281b4 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsNoPackage.ts @@ -0,0 +1,176 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'Invalid_webAppPkg'); +tr.setInput('UseWebDeploy', 'true'); + +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = 1, +process.env["RELEASE_RELEASEID"] = 1; +process.env["BUILD_BUILDNUMBER"] = 1; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; + +// provide answers for task mock +let a: ma.TaskLibAnswers = { + "which": { + "cmd": "cmd" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + } + }, + "osType": { + "osType": "Windows" + }, + "checkPath": { + "cmd": true, + "webAppPkg.zip": true, + "webAppPkg": true + }, + "exec": { + "cmd /C DefaultWorkingDirectory\\msDeployCommand.bat": { + "code": 0, + "stdout": "Executed Successfully" + }, + "cmd /C DefaultWorkingDirectory\\msDeployParam.bat": { + "code": 0, + "stdout": "Executed Successfully" + } + }, + "exist": { + "webAppPkg.zip": true, + "webAppPkg": true, + "Invalid_webAppPkg": false + }, + "glob": { + "webAppPkgPattern" : ["webAppPkg1", "webAppPkg2"], + "Invalid_webAppPkg" : [], + "webAppPkg.zip": ["webAppPkg.zip"], + "webAppPkg": ["webAppPkg"] + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "AZURE_HTTP_USER_AGENT": "TFS_useragent", + "System.DefaultWorkingDirectory": "DefaultWorkingDirectory", + "build.sourceVersion": "46da24f35850f455185b9188b4742359b537076f", + "build.buildId": 1, + "release.releaseId": 1, + "build.buildNumber": 1, + "release.releaseName": "Release-1", + "build.repository.provider": "TfsGit", + "build.repository.name": "MyFirstProject", + "system.TeamFoundationCollectionUri": "https://abc.visualstudio.com/", + "system.teamProject": "MyFirstProject", + "build.sourceVersionAuthor": "author", + "release.releaseUri": "vstfs:///ReleaseManagement/Release/1", + "agent.name": "agent" + } +} + + +import mockTask = require('vsts-task-lib/mock-task'); +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); +tr.registerMock('./msdeployutility.js', { + getMSDeployCmdArgs : msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath : function() { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + getAzureRMWebAppPublishProfile: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if(deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + getAzureRMWebAppConfigDetails: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [ ['Object'], ['Object'], ['Object'] ], + scmType: "None" + } + } + + return config; + }, + updateDeploymentStatus: function(publishingProfile, isDeploymentSuccess ) { + if(isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess); + requestDetails["requestBody"].author = 'author'; + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + getWebAppAppSettings : function (SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string){ + var appSettings = { + properties : { + MSDEPLOY_RENAME_LOCKED_FILES : '1' + } + }; + return appSettings; + }, + updateWebAppAppSettings : function (){ + return true; + }, + updateAzureRMWebAppConfigDetails: function() { + console.log("Successfully updated scmType to VSTSRM"); + } +}); + +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsParamFileinPkg.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsParamFileinPkg.ts new file mode 100644 index 000000000000..17be091d39c3 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsParamFileinPkg.ts @@ -0,0 +1,220 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'webAppPkg.zip'); +tr.setInput('UseWebDeploy', 'true'); +tr.setInput('SetParametersFile', 'parameterFilePresent.xml'); + +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = '1', +process.env["RELEASE_RELEASEID"] = '1'; +process.env["BUILD_BUILDNUMBER"] = '1'; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; + +let a: ma.TaskLibAnswers = { + "which": { + "msdeploy": "msdeploy" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + }, + "parameterFilePresent.xml": { + "isFile" : true + }, + "parameterFileUser.xml": { + "isFile" : true + } + }, + "checkPath": { + "msdeploy" : true, + "webAppPkg.zip": true, + "webAppPkg": true + }, + "osType": { + "osType": "Windows" + }, + "rmRF": { + "DefaultWorkingDirectory\\tempSetParameters.xml": { + "success": true + } + }, + "exec": { + "msdeploy -verb:getParameters -source:package=\'webAppPkg.zip\'": { + "code": 0, + "stdout": "Executed Successfully" + }, + "msdeploy -verb:sync -source:package=\'webAppPkg.zip\' -dest:auto,ComputerName=\'https://mytestappKuduUrl/msdeploy.axd?site=mytestapp\',UserName=\'$mytestapp\',Password=\'mytestappPwd\',AuthType=\'Basic\' -setParam:name=\'IIS Web Application Name\',value=\'mytestapp\' -setParamFile=tempSetParameters.xml -enableRule:DoNotDeleteRule -userAgent:TFS_useragent": { + "code": 0, + "stdout": "Executed Successfully" + } + }, + "exist": { + "webAppPkg.zip": true, + "DefaultWorkingDirectory\\tempSetParameters.xml": true + }, + "glob": { + "webAppPkg.zip": ["webAppPkg.zip"], + "webAppPkg": ["webAppPkg"] + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "SYSTEM_DEFAULTWORKINGDIRECTORY": "defaultWorkingDirectory", + "AZURE_HTTP_USER_AGENT": "TFS_useragent", + "System.DefaultWorkingDirectory" : "DefaultWorkingDirectory", + "build.sourcesDirectory": "DefaultWorkingDirectory" + } +}; + + +import mockTask = require('vsts-task-lib/mock-task'); +tr.registerMock('webdeployment-common/ziputility.js', { + getArchivedEntries: function(webDeployPkg) { + return { + "entries":[ + "systemInfo.xml", + "parameters.xml" + ] + }; + } +}); +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); +tr.registerMock('./msdeployutility.js', { + getMSDeployCmdArgs : msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath : function() { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + getAzureRMWebAppPublishProfile: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if(deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + getAzureRMWebAppConfigDetails: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [ ['Object'], ['Object'], ['Object'] ], + scmType: "None" + } + } + + return config; + }, + updateDeploymentStatus: function(publishingProfile, isDeploymentSuccess ) { + if(isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess); + requestDetails["requestBody"].author = 'author'; + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + getWebAppAppSettings : function (SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string){ + var appSettings = { + properties : { + MSDEPLOY_RENAME_LOCKED_FILES : '1' + } + }; + return appSettings; + }, + updateWebAppAppSettings : function (){ + return true; + }, + updateAzureRMWebAppConfigDetails: function() { + console.log("Successfully updated scmType to VSTSRM"); + }, + getAzureRMWebAppMetadata: function() { + return { + properties: {} + } + }, + updateAzureRMWebAppMetadata: function() { + console.log("Successfully updated Web App metadata"); + } +}); + +var fs = require('fs'); +tr.registerMock('fs', { + createWriteStream: function (filePath, options) { + return { + "isWriteStreamObj": true, + "on": (event) => { + console.log("event: " + event + " has occurred"); + }, + "end" : () => { return true } + }; + }, + ReadStream: fs.ReadStream, + WriteStream: fs.WriteStream, + readFileSync: function(msDeployErrorFilePath) { + console.log("reading the error file"); + return "ERROR DEPLOYING WEBSITE"; + }, + openSync: function (fd, options) { + return true; + }, + closeSync: function (fd) { + return true; + }, + fsyncSync: function(fd) { + return true; + } +}); + +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsSpecificSlot.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsSpecificSlot.ts new file mode 100644 index 000000000000..9d0f14880afd --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsSpecificSlot.ts @@ -0,0 +1,226 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'webAppPkg.zip'); +tr.setInput('UseWebDeploy', 'true'); +tr.setInput('DeployToSlotFlag', 'true'); +tr.setInput('ResourceGroupName', 'mytestappRg'); +tr.setInput('SlotName', 'testslot'); + +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = '1', +process.env["RELEASE_RELEASEID"] = '1'; +process.env["BUILD_BUILDNUMBER"] = '1'; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; + +// provide answers for task mock +let a: ma.TaskLibAnswers = { + "which": { + "msdeploy": "msdeploy" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + } + }, + "osType": { + "osType": "Windows" + }, + "checkPath": { + "webAppPkg.zip": true, + "webAppPkg": true, + "msdeploy": true + }, + "exec": { + "msdeploy -verb:getParameters -source:package=\'webAppPkg.zip\'": { + "code": 0, + "stdout": "Executed Successfully" + }, + "msdeploy -verb:sync -source:package=\'webAppPkg.zip\' -dest:auto,ComputerName=\'https://mytestappKuduUrl-testslot/msdeploy.axd?site=mytestapp\',UserName=\'$mytestapp__testslot\',Password=\'mytestappPwd\',AuthType=\'Basic\' -setParam:name=\'IIS Web Application Name\',value=\'mytestapp\' -enableRule:DoNotDeleteRule -userAgent:TFS_useragent": { + "code": 0, + "stdout": "Executed Successfully" + } + }, + "exist": { + "webAppPkg.zip": true, + "webAppPkg": true + }, + "glob": { + "webAppPkgPattern" : ["webAppPkg1", "webAppPkg2"], + "Invalid_webAppPkg" : [], + "webAppPkg.zip": ["webAppPkg.zip"], + "webAppPkg": ["webAppPkg"] + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "AZURE_HTTP_USER_AGENT": "TFS_useragent", + "System.DefaultWorkingDirectory": "DefaultWorkingDirectory", + "build.sourceVersion": "46da24f35850f455185b9188b4742359b537076f", + "build.buildId": '1', + "release.releaseId": '1', + "build.buildNumber": '1', + "release.releaseName": "Release-1", + "build.repository.provider": "TfsGit", + "build.repository.name": "MyFirstProject", + "system.TeamFoundationCollectionUri": "https://abc.visualstudio.com/", + "system.teamProject": "MyFirstProject", + "build.sourceVersionAuthor": "author", + "release.releaseUri": "vstfs:///ReleaseManagement/Release/1", + "agent.name": "agent" + } +} + + +import mockTask = require('vsts-task-lib/mock-task'); +tr.registerMock('webdeployment-common/ziputility.js', { + getArchivedEntries: function(webDeployPkg) { + return { + "entries":[ + "systemInfo.xml", + "parameters.xml" + ] + }; + } +}); +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); +tr.registerMock('./msdeployutility.js', { + getMSDeployCmdArgs : msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath : function() { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + appInsightsInstrumentationKeyAppSetting: "APPINSIGHTS_INSTRUMENTATIONKEY", + getAzureRMWebAppPublishProfile: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if(deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + + getAzureRMWebAppConfigDetails: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [ ['Object'], ['Object'], ['Object'] ], + scmType: "None" + } + } + + return config; + }, + updateDeploymentStatus: function(publishingProfile, isDeploymentSuccess ) { + if(isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess); + requestDetails["requestBody"].author = 'author'; + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + getWebAppAppSettings : function (SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string){ + var appSettings = { + properties : { + MSDEPLOY_RENAME_LOCKED_FILES: '1', + APPINSIGHTS_INSTRUMENTATIONKEY: "00000000-0000-0000-0000-000000000000" + } + }; + return appSettings; + }, + updateWebAppAppSettings : function (){ + return true; + }, + updateAzureRMWebAppConfigDetails: function() { + console.log("Successfully updated scmType to VSTSRM"); + }, + getAzureRMWebAppMetadata: function() { + return { + properties: {} + } + }, + updateAzureRMWebAppMetadata: function() { + console.log("Successfully updated Web App metadata"); + }, + getApplicationInsightsResources: () => { + return []; + } +}); + +var fs = require('fs'); +tr.registerMock('fs', { + createWriteStream: function (filePath, options) { + return { + "isWriteStreamObj": true, + "on": (event) => { + console.log("event: " + event + " has occurred"); + }, + "end" : () => { return true } + }; + }, + ReadStream: fs.ReadStream, + WriteStream: fs.WriteStream, + openSync: function (fd, options) { + return true; + }, + closeSync: function (fd) { + return true; + }, + fsyncSync: function(fd) { + return true; + } +}); + +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsXdtTransformation.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsXdtTransformation.ts new file mode 100644 index 000000000000..2e96d246c2e4 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsXdtTransformation.ts @@ -0,0 +1,279 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'webAppPkg.zip'); +tr.setInput('UseWebDeploy', 'true'); +tr.setInput('XmlTransformation', 'true'); + +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = 1, +process.env["RELEASE_RELEASEID"] = 1; +process.env["BUILD_BUILDNUMBER"] = 1; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; +process.env['SYSTEM_DEBUG'] = 'true'; + +// provide answers for task mock +let a: ma.TaskLibAnswers = { + "which": { + "cmd": "cmd", + "msdeploy": "msdeploy", + "DefaultWorkingDirectory/ctt/ctt.exe": "DefaultWorkingDirectory/ctt/ctt.exe" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + } + }, + "osType": { + "osType": "Windows" + }, + "checkPath": { + "cmd": true, + "webAppPkg.zip": true, + "webAppPkg": true, + "msdeploy": true, + "DefaultWorkingDirectory/ctt/ctt.exe": true + }, + "exec": { + "DefaultWorkingDirectory/ctt/ctt.exe s:C:\\tempFolder\\web.config t:C:\\tempFolder\\web.Release.config d:C:\\tempFolder\\web.config pw i verbose": { + "code": 0, + "stdout": "ctt execution successful" + }, + "msdeploy -verb:sync -source:package=\'DefaultWorkingDirectory\\temp_web_package.zip\' -dest:auto,ComputerName=\'https://mytestappKuduUrl/msdeploy.axd?site=mytestapp\',UserName=\'$mytestapp\',Password=\'mytestappPwd\',AuthType=\'Basic\' -setParam:name=\'IIS Web Application Name\',value=\'mytestapp\' -enableRule:DoNotDeleteRule -userAgent:TFS_useragent": { + "code": 0, + "stdout": "Executed Successfully" + } + }, + "rmRF": { + "temp_web_package_random_path": { + "success": true + }, + "DefaultWorkingDirectory\\temp_web_package.zip": { + "success": true + } + }, + "exist": { + "webAppPkg.zip": true, + "webAppPkg": true + }, + "findMatch": { + "webAppPkgPattern" : ["webAppPkg1", "webAppPkg2"], + "Invalid_webAppPkg" : [], + "webAppPkg.zip": ["webAppPkg.zip"], + "webAppPkg": ["webAppPkg"], + "**/*.config": ["C:\\tempFolder\\web.config", "C:\\tempFolder\\web.Release.config", "C:\\tempFolder\\web.Debug.config"] + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "AZURE_HTTP_USER_AGENT": "TFS_useragent", + "System.DefaultWorkingDirectory": "DefaultWorkingDirectory", + "build.sourceVersion": "46da24f35850f455185b9188b4742359b537076f", + "build.buildId": 1, + "release.releaseId": 1, + "build.buildNumber": 1, + "release.releaseName": "Release-1", + "build.repository.provider": "TfsGit", + "build.repository.name": "MyFirstProject", + "system.TeamFoundationCollectionUri": "https://abc.visualstudio.com/", + "system.teamProject": "MyFirstProject", + "build.sourceVersionAuthor": "author", + "release.releaseUri": "vstfs:///ReleaseManagement/Release/1", + "agent.name": "agent" + } +}; + +import mockTask = require('vsts-task-lib/mock-task'); +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); +tr.registerMock('./msdeployutility.js', { + getMSDeployCmdArgs : msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath : function() { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + getAzureRMWebAppPublishProfile: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if(deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + getAzureRMWebAppConfigDetails: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [ ['Object'], ['Object'], ['Object'] ], + scmType: "None" + } + } + + return config; + }, + updateDeploymentStatus: function(publishingProfile, isDeploymentSuccess ) { + if(isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess); + requestDetails["requestBody"].author = 'author'; + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + getWebAppAppSettings : function (SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string){ + var appSettings = { + properties : { + MSDEPLOY_RENAME_LOCKED_FILES : '1' + } + }; + return appSettings; + }, + updateWebAppAppSettings : function (){ + return true; + }, + updateAzureRMWebAppConfigDetails: function() { + console.log("Successfully updated scmType to VSTSRM"); + }, + getAzureRMWebAppMetadata: function() { + return { + properties: {} + } + }, + updateAzureRMWebAppMetadata: function() { + console.log("Successfully updated Web App metadata"); + } +}); + +tr.registerMock('webdeployment-common/ziputility.js', { + unzip: function() { + + }, + getArchivedEntries: function(webDeployPkg) { + return { + "entries":[ + "systemInfo.xml", + "parameters.xml" + ] + }; + } +}); + +tr.registerMock('webdeployment-common/utility.js', { + isInputPkgIsFolder: function() { + return false; + }, + fileExists: function() { + return true; + }, + canUseWebDeploy: function() { + return true; + }, + findfiles: function() { + return ['webDeployPkg'] + }, + generateTemporaryFolderForDeployment: function() { + return 'temp_web_package_random_path'; + }, + archiveFolderForDeployment: function() { + return { + "webDeployPkg": "DefaultWorkingDirectory\\temp_web_package.zip", + "tempPackagePath": "DefaultWorkingDirectory\\temp_web_package.zip" + }; + }, + isMSDeployPackage: function() { + return true; + } +}); + +var fs = require('fs'); +tr.registerMock('fs', { + createWriteStream: function (filePath, options) { + return { + "isWriteStreamObj": true, + "on": (event) => { + console.log("event: " + event + " has occurred"); + }, + "end" : () => { return true } + }; + }, + ReadStream: fs.ReadStream, + WriteStream: fs.WriteStream, + openSync: function (fd, options) { + return true; + }, + closeSync: function (fd) { + return true; + }, + fsyncSync: function(fd) { + return true; + } +}); + +tr.registerMock('path', { + win32: { + basename: function(filePath, extension) { + return path.win32.basename(filePath, extension); + } + }, + join: function() { + if(arguments[arguments.length -1] === 'ctt.exe') { + return 'DefaultWorkingDirectory/ctt/ctt.exe'; + } + var args = []; + for(var i=0; i < arguments.length; i += 1) { + args.push(arguments[i]); + } + return args.join('\\'); + }, + dirname: path.dirname +}); +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsXdtTransformationFail.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsXdtTransformationFail.ts new file mode 100644 index 000000000000..373c6f2f6e6a --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0WindowsXdtTransformationFail.ts @@ -0,0 +1,228 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'webAppPkg.zip'); +tr.setInput('UseWebDeploy', 'true'); +tr.setInput('XmlTransformation', 'true'); + +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = 1, +process.env["RELEASE_RELEASEID"] = 1; +process.env["BUILD_BUILDNUMBER"] = 1; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; +process.env['SYSTEM_DEBUG'] = false; + +// provide answers for task mock +let a: ma.TaskLibAnswers = { + "which": { + "cmd": "cmd", + "DefaultWorkingDirectory/ctt/ctt.exe": "DefaultWorkingDirectory/ctt/ctt.exe" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + } + }, + "osType": { + "osType": "Windows" + }, + "checkPath": { + "cmd": true, + "webAppPkg.zip": true, + "webAppPkg": true, + "DefaultWorkingDirectory/ctt/ctt.exe": true + }, + "exec": { + "cmd /C DefaultWorkingDirectory\\msDeployCommand.bat": { + "code": 0, + "stdout": "Executed Successfully" + }, + "cmd /C DefaultWorkingDirectory\\msDeployParam.bat": { + "code": 0, + "stdout": "Executed Successfully" + }, + "DefaultWorkingDirectory/ctt/ctt.exe s:C:\\tempFolder\\web.config t:C:\\tempFolder\\web.Release.config d:C:\\tempFolder\\web.config pw i": { + "code": 1, + "stderr": "ctt execution failed" + } + }, + "exist": { + "webAppPkg.zip": true, + "webAppPkg": true + }, + "findMatch": { + "webAppPkgPattern" : ["webAppPkg1", "webAppPkg2"], + "Invalid_webAppPkg" : [], + "webAppPkg.zip": ["webAppPkg.zip"], + "webAppPkg": ["webAppPkg"], + "**/*.config": ["C:\\tempFolder\\web.config", "C:\\tempFolder\\web.Release.config", "C:\\tempFolder\\web.Debug.config"] + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "AZURE_HTTP_USER_AGENT": "TFS_useragent", + "System.DefaultWorkingDirectory": "DefaultWorkingDirectory", + "build.sourceVersion": "46da24f35850f455185b9188b4742359b537076f", + "build.buildId": 1, + "release.releaseId": 1, + "build.buildNumber": 1, + "release.releaseName": "Release-1", + "build.repository.provider": "TfsGit", + "build.repository.name": "MyFirstProject", + "system.TeamFoundationCollectionUri": "https://abc.visualstudio.com/", + "system.teamProject": "MyFirstProject", + "build.sourceVersionAuthor": "author", + "release.releaseUri": "vstfs:///ReleaseManagement/Release/1", + "agent.name": "agent" + } +}; + +import mockTask = require('vsts-task-lib/mock-task'); +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); +tr.registerMock('./msdeployutility.js', { + getMSDeployCmdArgs : msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath : function() { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + getAzureRMWebAppPublishProfile: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if(deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + getAzureRMWebAppConfigDetails: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [ ['Object'], ['Object'], ['Object'] ], + scmType: "None" + } + } + + return config; + }, + updateDeploymentStatus: function(publishingProfile, isDeploymentSuccess ) { + if(isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess); + requestDetails["requestBody"].author = 'author'; + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + getWebAppAppSettings : function (SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string){ + var appSettings = { + properties : { + MSDEPLOY_RENAME_LOCKED_FILES : '1' + } + }; + return appSettings; + }, + updateWebAppAppSettings : function (){ + return true; + }, + updateAzureRMWebAppConfigDetails: function() { + console.log("Successfully updated scmType to VSTSRM"); + } +}); + +tr.registerMock('webdeployment-common/utility.js', { + isInputPkgIsFolder: function() { + return false; + }, + fileExists: function() { + return true; + }, + canUseWebDeploy: function() { + return true; + }, + findfiles: function() { + return ['webDeployPkg'] + }, + generateTemporaryFolderForDeployment: function() { + return 'temp_web_package_random_path'; + }, + archiveFolderForDeployment: function() { + return { + "webDeployPkg": "DefaultWorkingDirectory\\temp_web_package.zip", + "tempPackagePath": "DefaultWorkingDirectory\\temp_web_package.zip" + }; + }, + isMSDeployPackage: function() { + return false; + } +}); + +tr.registerMock('path', { + win32: { + basename: function(filePath, extension) { + return path.win32.basename(filePath, extension); + } + }, + join: function() { + if(arguments[arguments.length -1] === 'ctt.exe') { + return 'DefaultWorkingDirectory/ctt/ctt.exe'; + } + var args = []; + for(var i=0; i < arguments.length; i += 1) { + args.push(arguments[i]); + } + return args.join('\\'); + }, + dirname: path.dirname +}); + +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/L0XdtTransformationFailMSBuildPackage.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0XdtTransformationFailMSBuildPackage.ts new file mode 100644 index 000000000000..6fecf9dff39c --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/L0XdtTransformationFailMSBuildPackage.ts @@ -0,0 +1,227 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); + +let taskPath = path.join(__dirname, '..', 'azurermwebappdeployment.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); +tr.setInput('ConnectedServiceName', 'AzureRMSpn'); +tr.setInput('WebAppName', 'mytestapp'); +tr.setInput('Package', 'webAppPkg.zip'); +tr.setInput('UseWebDeploy', 'true'); +tr.setInput('XmlTransformation', 'true'); + +process.env['TASK_TEST_TRACE'] = 1; +process.env["ENDPOINT_AUTH_AzureRMSpn"] = "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALID"] = "spId"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_SERVICEPRINCIPALKEY"] = "spKey"; +process.env["ENDPOINT_AUTH_PARAMETER_AzureRMSpn_TENANTID"] = "tenant"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME"] = "sName"; +process.env["ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID"] = "sId"; +process.env["AZURE_HTTP_USER_AGENT"] = "TFS_useragent"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = "DefaultWorkingDirectory"; +process.env["BUILD_SOURCEVERSION"] = "46da24f35850f455185b9188b4742359b537076f"; +process.env["BUILD_BUILDID"] = 1, +process.env["RELEASE_RELEASEID"] = 1; +process.env["BUILD_BUILDNUMBER"] = 1; +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["BUILD_REPOSITORY_PROVIDER"] = "TfsGit"; +process.env["BUILD_REPOSITORY_NAME"] = "MyFirstProject"; +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = "https://abc.visualstudio.com/"; +process.env["SYSTEM_TEAMPROJECT"] = "MyFirstProject"; +process.env["BUILD_SOURCEVERISONAUTHOR"] = "author"; +process.env["RELEASE_RELEASEURI"] = "vstfs:///ReleaseManagement/Release/1"; +process.env["AGENT_NAME"] = "author"; + +// provide answers for task mock +let a: ma.TaskLibAnswers = { + "which": { + "cmd": "cmd", + "DefaultWorkingDirectory/ctt/ctt.exe": "DefaultWorkingDirectory/ctt/ctt.exe" + }, + "stats": { + "webAppPkg.zip": { + "isFile": true + } + }, + "osType": { + "osType": "Windows" + }, + "checkPath": { + "cmd": true, + "webAppPkg.zip": true, + "webAppPkg": true, + "DefaultWorkingDirectory/ctt/ctt.exe": true + }, + "exec": { + "cmd /C DefaultWorkingDirectory\\msDeployCommand.bat": { + "code": 0, + "stdout": "Executed Successfully" + }, + "cmd /C DefaultWorkingDirectory\\msDeployParam.bat": { + "code": 0, + "stdout": "Executed Successfully" + }, + "DefaultWorkingDirectory/ctt/ctt.exe s:C:\\tempFolder\\web.config t:C:\\tempFolder\\web.Release.config d:C:\\tempFolder\\web.config pw": { + "code": 1, + "stderr": "ctt execution failed" + } + }, + "exist": { + "webAppPkg.zip": true, + "webAppPkg": true + }, + "findMatch": { + "webAppPkgPattern" : ["webAppPkg1", "webAppPkg2"], + "Invalid_webAppPkg" : [], + "webAppPkg.zip": ["webAppPkg.zip"], + "webAppPkg": ["webAppPkg"], + "**/*.config": ["C:\\tempFolder\\web.config"] + }, + "getVariable": { + "ENDPOINT_AUTH_AzureRMSpn": "{\"parameters\":{\"serviceprincipalid\":\"spId\",\"serviceprincipalkey\":\"spKey\",\"tenantid\":\"tenant\"},\"scheme\":\"ServicePrincipal\"}", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONNAME": "sName", + "ENDPOINT_DATA_AzureRMSpn_SUBSCRIPTIONID": "sId", + "AZURE_HTTP_USER_AGENT": "TFS_useragent", + "System.DefaultWorkingDirectory": "DefaultWorkingDirectory", + "build.sourceVersion": "46da24f35850f455185b9188b4742359b537076f", + "build.buildId": 1, + "release.releaseId": 1, + "build.buildNumber": 1, + "release.releaseName": "Release-1", + "build.repository.provider": "TfsGit", + "build.repository.name": "MyFirstProject", + "system.TeamFoundationCollectionUri": "https://abc.visualstudio.com/", + "system.teamProject": "MyFirstProject", + "build.sourceVersionAuthor": "author", + "release.releaseUri": "vstfs:///ReleaseManagement/Release/1", + "agent.name": "agent" + } +}; + +import mockTask = require('vsts-task-lib/mock-task'); +var kuduDeploymentLog = require('azurerest-common/kududeploymentstatusutility.js'); +var msDeployUtility = require('webdeployment-common/msdeployutility.js'); +tr.registerMock('./msdeployutility.js', { + getMSDeployCmdArgs : msDeployUtility.getMSDeployCmdArgs, + getMSDeployFullPath : function() { + var msDeployFullPath = "msdeploypath\\msdeploy.exe"; + return msDeployFullPath; + } +}); + +tr.registerMock('azurerest-common/azurerestutility.js', { + getAzureRMWebAppPublishProfile: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var mockPublishProfile = { + profileName: 'mytestapp - Web Deploy', + publishMethod: 'MSDeploy', + publishUrl: 'mytestappKuduUrl', + msdeploySite: 'mytestapp', + userName: '$mytestapp', + userPWD: 'mytestappPwd', + destinationAppUrl: 'mytestappUrl', + SQLServerDBConnectionString: '', + mySQLDBConnectionString: '', + hostingProviderForumLink: '', + controlPanelLink: '', + webSystem: 'WebSites' + }; + if(deployToSlotFlag) { + mockPublishProfile.profileName = 'mytestapp-' + slotName + ' - Web Deploy'; + mockPublishProfile.publishUrl = 'mytestappKuduUrl-' + slotName; + mockPublishProfile.msdeploySite = 'mytestapp__' + slotName; + mockPublishProfile.userName = '$mytestapp__' + slotName; + mockPublishProfile.userPWD = 'mytestappPwd'; + mockPublishProfile.destinationAppUrl = 'mytestappUrl-' + slotName; + } + return mockPublishProfile; + }, + getAzureRMWebAppConfigDetails: function(SPN, webAppName, resourceGroupName, deployToSlotFlag, slotName) { + var config = { + id: 'appid', + properties: { + virtualApplications: [ ['Object'], ['Object'], ['Object'] ], + scmType: "None" + } + } + + return config; + }, + updateDeploymentStatus: function(publishingProfile, isDeploymentSuccess ) { + if(isDeploymentSuccess) { + console.log('Updated history to kudu'); + } + else { + console.log('Failed to update history to kudu'); + } + var webAppPublishKuduUrl = publishingProfile.publishUrl; + var requestDetails = kuduDeploymentLog.getUpdateHistoryRequest(webAppPublishKuduUrl, isDeploymentSuccess); + requestDetails["requestBody"].author = 'author'; + console.log("kudu log requestBody is:" + JSON.stringify(requestDetails["requestBody"])); + }, + getResourceGroupName: function (SPN, webAppName) { + return "foobar"; + }, + getWebAppAppSettings : function (SPN, webAppName: string, resourceGroupName: string, deployToSlotFlag: boolean, slotName: string){ + var appSettings = { + properties : { + MSDEPLOY_RENAME_LOCKED_FILES : '1' + } + }; + return appSettings; + }, + updateWebAppAppSettings : function (){ + return true; + }, + updateAzureRMWebAppConfigDetails: function() { + console.log("Successfully updated scmType to VSTSRM"); + } +}); + +tr.registerMock('webdeployment-common/utility.js', { + isInputPkgIsFolder: function() { + return false; + }, + fileExists: function() { + return true; + }, + canUseWebDeploy: function() { + return true; + }, + findfiles: function() { + return ['webDeployPkg'] + }, + generateTemporaryFolderForDeployment: function() { + return 'temp_web_package_random_path'; + }, + archiveFolderForDeployment: function() { + return { + "webDeployPkg": "DefaultWorkingDirectory\\temp_web_package.zip", + "tempPackagePath": "DefaultWorkingDirectory\\temp_web_package.zip" + }; + }, + isMSDeployPackage: function() { + return false; + } +}); + +tr.registerMock('path', { + win32: { + basename: function(filePath, extension) { + return path.win32.basename(filePath, extension); + } + }, + join: function() { + if(arguments[arguments.length -1] === 'ctt.exe') { + return 'DefaultWorkingDirectory/ctt/ctt.exe'; + } + var args = []; + for(var i=0; i < arguments.length; i += 1) { + args.push(arguments[i]); + } + return args.join('\\'); + }, + dirname: path.dirname +}); + +tr.setAnswers(a); +tr.run(); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/WebAppAvailabilityFailureTest.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/WebAppAvailabilityFailureTest.ts new file mode 100644 index 000000000000..d723b6482a1c --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/WebAppAvailabilityFailureTest.ts @@ -0,0 +1,8 @@ +var nock = require('nock'); +var azureRestUtiltiy = require('azurerest-common/azurerestutility.js'); + +nock('http://testwebapp.azurewebsites.net') + .get("/") + .reply(299, {"statusCode":"299", "statusMessage": "Fail"}); + +azureRestUtiltiy.testAzureWebAppAvailability('http://testwebapp.azurewebsites.net',100); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/WebAppAvailabilitySuccessTest.ts b/Tasks/AzureRmWebAppDeploymentV3/Tests/WebAppAvailabilitySuccessTest.ts new file mode 100644 index 000000000000..6d56b67d8547 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/WebAppAvailabilitySuccessTest.ts @@ -0,0 +1,8 @@ +var nock = require('nock'); +var azureRestUtiltiy = require('azurerest-common/azurerestutility.js'); + +nock('http://testwebapp.azurewebsites.net/') + .get("/") + .reply(200, {}); + +azureRestUtiltiy.testAzureWebAppAvailability('http://testwebapp.azurewebsites.net',100); \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/package-lock.json b/Tasks/AzureRmWebAppDeploymentV3/Tests/package-lock.json new file mode 100644 index 000000000000..99823aef319a --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/package-lock.json @@ -0,0 +1,124 @@ +{ + "name": "vsts-tasks-azurermappservicedeployment", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "assertion-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", + "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", + "dev": true + }, + "chai": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", + "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=", + "dev": true, + "requires": { + "assertion-error": "1.0.2", + "deep-eql": "0.1.3", + "type-detect": "1.0.0" + } + }, + "debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "dev": true, + "requires": { + "type-detect": "0.1.1" + }, + "dependencies": { + "type-detect": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", + "dev": true + } + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nock": { + "version": "9.0.11", + "resolved": "https://registry.npmjs.org/nock/-/nock-9.0.11.tgz", + "integrity": "sha1-EPIC5MwnYQLWDibjGfl9aNoJvpw=", + "dev": true, + "requires": { + "chai": "3.5.0", + "debug": "2.6.8", + "deep-equal": "1.0.1", + "json-stringify-safe": "5.0.1", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "propagate": "0.4.0", + "qs": "6.4.0" + } + }, + "propagate": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-0.4.0.tgz", + "integrity": "sha1-8/zKCm/gZzanulcpZgaWF8EwtIE=", + "dev": true + }, + "qs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", + "dev": true + }, + "type-detect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz", + "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=", + "dev": true + } + } +} diff --git a/Tasks/AzureRmWebAppDeploymentV3/Tests/package.json b/Tasks/AzureRmWebAppDeploymentV3/Tests/package.json new file mode 100644 index 000000000000..6b71557c5fe4 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/Tests/package.json @@ -0,0 +1,22 @@ +{ + "name": "vsts-tasks-azurermappservicedeployment", + "version": "1.0.0", + "description": "VSTS Azure RM App Service Deployment", + "main": "azurermappservicedeployment.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/Microsoft/vsts-tasks.git" + }, + "author": "Microsoft Corporation", + "license": "MIT", + "bugs": { + "url": "https://github.com/Microsoft/vsts-tasks/issues" + }, + "homepage": "https://github.com/Microsoft/vsts-tasks#readme", + "devDependencies": { + "nock": "9.0.11" + } +} diff --git a/Tasks/AzureRmWebAppDeploymentV3/ThirdPartyNotices.txt b/Tasks/AzureRmWebAppDeploymentV3/ThirdPartyNotices.txt new file mode 100644 index 000000000000..4540dc791933 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/ThirdPartyNotices.txt @@ -0,0 +1,1665 @@ + +THIRD-PARTY SOFTWARE NOTICES AND INFORMATION +Do Not Translate or Localize + +Azure App Service Deploy incorporates third party material from the projects listed below. The original copyright notice and the license under which Microsoft received such third party material are set forth below. Microsoft reserves all other rights not expressly granted, whether by implication, estoppel or otherwise. + +1. abbrev (https://github.com/isaacs/abbrev-js) +2. Archiver (https://github.com/archiverjs/node-archiver) +3. archiver-utils (https://github.com/archiverjs/archiver-utils) +4. async (https://github.com/caolan/async) +5. balanced-match (https://github.com/juliangruber/balanced-match) +6. binary (https://github.com/substack/node-binary) +7. bl (Buffer List) (https://github.com/rvagg/bl) +8. brace-expansion (https://github.com/juliangruber/brace-expansion) +9. buffer-crc32 (https://github.com/brianloveswords/buffer-crc32) +10. buffers (DefinitelyTyped) (https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/buffers) +11. buffer-shims (https://github.com/calvinmetcalf/buffer-shims) +12. chainsaw (https://github.com/substack/node-chainsaw) +13. compress-commons (https://github.com/archiverjs/node-compress-commons) +14. concat-map (https://github.com/substack/node-concat-map) +15. core-util-is (https://github.com/isaacs/core-util-is) +16. Crc32-stream (https://github.com/archiverjs/node-crc32-stream) +17. Ctt (https://ctt.codeplex.com) +18. decompress-zip (https://github.com/bower/decompress-zip) +19. end-of-stream (https://github.com/mafintosh/end-of-stream) +20. fs.realpath (https://github.com/isaacs/fs.realpath) +21. Glob (https://github.com/isaacs/node-glob) +22. graceful-fs (https://github.com/isaacs/node-graceful-fs) +23. inflight (https://github.com/npm/inflight) +24. inherits (https://github.com/isaacs/inherits) +25. isarray (https://github.com/juliangruber/isarray/) +26. lazystream (https://github.com/jpommerening/node-lazystream) +27. lodash (https://lodash.com/) + Includes:File(s) copyright John Resig (http://ejohn.org/blog/javascript-micro-templating/) + Includes:File(s) copyright Laura Doktorova (https://github.com/olado/doT) +28. Ltx (https://github.com/node-xmpp/ltx) +29. minimatch (https://github.com/isaacs/minimatch) +30. mkpath (https://github.com/jrajav/mkpath) +31. Mockery (https://github.com/mfncooper/mockery) +32. Node.js (https://nodejs.org/) +33. node-tar (https://github.com/npm/node-tar/) +34. node-uuid (https://github.com/broofa/node-uuid/) +35. nopt (https://github.com/npm/nopt) +36. normalize-path (https://github.com/jonschlinkert/normalize-path) +37. once (https://github.com/isaacs/once) +38. path-is-absolute (https://github.com/sindresorhus/path-is-absolute) +39. process-nextick-args (https://github.com/calvinmetcalf/process-nextick-args) +40. Q (https://github.com/kriskowal/q) +41. readable-stream (https://github.com/isaacs/readable-stream) +42. sax js (https://github.com/isaacs/sax-js) +43. semver (https://github.com/npm/node-semver/) +44. ShellJS (https://github.com/shelljs/shelljs) +45. string_decoder (https://github.com/rvagg/string_decoder) +46. tar-stream (https://github.com/mafintosh/tar-stream) +47. touch (https://github.com/isaacs/node-touch) +48. traverse (https://github.com/substack/js-traverse) +49. tunnel (https://github.com/koichik/node-tunnel) +50. underscore.js (http://underscorejs.org/; https://github.com/jashkenas/underscore) +51. util-deprecate (https://github.com/TooTallNate/util-deprecate) +52. vso-node-api (https://github.com/Microsoft/vsts-node-api) +53. VSTS-task-lib (https://github.com/Microsoft/vsts-task-lib) +54. winreg (https://github.com/fresc81/node-winreg) +55. wrappy (https://github.com/npm/wrappy) +56. Xml2JS (https://github.com/Leonidas-from-XIV/node-xml2js) +57. Xmlbuilder (https://github.com/oozcitak/xmlbuilder-js) +58. xtend (https://github.com/Raynos/xtend) +59. zip-stream (https://github.com/archiverjs/node-zip-stream) +60. uuid (https://github.com/kelektiv/node-uuid) + + +%% abbrev NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED AS IS AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF abbrev NOTICES, INFORMATION, AND LICENSE + +%% Archiver NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2012-2014 Chris Talkington, contributors. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF Archiver NOTICES, INFORMATION, AND LICENSE + +%% archiver-utils NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2015 Chris Talkington. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF archiver-utils NOTICES, INFORMATION, AND LICENSE + +%% async NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= + +Copyright (c) 2010-2016 Caolan McMahon + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the Software), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +========================================= +END OF async NOTICES, INFORMATION, AND LICENSE + +%% balanced-match NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +(MIT) + +Copyright (c) 2013 Julian Gruber + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +========================================= +END OF balanced-match NOTICES, INFORMATION, AND LICENSE + +%% binary NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2012 James Halliday + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF binary NOTICES, INFORMATION, AND LICENSE + +%% bl (Buffer List) NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The MIT License (MIT) +Copyright (c) 2014 bl contributors + +bl contributors listed at https://github.com/rvagg/bl#contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF bl (Buffer List) NOTICES, INFORMATION, AND LICENSE + +%% brace-expansion NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +(MIT) + +Copyright (c) 2013 Julian Gruber + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +========================================= +END OF brace-expansion NOTICES, INFORMATION, AND LICENSE + +%% buffer-crc32 NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The MIT License + +Copyright (c) 2013 Brian J. Brennan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF buffer-crc32 NOTICES, INFORMATION, AND LICENSE + +%% buffers (DefinitelyTyped) NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +This project is licensed under the MIT license. + +Copyrights are respective of each contributor listed at the beginning of each definition file. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +========================================= +END OF buffers (DefinitelyTyped) NOTICES, INFORMATION, AND LICENSE + +%% buffer-shims NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +# Copyright (c) 2016 Calvin Metcalf + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +**THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE.** + +========================================= +END OF buffer-shims NOTICES, INFORMATION, AND LICENSE + +%% chainsaw NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright 2010 James Halliday (mail@substack.net) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the Software), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +========================================= +END OF chainsaw NOTICES, INFORMATION, AND LICENSE + +%% compress-commons NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2014 Chris Talkington, contributors. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF compress-commons NOTICES, INFORMATION, AND LICENSE + +%% concat-map NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) James Halliday/substack + +This software is released under the MIT license: + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF concat-map NOTICES, INFORMATION, AND LICENSE + +%% core-util-is NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright Node.js contributors. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the Software), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. +========================================= +END OF core-util-is NOTICES, INFORMATION, AND LICENSE + +%% Crc32-stream NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2014 Chris Talkington, contributors. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF Crc32-stream NOTICES, INFORMATION, AND LICENSE + +%% Ctt NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Microsoft Public License (Ms-PL) + +This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. + +1. Definitions + +The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. + +A "contribution" is the original software, or any additions or changes to the software. + +A "contributor" is any person that distributes its contribution under this license. + +"Licensed patents" are a contributor's patent claims that read directly on its contribution. + +2. Grant of Rights + +(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. + +(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. + +3. Conditions and Limitations + +(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. + +(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. + +(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. + +(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. + +(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. +========================================= +END OF Ctt NOTICES, INFORMATION, AND LICENSE + +%% decompress-zip NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) Bower Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the Software), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +========================================= +END OF decompress-zip NOTICES, INFORMATION, AND LICENSE + +%% end-of-stream NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) 2014 Mathias Buus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the Software), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +========================================= +END OF end-of-stream NOTICES, INFORMATION, AND LICENSE + +%% fs.realpath NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +---- + +This library bundles a version of the `fs.realpath` and `fs.realpathSync` +methods from Node.js v0.10 under the terms of the Node.js MIT license, as follows: + + Copyright Joyent, Inc. and other Node contributors. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + +========================================= +END OF fs.realpath NOTICES, INFORMATION, AND LICENSE + +%% Glob NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF Glob NOTICES, INFORMATION, AND LICENSE + +%% graceful-fs NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED AS IS AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF graceful-fs NOTICES, INFORMATION, AND LICENSE + +%% inflight NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF inflight NOTICES, INFORMATION, AND LICENSE + +%% inherits NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF inherits NOTICES, INFORMATION, AND LICENSE + +%% isarray NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +(MIT) + +Copyright (c) 2013 Julian Gruber + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF isarray NOTICES, INFORMATION, AND LICENSE + +%% lazystream NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2013 J. Pommerening, contributors. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +========================================= +END OF lazystream NOTICES, INFORMATION, AND LICENSE + +%% lodash NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. + +========================================= +// Based on John Resig's `tmpl` implementation (http://ejohn.org/blog/javascript-micro-templating/) + +Copyright 2008 John Resig + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +========================================= +// Based on Laura Doktorova's doT.js (https://github.com/olado/doT). + +Copyright (c) 2011 Laura Doktorova + +Software includes portions from jQote2 Copyright (c) 2010 aefxx, +http://aefxx.com/ licensed under the MIT license. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF lodash NOTICES, INFORMATION, AND LICENSE + +%% Ltx NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2010 Stephan Maka + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +========================================= +END OF Ltx NOTICES, INFORMATION, AND LICENSE + +%% minimatch NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF minimatch NOTICES, INFORMATION, AND LICENSE + +%% mkpath NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (C) 2012 Jonathan Rajavuori + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF mkpath NOTICES, INFORMATION, AND LICENSE + +%% Mockery NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyrights for code authored by Yahoo! Inc. is licensed under the following +terms: + + MIT License + + Copyright (c) 2011 Yahoo! Inc. All Rights Reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +========================================= +END OF Mockery NOTICES, INFORMATION, AND LICENSE + +%% Node.js NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Node.js is licensed for use as follows: + +""" +Copyright Node.js contributors. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. +""" + +This license applies to parts of Node.js originating from the +https://github.com/joyent/node repository: + +""" +Copyright Joyent, Inc. and other Node contributors. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. +""" + +The Node.js license applies to all parts of Node.js that are not externally +maintained libraries. +========================================= +END OF Node.js NOTICES, INFORMATION, AND LICENSE + +%% node-tar NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License +Copyright (c) Isaac Z. Schlueter and Contributors +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF node-tar NOTICES, INFORMATION, AND LICENSE + +%% node-uuid NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) 2010-2012 Robert Kieffer + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF node-uuid NOTICES, INFORMATION, AND LICENSE + +%% nopt NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED AS IS AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF nopt NOTICES, INFORMATION, AND LICENSE + +%% normalize-path NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) 2014-2015, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +========================================= +END OF normalize-path NOTICES, INFORMATION, AND LICENSE + +%% once NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF once NOTICES, INFORMATION, AND LICENSE + +%% path-is-absolute NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +path-is-absolute + +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the Software), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +node.js: + +Copyright Joyent, Inc. and other Node contributors. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +Software), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF path-is-absolute NOTICES, INFORMATION, AND LICENSE + +%% process-nextick-args NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2015 Calvin Metcalf + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF process-nextick-args NOTICES, INFORMATION, AND LICENSE + +%% Q NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright 2009�2014 Kristopher Michael Kowal. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. + +The file q.js is prefaced by the following additional third-party subcomponent information: + +/*! + * + * Copyright 2009-2012 Kris Kowal under the terms of the MIT + * license found at http://github.com/kriskowal/q/raw/master/LICENSE + * + * With parts by Tyler Close + * Copyright 2007-2009 Tyler Close under the terms of the MIT X license found + * at http://www.opensource.org/licenses/mit-license.html + * Forked at ref_send.js version: 2009-05-11 + * + * With parts by Mark Miller + * Copyright (C) 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +========================================= +END OF Q NOTICES, INFORMATION, AND LICENSE + +%% readable-stream NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright Joyent, Inc. and other Node contributors. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the Software), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. +========================================= +END OF readable-stream NOTICES, INFORMATION, AND LICENSE + +%% sax js NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +==== + +`String.fromCodePoint` by Mathias Bynens used according to terms of MIT +License, as follows: + + Copyright Mathias Bynens + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF sax js NOTICES, INFORMATION, AND LICENSE + +%% semver NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF semver NOTICES, INFORMATION, AND LICENSE + +%% ShellJS NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2012, Artur Adib +All rights reserved. + +You may use this project under the terms of the New BSD license as follows: + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Artur Adib nor the + names of the contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL ARTUR ADIB BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +========================================= +END OF ShellJS NOTICES, INFORMATION, AND LICENSE + +%% string_decoder NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= + +Copyright Joyent, Inc. and other Node contributors. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +Software), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF string_decoder NOTICES, INFORMATION, AND LICENSE + +%% tar-stream NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) 2014 Mathias Buus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the Software), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +========================================= +END OF tar-stream NOTICES, INFORMATION, AND LICENSE + +%% touch NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED AS IS AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF touch NOTICES, INFORMATION, AND LICENSE + +%% traverse NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright 2010 James Halliday (mail@substack.net) + +This project is free software released under the MIT/X11 license: +http://www.opensource.org/licenses/mit-license.php + +Copyright 2010 James Halliday (mail@substack.net) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the Software), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +========================================= +END OF traverse NOTICES, INFORMATION, AND LICENSE + +%% tunnel NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) 2012 Koichi Kobayashi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +========================================= +END OF tunnel NOTICES, INFORMATION, AND LICENSE + +%% underscore.js NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2009-2017 Jeremy Ashkenas, DocumentCloud and Investigative +Reporters & Editors + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +========================================= +END OF underscore.js NOTICES, INFORMATION, AND LICENSE + +%% util-deprecate NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +(The MIT License) + +Copyright (c) 2014 Nathan Rajlich + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the Software), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF util-deprecate NOTICES, INFORMATION, AND LICENSE + +%% vso-node-api NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) Microsoft Corporation + +All rights reserved. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF vso-node-api NOTICES, INFORMATION, AND LICENSE + +%% VSTS-task-lib NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) Microsoft Corporation. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +========================================= +END OF VSTS-task-lib NOTICES, INFORMATION, AND LICENSE + +%% winreg NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +This project is released under BSD 2-Clause License. + +Copyright (c) 2016, Paul Bottin All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +========================================= +END OF winreg NOTICES, INFORMATION, AND LICENSE + +%% wrappy NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +========================================= +END OF wrappy NOTICES, INFORMATION, AND LICENSE + +%% Xml2JS NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright 2010, 2011, 2012, 2013. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. +========================================= +END OF Xml2JS NOTICES, INFORMATION, AND LICENSE + +%% Xmlbuilder NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +The MIT License (MIT) + +Copyright (c) 2013 Ozgur Ozcitak + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +========================================= +END OF Xmlbuilder NOTICES, INFORMATION, AND LICENSE + +%% xtend NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2012-2014 Raynos. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the Software), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +========================================= +END OF xtend NOTICES, INFORMATION, AND LICENSE + +%% zip-stream NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2014 Chris Talkington, contributors. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF zip-stream NOTICES, INFORMATION, AND LICENSE + +%% uuid NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= +Copyright (c) 2010-2016 Robert Kieffer and other contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +Includes Chris Veness' SHA1 + +Copyright (c) 2014 Chris Veness + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +========================================= +END OF uuid NOTICES, INFORMATION, AND LICENSE diff --git a/Tasks/AzureRmWebAppDeploymentV3/azurermwebappdeployment.ts b/Tasks/AzureRmWebAppDeploymentV3/azurermwebappdeployment.ts new file mode 100644 index 000000000000..77f1f78eeeb6 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/azurermwebappdeployment.ts @@ -0,0 +1,147 @@ +import tl = require('vsts-task-lib/task'); +import path = require('path'); +import fs = require('fs'); +import { AzureRMEndpoint } from 'azure-arm-rest/azure-arm-endpoint'; +import { AzureEndpoint } from 'azure-arm-rest/azureModels'; +import { AzureResourceFilterUtility } from './operations/AzureResourceFilterUtility'; +import { KuduServiceUtility } from './operations/KuduServiceUtility'; +import { AzureAppService } from 'azure-arm-rest/azure-arm-app-service'; +import { Kudu } from 'azure-arm-rest/azure-arm-app-service-kudu'; +import { AzureAppServiceUtility } from './operations/AzureAppServiceUtility'; +import { ContainerBasedDeploymentUtility } from './operations/ContainerBasedDeploymentUtility'; +import { TaskParameters, TaskParametersUtility } from './operations/TaskParameters'; +import { FileTransformsUtility } from './operations/FileTransformsUtility'; +import * as ParameterParser from './parameterparser' +import { addReleaseAnnotation } from './operations/ReleaseAnnotationUtility'; +import { DeployWar } from './operations/WarDeploymentUtilities'; + +var packageUtility = require('webdeployment-common/packageUtility.js'); + +var zipUtility = require('webdeployment-common/ziputility.js'); +var deployUtility = require('webdeployment-common/utility.js'); +var msDeploy = require('webdeployment-common/deployusingmsdeploy.js'); + +async function main() { + let zipDeploymentID: string; + let isDeploymentSuccess: boolean = true; + let kuduServiceUtility: KuduServiceUtility; + + try { + tl.setResourcePath(path.join( __dirname, 'task.json')); + var taskParams: TaskParameters = TaskParametersUtility.getParameters(); + var azureEndpoint: AzureEndpoint = await new AzureRMEndpoint(taskParams.connectedServiceName).getEndpoint(); + var virtualApplicationPath: string; + console.log(tl.loc('GotconnectiondetailsforazureRMWebApp0', taskParams.WebAppName)); + if(!taskParams.DeployToSlotFlag) { + taskParams.ResourceGroupName = await AzureResourceFilterUtility.getResourceGroupName(azureEndpoint, taskParams.WebAppName); + } + + tl.debug(`Resource Group: ${taskParams.ResourceGroupName}`); + var appService: AzureAppService = new AzureAppService(azureEndpoint, taskParams.ResourceGroupName, taskParams.WebAppName, taskParams.SlotName, taskParams.WebAppKind); + let appServiceUtility: AzureAppServiceUtility = new AzureAppServiceUtility(appService); + + await appServiceUtility.pingApplication(); + let kuduService: Kudu = await appServiceUtility.getKuduService(); + kuduServiceUtility = new KuduServiceUtility(kuduService); + if(taskParams.WebAppUri) { + tl.setVariable(taskParams.WebAppUri, await appServiceUtility.getApplicationURL(!taskParams.isLinuxApp ? taskParams.VirtualApplication : null)); + } + + 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'); + } + } + } + else { + var webPackage = packageUtility.PackageUtility.getPackagePath(taskParams.Package); + var isFolderBasedDeployment = deployUtility.isInputPkgIsFolder(webPackage); + var physicalPath: string = '/site/wwwroot'; + if(taskParams.VirtualApplication) { + physicalPath = await appServiceUtility.getPhysicalPath(taskParams.VirtualApplication); + await kuduServiceUtility.createPathIfRequired(physicalPath); + virtualApplicationPath = physicalPath; + } + + webPackage = await FileTransformsUtility.applyTransformations(webPackage, taskParams); + + if(deployUtility.canUseWebDeploy(taskParams.UseWebDeploy)) { + tl.debug("Performing the deployment of webapp."); + if(!tl.osType().match(/^Win/)){ + throw Error(tl.loc("PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent")); + } + + if(taskParams.RenameFilesFlag) { + await appServiceUtility.enableRenameLockedFiles(); + } + + var msDeployPublishingProfile = await appServiceUtility.getWebDeployPublishingProfile(); + if (webPackage.toString().toLowerCase().endsWith('.war')) { + await DeployWar(webPackage, taskParams, msDeployPublishingProfile, kuduService, appServiceUtility); + } + else { + await msDeploy.DeployUsingMSDeploy(webPackage, taskParams.WebAppName, msDeployPublishingProfile, taskParams.RemoveAdditionalFilesFlag, + taskParams.ExcludeFilesFromAppDataFlag, taskParams.TakeAppOfflineFlag, taskParams.VirtualApplication, taskParams.SetParametersFile, + taskParams.AdditionalArguments, isFolderBasedDeployment, taskParams.UseWebDeploy); + } + } + else { + tl.debug("Initiated deployment via kudu service for webapp package : "); + await kuduServiceUtility.deployWebPackage(webPackage, physicalPath, taskParams.VirtualApplication, taskParams.TakeAppOfflineFlag); + } + } + + if(!taskParams.isContainerWebApp) { + if(taskParams.AppSettings) { + var customApplicationSettings = ParameterParser.parse(taskParams.AppSettings); + await appServiceUtility.updateAndMonitorAppSettings(customApplicationSettings); + } + + if(taskParams.ConfigurationSettings) { + var customApplicationSettings = ParameterParser.parse(taskParams.ConfigurationSettings); + await appServiceUtility.updateConfigurationSettings(customApplicationSettings); + } + } + else { + tl.debug('App Settings and config settings are already updated during container based deployment.') + } + + if(taskParams.ScriptType) { + await kuduServiceUtility.runPostDeploymentScript(taskParams, virtualApplicationPath); + } + + await appServiceUtility.updateScmTypeAndConfigurationDetails(); + } + catch(error) { + isDeploymentSuccess = false; + tl.setResult(tl.TaskResult.Failed, error); + } + finally { + if(kuduServiceUtility) { + await addReleaseAnnotation(azureEndpoint, appService, isDeploymentSuccess); + let activeDeploymentID: string = await kuduServiceUtility.updateDeploymentStatus(isDeploymentSuccess, null, {'type': 'Deployment', slotName: appService.getSlot()}); + if(zipDeploymentID && activeDeploymentID && isDeploymentSuccess) { + await kuduServiceUtility.postZipDeployOperation(zipDeploymentID, activeDeploymentID); + } + } + else { + tl.debug('Cannot update deployment status as Kudu is not initialized'); + } + } +} + +main(); diff --git a/Tasks/AzureRmWebAppDeploymentV3/icon.png b/Tasks/AzureRmWebAppDeploymentV3/icon.png new file mode 100644 index 000000000000..9ee7be815737 Binary files /dev/null and b/Tasks/AzureRmWebAppDeploymentV3/icon.png differ diff --git a/Tasks/AzureRmWebAppDeploymentV3/icon.svg b/Tasks/AzureRmWebAppDeploymentV3/icon.svg new file mode 100644 index 000000000000..a06728a6e48e --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/icon.svg @@ -0,0 +1,74 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/make.json b/Tasks/AzureRmWebAppDeploymentV3/make.json new file mode 100644 index 000000000000..e64b05884e39 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/make.json @@ -0,0 +1,45 @@ +{ + "common": [ + { + "module": "../Common/azure-arm-rest", + "type": "node", + "dest": "./", + "compile" : true + }, + { + "module": "../Common/webdeployment-common", + "type": "node", + "dest": "./", + "compile" : true + } + ], + "externals": { + "archivePackages": [ + { + "archiveName": "MSDeploy.zip", + "url": "https://vstsagenttools.blob.core.windows.net/tools/MSDeploy/3.6/MSDeploy.zip", + "dest": "./" + }, + { + "archiveName": "ctt.zip", + "url": "https://vstsagenttools.blob.core.windows.net/tools/ctt/1.6/ctt.zip", + "dest": "./" + } + ] + }, + "cp": [ + { + "source": "postDeploymentScript", + "options": "-R" + } + ], + "rm": [ + { + "items": [ + "node_modules/azure-arm-rest/node_modules/vsts-task-lib", + "node_modules/webdeployment-common/node_modules/vsts-task-lib" + ], + "options": "-Rf" + } + ] +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/operations/AzureAppServiceUtility.ts b/Tasks/AzureRmWebAppDeploymentV3/operations/AzureAppServiceUtility.ts new file mode 100644 index 000000000000..528b2afe3c91 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/operations/AzureAppServiceUtility.ts @@ -0,0 +1,233 @@ +import tl = require('vsts-task-lib/task'); +import { AzureAppService } from 'azure-arm-rest/azure-arm-app-service'; +import webClient = require('azure-arm-rest/webClient'); +var parseString = require('xml2js').parseString; +import Q = require('q'); +import { Kudu } from 'azure-arm-rest/azure-arm-app-service-kudu'; +import { AzureAppServiceConfigurationDetails } from 'azure-arm-rest/azureModels'; + +export class AzureAppServiceUtility { + private _appService: AzureAppService; + constructor(appService: AzureAppService) { + this._appService = appService; + } + + public async updateScmTypeAndConfigurationDetails() : Promise{ + try { + var configDetails = await this._appService.getConfiguration(); + var scmType: string = configDetails.properties.scmType; + if (scmType && scmType.toLowerCase() === "none") { + configDetails.properties.scmType = 'VSTSRM'; + tl.debug('updating SCM Type to VSTS-RM'); + await this._appService.updateConfiguration(configDetails); + tl.debug('updated SCM Type to VSTS-RM'); + tl.debug('Updating metadata with latest release details'); + await this._appService.patchMetadata(this._getNewMetadata()); + tl.debug('Updated metadata with latest release details'); + console.log(tl.loc("SuccessfullyUpdatedAzureRMWebAppConfigDetails")); + } + else { + tl.debug(`Skipped updating the SCM value. Value: ${scmType}`); + } + } + catch(error) { + tl.warning(tl.loc("FailedToUpdateAzureRMWebAppConfigDetails", error)); + } + } + + public async getWebDeployPublishingProfile(): Promise { + var publishingProfile = await this._appService.getPublishingProfileWithSecrets(); + var defer = Q.defer(); + parseString(publishingProfile, (error, result) => { + if(!!error) { + defer.reject(error); + } + var publishProfile = result && result.publishData && result.publishData.publishProfile ? result.publishData.publishProfile : null; + if(publishProfile) { + for (var index in publishProfile) { + if (publishProfile[index].$ && publishProfile[index].$.publishMethod === "MSDeploy") { + defer.resolve(result.publishData.publishProfile[index].$); + } + } + } + + defer.reject(tl.loc('ErrorNoSuchDeployingMethodExists')); + }); + + return defer.promise; + } + + public async getApplicationURL(virtualApplication ?: string): Promise { + let webDeployProfile: any = await this.getWebDeployPublishingProfile(); + return await webDeployProfile.destinationAppUrl + ( virtualApplication ? "/" + virtualApplication : ""); + } + + public async pingApplication(): Promise { + try { + var applicationUrl: string = await this.getApplicationURL(); + + if(!applicationUrl) { + tl.debug('Application Url not found.'); + return; + } + var webRequest = new webClient.WebRequest(); + webRequest.method = 'GET'; + webRequest.uri = applicationUrl; + var response = await webClient.sendRequest(webRequest); + tl.debug(`App Service status Code: '${response.statusCode}'. Status Message: '${response.statusMessage}'`); + } + catch(error) { + tl.debug(`Unable to ping App Service. Error: ${error}`); + } + } + + public async getKuduService(): Promise { + var publishingCredentials = await this._appService.getPublishingCredentials(); + if(publishingCredentials.properties["scmUri"]) { + tl.setVariable(`AZURE_APP_SERVICE_KUDU_${this._appService.getSlot()}_PASSWORD`, publishingCredentials.properties["publishingPassword"], true); + return new Kudu(publishingCredentials.properties["scmUri"], publishingCredentials.properties["publishingUserName"], publishingCredentials.properties["publishingPassword"]); + } + + throw Error(tl.loc('KuduSCMDetailsAreEmpty')); + } + + public async getPhysicalPath(virtualApplication: string): Promise { + + if(!virtualApplication) { + return '/site/wwwroot'; + } + + virtualApplication = (virtualApplication.startsWith("/")) ? virtualApplication.substr(1) : virtualApplication; + + var physicalToVirtualPathMap = await this._getPhysicalToVirtualPathMap(virtualApplication); + + if(!physicalToVirtualPathMap) { + throw Error(tl.loc("VirtualApplicationDoesNotExist", virtualApplication)); + } + + tl.debug(`Virtual Application Map: Physical path: '${physicalToVirtualPathMap.physicalPath}'. Virtual path: '${physicalToVirtualPathMap.virtualPath}'.`); + return physicalToVirtualPathMap.physicalPath; + } + + public async updateConfigurationSettings(properties: any) : Promise { + for(var property in properties) { + if(!!properties[property] && properties[property].value !== undefined) { + properties[property] = properties[property].value; + } + } + + console.log(tl.loc('UpdatingAppServiceConfigurationSettings', JSON.stringify(properties))); + await this._appService.patchConfiguration({'properties': properties}); + console.log(tl.loc('UpdatedAppServiceConfigurationSettings')); + } + + public async updateAndMonitorAppSettings(properties: any): Promise { + for(var property in properties) { + if(!!properties[property] && properties[property].value !== undefined) { + properties[property] = properties[property].value; + } + } + + console.log(tl.loc('UpdatingAppServiceApplicationSettings', JSON.stringify(properties))); + await this._appService.patchApplicationSettings(properties); + var kuduService = await this.getKuduService(); + var noOftimesToIterate: number = 6; + tl.debug('retrieving values from Kudu service to check if new values are updated'); + while(noOftimesToIterate > 0) { + var kuduServiceAppSettings = await kuduService.getAppSettings(); + var propertiesChanged: boolean = true; + for(var property in properties) { + if(kuduServiceAppSettings[property] != properties[property]) { + tl.debug('New properties are not updated in Kudu service :('); + propertiesChanged = false; + break; + } + } + + if(propertiesChanged) { + tl.debug('New properties are updated in Kudu service.'); + console.log(tl.loc('UpdatedAppServiceApplicationSettings')); + return; + } + + noOftimesToIterate -= 1; + await webClient.sleepFor(10); + } + + tl.debug('Timing out from app settings check'); + } + + public async enableRenameLockedFiles(): Promise { + try { + var webAppSettings = await this._appService.getApplicationSettings(); + if(webAppSettings && webAppSettings.properties) { + if(webAppSettings.properties.MSDEPLOY_RENAME_LOCKED_FILES !== '1') { + tl.debug(`Rename locked files value found to be ${webAppSettings.properties.MSDEPLOY_RENAME_LOCKED_FILES}. Updating the value to 1`); + await this.updateAndMonitorAppSettings({ 'MSDEPLOY_RENAME_LOCKED_FILES' : '1' }); + console.log(tl.loc('RenameLockedFilesEnabled')); + } + else { + tl.debug('Rename locked files is already enabled in App Service'); + } + } + } + catch(error) { + throw new Error(tl.loc('FailedToEnableRenameLockedFiles', error)); + } + } + + public async updateStartupCommandAndRuntimeStack(runtimeStack: string, startupCommand?: string): Promise { + var configDetails = await this._appService.getConfiguration(); + startupCommand = (!!startupCommand) ? startupCommand : ""; + var linuxFxVersion: string = configDetails.properties.linuxFxVersion; + var appCommandLine: string = configDetails.properties.appCommandLine; + + if (appCommandLine != startupCommand || runtimeStack != linuxFxVersion) { + await this.updateConfigurationSettings({linuxFxVersion: runtimeStack, appCommandLine: startupCommand}); + } + else { + tl.debug(`Skipped updating the values. linuxFxVersion: ${linuxFxVersion} : appCommandLine: ${appCommandLine}`) + } + } + + private async _getPhysicalToVirtualPathMap(virtualApplication: string): Promise { + // construct URL depending on virtualApplication or root of webapplication + var physicalPath = null; + var virtualPath = "/" + virtualApplication; + var appConfigSettings = await this._appService.getConfiguration(); + var virtualApplicationMappings = appConfigSettings.properties && appConfigSettings.properties.virtualApplications; + + if(virtualApplicationMappings) { + for( var mapping of virtualApplicationMappings ) { + if(mapping.virtualPath.toLowerCase() == virtualPath.toLowerCase()) { + physicalPath = mapping.physicalPath; + break; + } + } + } + + return physicalPath ? { + 'virtualPath': virtualPath, + 'physicalPath': physicalPath + }: null; + } + + private _getNewMetadata(): any { + var collectionUri = tl.getVariable("system.teamfoundationCollectionUri"); + var projectId = tl.getVariable("system.teamprojectId"); + var buildDefintionId = tl.getVariable("build.definitionId") + var releaseDefinitionId = tl.getVariable("release.definitionId"); + + let newProperties = { + VSTSRM_BuildDefinitionId: buildDefintionId, + VSTSRM_ReleaseDefinitionId: releaseDefinitionId, + VSTSRM_ProjectId: projectId, + VSTSRM_AccountId: tl.getVariable("system.collectionId"), + VSTSRM_BuildDefinitionWebAccessUrl: collectionUri + projectId + "/_build?_a=simple-process&definitionId=" + buildDefintionId, + VSTSRM_ConfiguredCDEndPoint: collectionUri + projectId + "/_apps/hub/ms.vss-releaseManagement-web.hub-explorer?definitionId=" + releaseDefinitionId + } + + return newProperties; + } + +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/operations/AzureResourceFilterUtility.ts b/Tasks/AzureRmWebAppDeploymentV3/operations/AzureResourceFilterUtility.ts new file mode 100644 index 000000000000..4c5cd68cc3e0 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/operations/AzureResourceFilterUtility.ts @@ -0,0 +1,22 @@ +import tl = require('vsts-task-lib/task'); +import { AzureEndpoint } from 'azure-arm-rest/azureModels'; +import { Resources } from 'azure-arm-rest/azure-arm-resource'; + +export class AzureResourceFilterUtility { + public static async getResourceGroupName(endpoint: AzureEndpoint, resourceName: string): Promise { + var azureResources: Resources = new Resources(endpoint); + var filteredResources: Array = await azureResources.getResources('Microsoft.Web/Sites', resourceName); + let resourceGroupName: string; + if(!filteredResources || filteredResources.length == 0) { + throw new Error(tl.loc('ResourceDoesntExist', resourceName)); + } + else if(filteredResources.length == 1) { + resourceGroupName = filteredResources[0].id.split("/")[4]; + } + else { + throw new Error(tl.loc('MultipleResourceGroupFoundForAppService', resourceName)); + } + + return resourceGroupName; + } +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/operations/ContainerBasedDeploymentUtility.ts b/Tasks/AzureRmWebAppDeploymentV3/operations/ContainerBasedDeploymentUtility.ts new file mode 100644 index 000000000000..dedb4f9b9ef0 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/operations/ContainerBasedDeploymentUtility.ts @@ -0,0 +1,216 @@ +import tl = require('vsts-task-lib/task'); +import url = require('url'); +import util = require('util'); +import { AzureAppService } from 'azure-arm-rest/azure-arm-app-service'; +import { TaskParameters } from './TaskParameters'; +import { parse } from './ParameterParserUtility'; +import { AzureAppServiceUtility } from './AzureAppServiceUtility'; + +enum registryTypes { + "AzureContainerRegistry", + "Registry", // TODO: Rename it to DockerHub while supporting all the registry types. Also add all these registry types in Task.json in ImageSource pick list. + "PrivateRegistry" +} + +export class ContainerBasedDeploymentUtility { + private _appService: AzureAppService; + private _appServiceUtility: AzureAppServiceUtility; + + constructor(appService: AzureAppService) { + this._appService = appService; + this._appServiceUtility = new AzureAppServiceUtility(appService); + } + + public async deployWebAppImage(taskParameters: TaskParameters): Promise { + var imageName = this._getImageName(); + tl.debug("Deploying an image " + imageName + " to the webapp " + this._appService.getName()); + + tl.debug("Updating the webapp configuration."); + await this._updateConfigurationDetails(taskParameters, imageName); + + tl.debug('Updating web app settings'); + await this._updateApplicationSettings(taskParameters, imageName); + } + + private async _updateApplicationSettings(taskParameters: TaskParameters, imageName: string): Promise { + var appSettingsParameters = taskParameters.AppSettings; + appSettingsParameters = appSettingsParameters ? appSettingsParameters.trim() : ""; + appSettingsParameters = await this._getContainerRegistrySettings(imageName, null) + ' ' + appSettingsParameters; + var appSettingsNewProperties = parse(appSettingsParameters); + await this._appServiceUtility.updateAndMonitorAppSettings(appSettingsNewProperties); + } + + private async _updateConfigurationDetails(taskParameters: TaskParameters, imageName: string): Promise { + var startupCommand: string = taskParameters.StartupCommand; + var configSettingsParameters = taskParameters.ConfigurationSettings; + var appSettingsNewProperties = !!configSettingsParameters ? parse(configSettingsParameters.trim()): { }; + appSettingsNewProperties.appCommandLine = { + 'value': startupCommand + } + + appSettingsNewProperties.linuxFxVersion = { + 'value': "DOCKER|" + imageName + } + tl.debug(`CONATINER UPDATE CONFIG VALUES : ${appSettingsNewProperties}`); + await this._appServiceUtility.updateConfigurationSettings(appSettingsNewProperties); + } + + private getDockerHubImageName(): string { + var namespace = tl.getInput('DockerNamespace', true); + var image = tl.getInput('DockerRepository', true); + var tag = tl.getInput('DockerImageTag', false); + + return this._constructImageName(namespace, image, tag); + } + + private _getAzureContainerImageName(): string { + var registry = tl.getInput('AzureContainerRegistryLoginServer', true) + ".azurecr.io"; + var image = tl.getInput('AzureContainerRegistryImage', true); + var tag = tl.getInput('AzureContainerRegistryTag', false); + + return this._constructImageName(registry, image, tag); + } + + private _getDockerHubImageName(): string { + var namespace = tl.getInput('DockerNamespace', true); + var image = tl.getInput('DockerRepository', true); + var tag = tl.getInput('DockerImageTag', false); + + return this._constructImageName(namespace, image, tag); + } + + private _constructImageName(namespace, repository, tag): string { + var imageName = null; + /* + Special Case : If release definition is not linked to build artifacts + then $(Build.BuildId) variable don't expand in release. So clearing state + of dockerImageTag if $(Build.BuildId) not expanded in value of dockerImageTag. + */ + if(tag && (tag.trim() == "$(Build.BuildId)")) { + tag = null; + } + + if(tag) { + imageName = namespace + "/" + repository + ":" + tag; + } else { + imageName = namespace + "/" + repository; + } + + return imageName; + } + + private _getPrivateRegistryImageName(): string { + var registryConnectedServiceName = tl.getInput('RegistryConnectedServiceName', true); + var loginServer = tl.getEndpointAuthorizationParameter(registryConnectedServiceName, 'url', true); + + var registry = url.parse(loginServer).hostname; + var image = tl.getInput('PrivateRegistryImage', true); + var tag = tl.getInput('PrivateRegistryTag', false); + + return this._constructImageName(registry, image, tag); + } + + private _updateWebAppSettings(appSettingsParameters, webAppSettings): void { + // In case of public repo, clear the connection details of a registry + var dockerRespositoryAccess = tl.getInput('DockerRepositoryAccess', true); + + // Uncomment the below lines while supprting all registry types. + // if(dockerRespositoryAccess === "public") + // { + // deleteRegistryConnectionSettings(webAppSettings); + // } + + var parsedAppSettings = parse(appSettingsParameters); + for (var settingName in parsedAppSettings) { + var setting = settingName.trim(); + var settingVal = parsedAppSettings[settingName].value; + settingVal = settingVal ? settingVal.trim() : ""; + + if(setting) { + webAppSettings["properties"][setting] = settingVal; + } + } + } + + private _getImageName(): string { + var registryType = tl.getInput('ImageSource', true); + var imageName = null; + + switch(registryType) { + case registryTypes[registryTypes.AzureContainerRegistry]: + imageName = this._getAzureContainerImageName(); + break; + + case registryTypes[registryTypes.Registry]: + imageName = this._getDockerHubImageName(); + break; + + case registryTypes[registryTypes.PrivateRegistry]: + imageName = this._getPrivateRegistryImageName(); + break; + } + + return imageName; + } + + private async _getContainerRegistrySettings(imageName, endPoint): Promise { + var containerRegistryType: string = tl.getInput('ImageSource', true); + 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"; + + switch(containerRegistryType) { + case registryTypes[registryTypes.AzureContainerRegistry]: + containerRegistrySettings = await this._getAzureContainerRegistrySettings(endPoint, containerRegistrySettings, containerRegistryAuthParamsFormatString); + break; + + case registryTypes[registryTypes.Registry]: + var dockerRespositoryAccess = tl.getInput('DockerRepositoryAccess', false); + if(dockerRespositoryAccess === "private") + { + containerRegistrySettings = this._getDockerPrivateRegistrySettings(containerRegistrySettings, containerRegistryAuthParamsFormatString); + } + break; + + case registryTypes[registryTypes.PrivateRegistry]: + containerRegistrySettings = this._getDockerPrivateRegistrySettings(containerRegistrySettings, containerRegistryAuthParamsFormatString); + break; + } + + return containerRegistrySettings; + } + + private async _getAzureContainerRegistrySettings(endPoint, containerRegistrySettings, containerRegistryAuthParamsFormatString): Promise { + var registryServerName = tl.getInput('AzureContainerRegistryLoginServer', true); + var registryUrl = "https://" + registryServerName + ".azurecr.io"; + tl.debug("Azure Container Registry Url: " + registryUrl); + + var registryName = tl.getInput('AzureContainerRegistry', true); + var resourceGroupName = '';// await azureRESTUtility.getResourceGroupName(endPoint, registryName, "Microsoft.ContainerRegistry/registries"); + tl.debug("Resource group name of a registry: " + resourceGroupName); + + var creds = null //await azureRESTUtility.getAzureContainerRegistryCredentials(endPoint, registryName, resourceGroupName); + tl.debug("Successfully retrieved the registry credentials"); + + var username = creds.username; + var password = creds["passwords"][0].value; + + return containerRegistrySettings + " " + util.format(containerRegistryAuthParamsFormatString, registryUrl, username, password); + } + + private _getDockerPrivateRegistrySettings(containerRegistrySettings, containerRegistryAuthParamsFormatString): string { + var registryConnectedServiceName = tl.getInput('RegistryConnectedServiceName', true); + var username = tl.getEndpointAuthorizationParameter(registryConnectedServiceName, 'username', true); + var password = tl.getEndpointAuthorizationParameter(registryConnectedServiceName, 'password', true); + var registryUrl = tl.getEndpointAuthorizationParameter(registryConnectedServiceName, 'registry', true); + + tl.debug("Docker or Private Container Registry Url: " + registryUrl); + + return containerRegistrySettings + " " + util.format(containerRegistryAuthParamsFormatString, registryUrl, username, password); + } + + private _deleteRegistryConnectionSettings(webAppSettings): void { + delete webAppSettings["properties"]["DOCKER_REGISTRY_SERVER_URL"]; + delete webAppSettings["properties"]["DOCKER_REGISTRY_SERVER_USERNAME"]; + delete webAppSettings["properties"]["DOCKER_REGISTRY_SERVER_PASSWORD"]; + } +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/operations/FileTransformsUtility.ts b/Tasks/AzureRmWebAppDeploymentV3/operations/FileTransformsUtility.ts new file mode 100644 index 000000000000..d13b8ce88700 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/operations/FileTransformsUtility.ts @@ -0,0 +1,38 @@ +import tl = require('vsts-task-lib/task'); +import { TaskParameters } from './TaskParameters'; +import { parse } from './ParameterParserUtility'; +var zipUtility = require('webdeployment-common/ziputility.js'); +var deployUtility = require('webdeployment-common/utility.js'); +var fileTransformationsUtility = require('webdeployment-common/fileTransformationsUtility.js'); +var generateWebConfigUtil = require('webdeployment-common/webconfigutil.js'); + +export class FileTransformsUtility { + + private static rootDirectoryPath: string = "D:\\home\\site\\wwwroot"; + + public static async applyTransformations(webPackage: string, taskParams: TaskParameters): Promise { + var applyFileTransformFlag = taskParams.JSONFiles.length != 0 || taskParams.XmlTransformation || taskParams.XmlVariableSubstitution; + if (applyFileTransformFlag || taskParams.GenerateWebConfig) { + var isFolderBasedDeployment: boolean = tl.stats(webPackage).isDirectory(); + var folderPath = await deployUtility.generateTemporaryFolderForDeployment(isFolderBasedDeployment, webPackage); + if (taskParams.GenerateWebConfig) { + tl.debug('parsing web.config parameters'); + var webConfigParameters = parse(taskParams.WebConfigParameters); + generateWebConfigUtil.addWebConfigFile(folderPath, webConfigParameters, this.rootDirectoryPath); + } + + if (applyFileTransformFlag) { + var isMSBuildPackage = !isFolderBasedDeployment && (await deployUtility.isMSDeployPackage(webPackage)); + fileTransformationsUtility.fileTransformations(isFolderBasedDeployment, taskParams.JSONFiles, taskParams.XmlTransformation, taskParams.XmlVariableSubstitution, folderPath, isMSBuildPackage); + } + + var output = await deployUtility.archiveFolderForDeployment(isFolderBasedDeployment, folderPath); + webPackage = output.webDeployPkg; + } + else { + tl.debug('File Tranformation not enabled'); + } + + return webPackage; + } +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/operations/KuduServiceUtility.ts b/Tasks/AzureRmWebAppDeploymentV3/operations/KuduServiceUtility.ts new file mode 100644 index 000000000000..3fe354bc5dc3 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/operations/KuduServiceUtility.ts @@ -0,0 +1,443 @@ +import tl = require('vsts-task-lib/task'); +import Q = require('q'); +import path = require('path'); +import { Kudu } from 'azure-arm-rest/azure-arm-app-service-kudu'; +import { KUDU_DEPLOYMENT_CONSTANTS } from 'azure-arm-rest/constants'; +import webClient = require('azure-arm-rest/webClient'); +import { TaskParameters } from './TaskParameters'; +var deployUtility = require('webdeployment-common/utility.js'); +var zipUtility = require('webdeployment-common/ziputility.js'); +const physicalRootPath: string = '/site/wwwroot'; +const deploymentFolder: string = 'site/deployments'; +const manifestFileName: string = 'manifest'; +const VSTS_ZIP_DEPLOY: string = 'VSTS_ZIP_DEPLOY'; + +export class KuduServiceUtility { + private _appServiceKuduService: Kudu; + private _deploymentID: string; + + constructor(kuduService: Kudu) { + this._appServiceKuduService = kuduService; + } + + public async createPathIfRequired(phsyicalPath: string): Promise { + var listDir = await this._appServiceKuduService.listDir(phsyicalPath); + if(listDir == null) { + await this._appServiceKuduService.createPath(phsyicalPath); + } + } + + public async updateDeploymentStatus(taskResult: boolean, DeploymentID: string, customMessage: any): Promise { + try { + let requestBody = this._getUpdateHistoryRequest(taskResult, DeploymentID, customMessage); + return await this._appServiceKuduService.updateDeployment(requestBody); + } + catch(error) { + tl.warning(error); + } + } + + public async runPostDeploymentScript(taskParams: TaskParameters, directoryPath?: string): Promise { + try { + directoryPath = (!!directoryPath) ? directoryPath : physicalRootPath.substring(1); + + if(taskParams.TakeAppOfflineFlag) { + await this._appOfflineKuduService(directoryPath, true); + } + + var scriptFile = this._getPostDeploymentScript(taskParams.ScriptType, taskParams.InlineScript, taskParams.ScriptPath, taskParams.isLinuxApp); + var uniqueID = this.getDeploymentID(); + var fileExtension : string = taskParams.isLinuxApp ? '.sh' : '.cmd'; + var mainCmdFilePath = path.join(__dirname, '..', 'postDeploymentScript', 'mainCmdFile' + fileExtension); + await this._appServiceKuduService.uploadFile(directoryPath, 'mainCmdFile_' + uniqueID + fileExtension, mainCmdFilePath); + await this._appServiceKuduService.uploadFile(directoryPath, 'kuduPostDeploymentScript_' + uniqueID + fileExtension, scriptFile.filePath); + console.log(tl.loc('ExecuteScriptOnKudu')); + await this.runCommand(directoryPath, + 'mainCmdFile_' + uniqueID + fileExtension + ' ' + uniqueID, + 30, 'script_result_' + uniqueID + '.txt'); + await this._printPostDeploymentLogs(directoryPath, uniqueID); + + } + catch(error) { + throw Error(tl.loc('FailedToRunScriptOnKuduError', error)); + } + finally { + try { + await this._appServiceKuduService.uploadFile(directoryPath, 'delete_log_file_' + uniqueID + fileExtension, path.join(__dirname, '..', 'postDeploymentScript', 'deleteLogFile' + fileExtension)); + await this.runCommand(directoryPath, 'delete_log_file_' + uniqueID + fileExtension + ' ' + uniqueID, 0, null); + } + catch(error) { + tl.debug('Unable to delete log files : ' + error); + } + if(taskParams.TakeAppOfflineFlag) { + await this._appOfflineKuduService(directoryPath, false); + } + } + } + + public getDeploymentID(): string { + if(this._deploymentID) { + return this._deploymentID; + } + + var buildUrl = tl.getVariable('build.buildUri'); + var releaseUrl = tl.getVariable('release.releaseUri'); + + var buildId = tl.getVariable('build.buildId'); + var releaseId = tl.getVariable('release.releaseId'); + + var buildNumber = tl.getVariable('build.buildNumber'); + var releaseName = tl.getVariable('release.releaseName'); + + var collectionUrl = tl.getVariable('system.TeamFoundationCollectionUri'); + var teamProject = tl.getVariable('system.teamProjectId'); + + var commitId = tl.getVariable('build.sourceVersion'); + var repoName = tl.getVariable('build.repository.name'); + var repoProvider = tl.getVariable('build.repository.provider'); + + var buildOrReleaseUrl = "" ; + var deploymentID: string = (releaseId ? releaseId : buildId) + Date.now().toString(); + return deploymentID; + } + + public async deployWebPackage(packagePath: string, physicalPath: string, virtualPath: string, appOffline?: boolean): Promise { + physicalPath = physicalPath ? physicalPath : physicalRootPath; + try { + if(appOffline) { + await this._appOfflineKuduService(physicalPath, true); + tl.debug('Wait for 10 seconds for app_offline to take effect'); + await webClient.sleepFor(10); + } + + if(tl.stats(packagePath).isDirectory()) { + let tempPackagePath = deployUtility.generateTemporaryFolderOrZipPath(tl.getVariable('AGENT.TEMPDIRECTORY'), false); + packagePath = await zipUtility.archiveFolder(packagePath, "", tempPackagePath); + tl.debug("Compressed folder " + packagePath + " into zip : " + packagePath); + } + else if(packagePath.toLowerCase().endsWith('.war')) { + physicalPath = await this._warFileDeployment(packagePath, physicalPath, virtualPath); + } + + await this._appServiceKuduService.extractZIP(packagePath, physicalPath); + if(appOffline) { + await this._appOfflineKuduService(physicalPath, false); + } + + console.log(tl.loc("Successfullydeployedpackageusingkuduserviceat", packagePath, physicalPath)); + } + catch(error) { + tl.error(tl.loc('PackageDeploymentFailed')); + throw Error(error); + } + } + + public async zipDeploy(packagePath: string, appOffline?: boolean, customMessage?: any): Promise { + try { + console.log(tl.loc('PackageDeploymentInitiated')); + await this._preZipDeployOperation(); + + if(tl.stats(packagePath).isDirectory()) { + let tempPackagePath = deployUtility.generateTemporaryFolderOrZipPath(tl.getVariable('AGENT.TEMPDIRECTORY'), false); + packagePath = await zipUtility.archiveFolder(packagePath, "", tempPackagePath); + tl.debug("Compressed folder " + packagePath + " into zip : " + packagePath); + } + + if(appOffline) { + await this._appOfflineKuduService(physicalRootPath, true); + tl.debug('Wait for 10 seconds for app_offline to take effect'); + await webClient.sleepFor(10); + } + + let queryParameters: Array = [ + 'isAsync=true', + 'deployer=' + VSTS_ZIP_DEPLOY + ]; + + let deploymentDetails = await this._appServiceKuduService.zipDeploy(packagePath, queryParameters); + + try { + var kuduDeploymentDetails = await this._appServiceKuduService.getDeploymentDetails(deploymentDetails.id); + tl.debug(`logs from ZIP deploy: ${kuduDeploymentDetails.log_url}`); + await this._printZipDeployLogs(kuduDeploymentDetails.log_url); + } + catch(error) { + tl.debug(`Unable to fetch logs for kudu ZIP Deploy: ${JSON.stringify(error)}`) + } + + if(deploymentDetails.status == KUDU_DEPLOYMENT_CONSTANTS.FAILED) { + throw tl.loc('PackageDeploymentUsingZipDeployFailed'); + } + + if(appOffline) { + await this._appOfflineKuduService(physicalRootPath, false); + } + + console.log(tl.loc('PackageDeploymentSuccess')); + return deploymentDetails.id; + } + catch(error) { + tl.error(tl.loc('PackageDeploymentFailed')); + throw Error(error); + } + } + + public async postZipDeployOperation(oldDeploymentID: string, activeDeploymentID: string): Promise { + try { + tl.debug(`ZIP DEPLOY - Performing post zip-deploy operation: ${oldDeploymentID} => ${activeDeploymentID}`); + let manifestFileContent = await this._appServiceKuduService.getFileContent(`${deploymentFolder}/${oldDeploymentID}`, manifestFileName); + if(!!manifestFileContent) { + let tempManifestFile: string = path.join(tl.getVariable('AGENT.TEMPDIRECTORY'), manifestFileName); + tl.writeFile(tempManifestFile, manifestFileContent); + await this._appServiceKuduService.uploadFile(`${deploymentFolder}/${activeDeploymentID}`, manifestFileName, tempManifestFile); + } + tl.debug('ZIP DEPLOY - Performed post-zipdeploy operation.'); + } + catch(error) { + tl.debug(`Failed to execute post zip-deploy operation: ${JSON.stringify(error)}.`); + } + } + + private async _printZipDeployLogs(log_url: string): Promise { + if(!log_url) { + return; + } + + var deploymentLogs = await this._appServiceKuduService.getDeploymentLogs(log_url); + for(var deploymentLog of deploymentLogs) { + console.log(`${deploymentLog.message}`); + if(deploymentLog.details_url) { + await this._printZipDeployLogs(deploymentLog.details_url); + } + } + } + + private async _preZipDeployOperation(): Promise { + try { + tl.debug('ZIP DEPLOY - Performing pre-zipdeploy operation.'); + let activeDeploymentID: string = await this._appServiceKuduService.getFileContent(deploymentFolder, 'active'); + if(!!activeDeploymentID) { + let activeDeploymentFolder: string = `${deploymentFolder}/${activeDeploymentID}`; + tl.debug(`Active Deployment ID: '${activeDeploymentID}'. Deployment Folder: '${activeDeploymentFolder}'`); + let manifestFileContent: string = await this._appServiceKuduService.getFileContent(activeDeploymentFolder, manifestFileName); + if(!manifestFileContent) { + tl.debug(`No Manifest file present. Creating a empty manifest file in '${activeDeploymentFolder}' directory.`); + var tempManifestFile: string = path.join(tl.getVariable('AGENT.TEMPDIRECTORY'), manifestFileName); + tl.writeFile(tempManifestFile, ''); + await this._appServiceKuduService.uploadFile(`${activeDeploymentFolder}`, manifestFileName, tempManifestFile); + tl.debug(`Manifest file created in '${activeDeploymentFolder}' directory.`); + } + else { + tl.debug('Manifest file present in active deployment directory. Skip creating a new one.'); + } + tl.debug('ZIP DEPLOY - Performed pre-zipdeploy operation.'); + } + } + catch(error) { + tl.debug(`Failed to execute pre zip-deploy operation: ${JSON.stringify(error)}.`); + } + } + + private async _printPostDeploymentLogs(physicalPath: string, uniqueID: string) : Promise { + var stdoutLog = await this._appServiceKuduService.getFileContent(physicalPath, 'stdout_' + uniqueID + '.txt'); + var stderrLog = await this._appServiceKuduService.getFileContent(physicalPath, 'stderr_' + uniqueID + '.txt'); + var scriptReturnCode = await this._appServiceKuduService.getFileContent(physicalPath, 'script_result_' + uniqueID + '.txt'); + + if(scriptReturnCode == null) { + throw new Error('File not found in Kudu Service. ' + 'script_result_' + uniqueID + '.txt'); + } + + if(stdoutLog) { + console.log(tl.loc('stdoutFromScript')); + console.log(stdoutLog); + } + if(stderrLog) { + console.log(tl.loc('stderrFromScript')); + if(scriptReturnCode != '0') { + tl.error(stderrLog); + throw Error(tl.loc('ScriptExecutionOnKuduFailed', scriptReturnCode, stderrLog)); + } + else { + console.log(stderrLog); + } + } + } + + private async runCommand(physicalPath: string, command: string, timeOutInMinutes: number, pollFile: string): Promise { + try { + await this._appServiceKuduService.runCommand(physicalPath, command); + } + catch(error) { + if(timeOutInMinutes > 0 && error.toString().indexOf('Request timeout: /api/command') != -1) { + tl.debug('Request timeout occurs. Trying to poll for file: ' + pollFile); + await this._pollForFile(physicalPath, pollFile, timeOutInMinutes); + } + else { + if(typeof error.valueOf() == 'string') { + throw error; + } + + throw `${error.statusCode} - ${error.statusMessage}`; + } + } + } + + private _getPostDeploymentScript(scriptType, inlineScript, scriptPath, isLinux): any { + if(scriptType === 'Inline Script') { + tl.debug('creating kuduPostDeploymentScript_local file'); + var scriptFilePath = path.join(tl.getVariable('AGENT.TEMPDIRECTORY'), isLinux ? 'kuduPostDeploymentScript_local.sh' : 'kuduPostDeploymentScript_local.cmd'); + tl.writeFile(scriptFilePath, inlineScript); + tl.debug('Created temporary script file : ' + scriptFilePath); + return { + "filePath": scriptFilePath, + "isCreated": true + }; + } + if(!tl.exist(scriptPath)) { + throw Error(tl.loc('ScriptFileNotFound', scriptPath)); + } + var scriptExtension = path.extname(scriptPath); + if(isLinux){ + if(scriptExtension != '.sh'){ + throw Error(tl.loc('InvalidScriptFile', scriptPath)); + } + } else { + if(scriptExtension != '.bat' && scriptExtension != '.cmd') { + throw Error(tl.loc('InvalidScriptFile', scriptPath)); + } + } + tl.debug('postDeployment script path to execute : ' + scriptPath); + return { + filePath: scriptPath, + isCreated: false + } + } + + private async _warFileDeployment(packagePath: string, physicalPath: string, virtualPath?: string): Promise { + tl.debug('WAR: webAppPackage = ' + packagePath); + let warFile = path.basename(packagePath.slice(0, packagePath.length - '.war'.length)); + let warExt = packagePath.slice(packagePath.length - '.war'.length) + tl.debug('WAR: warFile = ' + warFile); + warFile = warFile + ((virtualPath) ? "/" + virtualPath : ""); + tl.debug('WAR: warFile = ' + warFile); + physicalPath = physicalPath + "/webapps/" + warFile; + await this.createPathIfRequired(physicalPath); + return physicalPath; + + } + + private async _appOfflineKuduService(physicalPath: string, enableFeature: boolean): Promise { + if(enableFeature) { + tl.debug('Trying to enable app offline mode.'); + var appOfflineFilePath = path.join(tl.getVariable('AGENT.TEMPDIRECTORY'), 'app_offline_temp.htm'); + tl.writeFile(appOfflineFilePath, '

App Service is offline.

'); + await this._appServiceKuduService.uploadFile(physicalPath, 'app_offline.htm', appOfflineFilePath); + tl.debug('App Offline mode enabled.'); + } + else { + tl.debug('Trying to disable app offline mode.'); + await this._appServiceKuduService.deleteFile(physicalPath, 'app_offline.htm'); + tl.debug('App Offline mode disabled.'); + } + } + + private async _pollForFile(physicalPath: string, fileName: string, timeOutInMinutes: number): Promise { + var attempts: number = 0; + const retryInterval: number = 10; + if(tl.getVariable('appservicedeploy.retrytimeout')) { + timeOutInMinutes = Number(tl.getVariable('appservicedeploy.retrytimeout')); + tl.debug('Retry timeout in minutes provided by user: ' + timeOutInMinutes); + } + + var timeOutInSeconds = timeOutInMinutes * 60; + var noOfRetry = timeOutInSeconds / retryInterval; + + tl.debug(`Polling started for file: ${fileName} with retry count: ${noOfRetry}`); + + while (attempts < noOfRetry) { + attempts += 1; + var fileContent: string = await this._appServiceKuduService.getFileContent(physicalPath, fileName); + if(fileContent == null) { + tl.debug('File: ' + fileName + ' not found. retry after 10 seconds. Attempt: ' + attempts); + await webClient.sleepFor(10); + } + else { + tl.debug('Found file: ' + fileName); + return ; + } + } + + if(attempts == noOfRetry) { + throw new Error(tl.loc('ScriptStatusTimeout')); + } + } + + private _getUpdateHistoryRequest(isDeploymentSuccess: boolean, deploymentID?: string, customMessage?: any): any { + + var status = isDeploymentSuccess ? KUDU_DEPLOYMENT_CONSTANTS.SUCCESS : KUDU_DEPLOYMENT_CONSTANTS.FAILED; + var author = tl.getVariable('build.sourceVersionAuthor') || tl.getVariable('build.requestedfor') || + tl.getVariable('release.requestedfor') || tl.getVariable('agent.name') + + var buildUrl = tl.getVariable('build.buildUri'); + var releaseUrl = tl.getVariable('release.releaseUri'); + + var buildId = tl.getVariable('build.buildId'); + var releaseId = tl.getVariable('release.releaseId'); + + var buildNumber = tl.getVariable('build.buildNumber'); + var releaseName = tl.getVariable('release.releaseName'); + + var collectionUrl = tl.getVariable('system.TeamFoundationCollectionUri'); + var teamProject = tl.getVariable('system.teamProjectId'); + + var commitId = tl.getVariable('build.sourceVersion'); + var repoName = tl.getVariable('build.repository.name'); + var repoProvider = tl.getVariable('build.repository.provider'); + + var buildOrReleaseUrl = "" ; + deploymentID = !!deploymentID ? deploymentID : this.getDeploymentID(); + + if(releaseUrl !== undefined) { + buildOrReleaseUrl = collectionUrl + teamProject + "/_apps/hub/ms.vss-releaseManagement-web.hub-explorer?releaseId=" + releaseId + "&_a=release-summary"; + } + else if(buildUrl !== undefined) { + buildOrReleaseUrl = collectionUrl + teamProject + "/_build?buildId=" + buildId + "&_a=summary"; + } + + var message = { + type : "deployment", + commitId : commitId, + buildId : buildId, + releaseId : releaseId, + buildNumber : buildNumber, + releaseName : releaseName, + repoProvider : repoProvider, + repoName : repoName, + collectionUrl : collectionUrl, + teamProject : teamProject + }; + + if(!!customMessage) { + // Append Custom Messages to original message + for(var attribute in customMessage) { + message[attribute] = customMessage[attribute]; + } + + } + var deploymentLogType: string = message['type']; + var active: boolean = false; + if(deploymentLogType.toLowerCase() === "deployment" && isDeploymentSuccess) { + active = true; + } + + return { + id: deploymentID, + active : active, + status : status, + message : JSON.stringify(message), + author : author, + deployer : 'VSTS', + details : buildOrReleaseUrl + }; + } +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/operations/ParameterParserUtility.ts b/Tasks/AzureRmWebAppDeploymentV3/operations/ParameterParserUtility.ts new file mode 100644 index 000000000000..8933f643c6c3 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/operations/ParameterParserUtility.ts @@ -0,0 +1,127 @@ +// TODO: This whole file is copied from AzureResourceGroupDeployment task. Move this parser to common lib +// Similar parser is used in Grid UI extension. Try to move the code to some place where all can use it. + +export function parse(input: string): {[key: string]: any} { + var result = {}; + var index = 0; + var obj = { name: "", value: "" }; + while (index < input.length) { + var literalData = findLiteral(input, index); + var nextIndex = literalData.currentPosition; + var specialCharacterFlag = literalData.specialCharacterFlag + var literal = input.substr(index, nextIndex - index).trim(); + if (isName(literal, specialCharacterFlag)) { + if (obj.name) { + result[obj.name] = { value: obj.value }; + obj = { name: "", value: "" }; + } + obj.name = literal.substr(1, literal.length); + } + else { + obj.value = literal; + result[obj.name] = { value: obj.value }; + obj = { name: "", value: "" }; + } + index = nextIndex + 1; + } + if (obj.name) { + result[obj.name] = { value: obj.value }; + } + for (var name in result) { + result[name].value = result[name].value.replace(/^"(.*)"$/, '$1'); + } + return result; +} + +function isName(literal: string, specialCharacterFlag: boolean): boolean { + return literal[0] === '-' && !specialCharacterFlag && isNaN(Number(literal)); +} + +function findLiteral(input, currentPosition): {[key: string]: any} { + var specialCharacterFlag = false; + for (; currentPosition < input.length; currentPosition++) { + if (input[currentPosition] == " " || input[currentPosition] == "\t") { + for (; currentPosition < input.length; currentPosition++) { + if (input[currentPosition + 1] != " " || input[currentPosition + 1] != "\t") { + break; + } + } + break; + } + else if (input[currentPosition] == "(") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, ")"); + specialCharacterFlag = true; + } + else if (input[currentPosition] == "[") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, "]"); + specialCharacterFlag = true; + } + else if (input[currentPosition] == "{") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, "}"); + specialCharacterFlag = true; + } + else if (input[currentPosition] == "\"") { + //keep going till this one closes + currentPosition = findClosingQuoteIndex(input, currentPosition + 1, "\""); + specialCharacterFlag = true; + } + else if (input[currentPosition] == "'") { + //keep going till this one closes + currentPosition = findClosingQuoteIndex(input, currentPosition + 1, "'"); + specialCharacterFlag = true; + } + else if (input[currentPosition] == "`") { + currentPosition++; + specialCharacterFlag = true; + if (currentPosition >= input.length) { + break; + } + } + } + return { currentPosition: currentPosition, specialCharacterFlag: specialCharacterFlag }; +} + +function findClosingBracketIndex(input, currentPosition, closingBracket): number { + for (; currentPosition < input.length; currentPosition++) { + if (input[currentPosition] == closingBracket) { + break; + } + else if (input[currentPosition] == "(") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, ")"); + } + else if (input[currentPosition] == "[") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, "]"); + } + else if (input[currentPosition] == "{") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, "}"); + } + else if (input[currentPosition] == "\"") { + currentPosition = findClosingQuoteIndex(input, currentPosition + 1, "\""); + } + else if (input[currentPosition] == "'") { + currentPosition = findClosingQuoteIndex(input, currentPosition + 1, "'"); + } + else if (input[currentPosition] == "`") { + currentPosition++; + if (currentPosition >= input.length) { + break; + } + } + } + return currentPosition; +} + +function findClosingQuoteIndex(input, currentPosition, closingQuote) { + for (; currentPosition < input.length; currentPosition++) { + if (input[currentPosition] == closingQuote) { + break; + } + else if (input[currentPosition] == "`") { + currentPosition++; + if (currentPosition >= input.length) { + break; + } + } + } + return currentPosition; +} diff --git a/Tasks/AzureRmWebAppDeploymentV3/operations/ReleaseAnnotationUtility.ts b/Tasks/AzureRmWebAppDeploymentV3/operations/ReleaseAnnotationUtility.ts new file mode 100644 index 000000000000..bdd343509b1e --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/operations/ReleaseAnnotationUtility.ts @@ -0,0 +1,78 @@ +import tl = require('vsts-task-lib/task'); +import { AzureAppService } from 'azure-arm-rest/azure-arm-app-service'; +import { AzureApplicationInsights, ApplicationInsightsResources} from 'azure-arm-rest/azure-arm-appinsights'; +import { AzureEndpoint } from 'azure-arm-rest/azureModels'; + +var uuidV4 = require("uuid/v4"); + +export async function addReleaseAnnotation(endpoint: AzureEndpoint, azureAppService: AzureAppService, isDeploymentSuccess: boolean): Promise { + try { + var appSettings = await azureAppService.getApplicationSettings(); + var instrumentationKey = appSettings && appSettings.properties && appSettings.properties.APPINSIGHTS_INSTRUMENTATIONKEY; + if(instrumentationKey) { + let appinsightsResources: ApplicationInsightsResources = new ApplicationInsightsResources(endpoint); + var appInsightsResources = await appinsightsResources.list(null, [`$filter=InstrumentationKey eq '${instrumentationKey}'`]); + if(appInsightsResources.length > 0) { + var appInsights: AzureApplicationInsights = new AzureApplicationInsights(endpoint, appInsightsResources[0].id.split('/')[4], appInsightsResources[0].name); + var releaseAnnotationData = getReleaseAnnotation(isDeploymentSuccess); + await appInsights.addReleaseAnnotation(releaseAnnotationData); + console.log(tl.loc("SuccessfullyAddedReleaseAnnotation", appInsightsResources[0].name)); + } + else { + tl.debug(`Unable to find Application Insights resource with Instrumentation key ${instrumentationKey}. Skipping adding release annotation.`); + } + } + else { + tl.debug(`Application Insights is not configured for the App Service. Skipping adding release annotation.`); + } + } + catch(error) { + console.log(tl.loc("FailedAddingReleaseAnnotation", error)); + } +} + +function getReleaseAnnotation(isDeploymentSuccess: boolean): {[key: string]: any} { + let annotationName = "Release Annotation"; + let releaseUri = tl.getVariable("Release.ReleaseUri"); + let buildUri = tl.getVariable("Build.BuildUri"); + + if (!!releaseUri) { + annotationName = `${tl.getVariable("Release.DefinitionName")} - ${tl.getVariable("Release.ReleaseName")}`; + } + else if (!!buildUri) { + annotationName = `${tl.getVariable("Build.DefinitionName")} - ${tl.getVariable("Build.BuildNumber")}`; + } + + let releaseAnnotationProperties = { + "Label": isDeploymentSuccess ? "Success" : "Error", // Label decides the icon for release annotation + "Deployment Uri": getDeploymentUri() + }; + + let releaseAnnotation = { + "AnnotationName": annotationName, + "Category": "Text", + "EventTime": new Date(), + "Id": uuidV4(), + "Properties": JSON.stringify(releaseAnnotationProperties) + }; + + return releaseAnnotation; +} + +function getDeploymentUri(): string { + let buildUri = tl.getVariable("Build.BuildUri"); + let releaseWebUrl = tl.getVariable("Release.ReleaseWebUrl"); + let collectionUrl = tl.getVariable('System.TeamFoundationCollectionUri'); + let teamProject = tl.getVariable('System.TeamProjectId'); + let buildId = tl.getVariable('build.buildId'); + + if (!!releaseWebUrl) { + return releaseWebUrl; + } + + if (!!buildUri) { + return `${collectionUrl}${teamProject}/_build?buildId=${buildId}&_a=summary`; + } + + return ""; +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/operations/TaskParameters.ts b/Tasks/AzureRmWebAppDeploymentV3/operations/TaskParameters.ts new file mode 100644 index 000000000000..08bb2d294602 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/operations/TaskParameters.ts @@ -0,0 +1,95 @@ +import tl = require('vsts-task-lib/task'); + +export class TaskParametersUtility { + public static getParameters(): TaskParameters { + var taskParameters: TaskParameters = { + connectedServiceName: tl.getInput('ConnectedServiceName', true), + WebAppName: tl.getInput('WebAppName', true), + WebAppKind: tl.getInput('WebAppKind', false), + DeployToSlotFlag: tl.getBoolInput('DeployToSlotFlag', false), + VirtualApplication: tl.getInput('VirtualApplication', false), + Package: tl.getPathInput('Package', true), + GenerateWebConfig: tl.getBoolInput('GenerateWebConfig', false), + WebConfigParameters: tl.getInput('WebConfigParameters', false), + XmlTransformation: tl.getBoolInput('XmlTransformation', false), + JSONFiles: tl.getDelimitedInput('JSONFiles', '\n', false), + XmlVariableSubstitution: tl.getBoolInput('XmlVariableSubstitution', false), + UseWebDeploy: tl.getBoolInput('UseWebDeploy', false), + TakeAppOfflineFlag: tl.getBoolInput('TakeAppOfflineFlag', false), + RenameFilesFlag: tl.getBoolInput('RenameFilesFlag', false), + AdditionalArguments: tl.getInput('AdditionalArguments', false), + ScriptType: tl.getInput('ScriptType', false), + InlineScript: tl.getInput('InlineScript', false), + ScriptPath : tl.getPathInput('ScriptPath', false), + DockerNamespace: tl.getInput('DockerNamespace', false), + AppSettings: tl.getInput('AppSettings', false), + ImageSource: tl.getInput('ImageSource', false), + StartupCommand: tl.getInput('StartupCommand', false), + WebAppUri: tl.getInput('WebAppUri', false), + ConfigurationSettings: tl.getInput('ConfigurationSettings', false) + } + + taskParameters.isLinuxApp = taskParameters.WebAppKind && taskParameters.WebAppKind.indexOf("linux") >= 0; + taskParameters.isBuiltinLinuxWebApp = taskParameters.ImageSource && taskParameters.ImageSource.indexOf("Builtin") >= 0; + taskParameters.isContainerWebApp = taskParameters.isLinuxApp && taskParameters.ImageSource.indexOf("Registry") >= 0; + taskParameters.ResourceGroupName = taskParameters.DeployToSlotFlag ? tl.getInput('ResourceGroupName', false) : null; + taskParameters.SlotName = taskParameters.DeployToSlotFlag ? tl.getInput('SlotName', false) : null; + + if(taskParameters.isLinuxApp && taskParameters.isBuiltinLinuxWebApp) { + taskParameters.BuiltinLinuxPackage = tl.getInput('BuiltinLinuxPackage', true); + taskParameters.RuntimeStack = tl.getInput('RuntimeStack', true); + tl.debug('Change package path to Linux package path'); + taskParameters.Package = tl.getInput('BuiltinLinuxPackage', true); + } + + taskParameters.VirtualApplication = taskParameters.VirtualApplication && taskParameters.VirtualApplication.startsWith('/') ? + taskParameters.VirtualApplication.substr(1) : taskParameters.VirtualApplication; + + if(taskParameters.UseWebDeploy) { + taskParameters.RemoveAdditionalFilesFlag = tl.getBoolInput('RemoveAdditionalFilesFlag', false); + taskParameters.SetParametersFile = tl.getPathInput('SetParametersFile', false); + taskParameters.ExcludeFilesFromAppDataFlag = tl.getBoolInput('ExcludeFilesFromAppDataFlag', false) + taskParameters.AdditionalArguments = tl.getInput('AdditionalArguments', false); + } + + return taskParameters; + } +} + +export interface TaskParameters { + connectedServiceName: string; + WebAppName: string; + WebAppKind?: string; + DeployToSlotFlag?: boolean; + ResourceGroupName?: string; + SlotName?: string; + VirtualApplication?: string; + Package: string; + GenerateWebConfig?: boolean; + WebConfigParameters?: string; + XmlTransformation?: boolean; + JSONFiles?: string[]; + XmlVariableSubstitution?: boolean; + UseWebDeploy?: boolean; + RemoveAdditionalFilesFlag?: boolean; + SetParametersFile?: string; + ExcludeFilesFromAppDataFlag?: boolean; + TakeAppOfflineFlag?: boolean; + RenameFilesFlag?: boolean; + AdditionalArguments?: string; + ScriptType?: string; + InlineScript?: string; + ScriptPath ?: string; + DockerNamespace?: string; + AppSettings?: string; + ImageSource?: string; + StartupCommand?: string; + BuiltinLinuxPackage?: string; + RuntimeStack?: string; + WebAppUri?: string; + ConfigurationSettings?: string; + /** Additional parameters */ + isLinuxApp?: boolean; + isBuiltinLinuxWebApp?: boolean; + isContainerWebApp?: boolean; +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/operations/WarDeploymentUtilities.ts b/Tasks/AzureRmWebAppDeploymentV3/operations/WarDeploymentUtilities.ts new file mode 100644 index 000000000000..ad77b0b781c2 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/operations/WarDeploymentUtilities.ts @@ -0,0 +1,70 @@ +import tl = require('vsts-task-lib/task'); +import fs = require('fs'); +import path = require('path'); +import { Kudu } from 'azure-arm-rest/azure-arm-app-service-kudu'; +import { AzureAppServiceUtility } from './AzureAppServiceUtility'; +import { TaskParameters } from './TaskParameters'; +import { sleepFor } from 'azure-arm-rest/webClient'; + +var msDeploy = require('webdeployment-common/deployusingmsdeploy.js'); + +export async function DeployWar(webPackage, taskParams: TaskParameters, msDeployPublishingProfile, kuduService: Kudu, appServiceUtility: AzureAppServiceUtility): Promise { + // get list of files before deploying to the web app. + await appServiceUtility.pingApplication(); + var listOfFilesBeforeDeployment: any = await kuduService.listDir('/site/wwwroot/webapps/'); + tl.debug("Listing file structure of webapps folder before deployment starts => " + JSON.stringify(listOfFilesBeforeDeployment)); + + // Strip package path and only keep the package name. + var warFileName = path.basename(webPackage).split('.war')[0]; + + // Find if directory with same name as war file, existed before deployment + var directoryWithSameNameBeforeDeployment; + if (listOfFilesBeforeDeployment) { + listOfFilesBeforeDeployment.some(item => { + if (item.name == warFileName && item.mime == "inode/directory") { + directoryWithSameNameBeforeDeployment = item; + return true; + } + return false; + }); + } + + var retryCount = 3; + while (retryCount > 0) { + await msDeploy.DeployUsingMSDeploy(webPackage, taskParams.WebAppName, msDeployPublishingProfile, taskParams.RemoveAdditionalFilesFlag, + taskParams.ExcludeFilesFromAppDataFlag, taskParams.TakeAppOfflineFlag, taskParams.VirtualApplication, taskParams.SetParametersFile, + taskParams.AdditionalArguments, false, taskParams.UseWebDeploy); + + // verify if the war file has expanded + // if not expanded, deploy using msdeploy once more, to make it work. + var hasWarExpandedSuccessfully: boolean = await HasWarExpandedSuccessfully(kuduService, directoryWithSameNameBeforeDeployment, warFileName, appServiceUtility); + if (!hasWarExpandedSuccessfully) { + console.log(tl.loc("WarDeploymentRetry")); + // If the war file is exactly same, MSDeploy doesn't update the war file in webapp. + // So by changing ModifiedTime, we ensure it will be updated. + var currentTime = new Date(Date.now()); + var modifiedTime = new Date(Date.now()); + fs.utimesSync(webPackage, currentTime, modifiedTime); + } + else { + break; + } + + retryCount--; + } +} + +export async function HasWarExpandedSuccessfully(kuduService: Kudu, directoryWithSameNameBeforeDeployment: any, warFileName: string, appServiceUtility: AzureAppServiceUtility): Promise { + // Waiting for war to expand + await sleepFor(10); + + // do a get call on the target web app. + await appServiceUtility.pingApplication(); + var filesAfterDeployment: any = await kuduService.listDir('/site/wwwroot/webapps/'); + tl.debug("Listing file structure of webapps folder after deployment has completed => " + JSON.stringify(filesAfterDeployment)); + + // Verify if the content of that war file has successfully expanded. This is can be concluded if + // directory with same name as war file exists after deployment and if it existed before deployment, then the directory should contain content of new war file + // which can be concluded if the modified time of the directory has changed. We have however observerd some minor milliseconds change in the modified time even when deployment is not successfull, only for the first time. Hence we are introducing a check that the time change should be more than 0.5 second or 500 milliseconds. + return filesAfterDeployment.some(item => { return item.name == warFileName && item.mime == "inode/directory" && (!directoryWithSameNameBeforeDeployment || (item.mtime != directoryWithSameNameBeforeDeployment.mtime && (new Date(item.mtime).getTime() - new Date(directoryWithSameNameBeforeDeployment.mtime).getTime() > 500))) }); +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/package-lock.json b/Tasks/AzureRmWebAppDeploymentV3/package-lock.json new file mode 100644 index 000000000000..bdcac53dc66f --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/package-lock.json @@ -0,0 +1,527 @@ +{ + "name": "vsts-tasks-azurermappservicedeployment", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=" + }, + "archiver": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-1.2.0.tgz", + "integrity": "sha1-+1xq9UQ7P6akJjRHU7rSp7REqt0=", + "requires": { + "archiver-utils": "1.3.0", + "async": "2.1.4", + "buffer-crc32": "0.2.13", + "glob": "7.1.1", + "lodash": "4.17.2", + "readable-stream": "2.2.2", + "tar-stream": "1.5.2", + "zip-stream": "1.1.0" + } + }, + "archiver-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz", + "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=", + "requires": { + "glob": "7.1.1", + "graceful-fs": "4.1.11", + "lazystream": "1.0.0", + "lodash": "4.17.2", + "normalize-path": "2.0.1", + "readable-stream": "2.2.2" + } + }, + "async": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.1.4.tgz", + "integrity": "sha1-LSFgx3iAMuTdbL4lAvH5osj2zeQ=", + "requires": { + "lodash": "4.17.2" + } + }, + "azure-arm-rest": { + "version": "file:../../_build/Tasks/Common/azure-arm-rest-1.0.2.tgz", + "requires": { + "q": "1.4.1", + "typed-rest-client": "0.12.0", + "vsts-task-lib": "2.0.5" + } + }, + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + }, + "binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", + "requires": { + "buffers": "0.1.1", + "chainsaw": "0.1.0" + } + }, + "bl": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz", + "integrity": "sha1-/cqHGplxOqANGeO7ukHER4emU5g=", + "requires": { + "readable-stream": "2.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } + } + } + }, + "brace-expansion": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", + "integrity": "sha1-cZfX6qm4fmSDkOph/GbIRCdCDfk=", + "requires": { + "balanced-match": "0.4.2", + "concat-map": "0.0.1" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" + }, + "buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=" + }, + "chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", + "requires": { + "traverse": "0.3.9" + } + }, + "compress-commons": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.1.0.tgz", + "integrity": "sha1-n0RguxKIVkx0c5FuApiqPDINyts=", + "requires": { + "buffer-crc32": "0.2.13", + "crc32-stream": "1.0.0", + "normalize-path": "2.0.1", + "readable-stream": "2.2.2" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "crc32-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-1.0.0.tgz", + "integrity": "sha1-6hVeXh1zjtN3hDj/6S/+KhQa6z8=", + "requires": { + "buffer-crc32": "0.2.13", + "readable-stream": "2.2.2" + } + }, + "decompress-zip": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/decompress-zip/-/decompress-zip-0.3.0.tgz", + "integrity": "sha1-rjvLfjTGWHmt/nfhnDD4ZgK0vbA=", + "requires": { + "binary": "0.3.0", + "graceful-fs": "4.1.11", + "mkpath": "0.1.0", + "nopt": "3.0.6", + "q": "1.5.1", + "readable-stream": "1.1.14", + "touch": "0.0.3" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "end-of-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.1.0.tgz", + "integrity": "sha1-6TUyWLqpEIll78QcsO+K3i88+wc=", + "requires": { + "once": "1.3.3" + }, + "dependencies": { + "once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", + "requires": { + "wrappy": "1.0.2" + } + } + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.3", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "requires": { + "readable-stream": "2.2.2" + } + }, + "lodash": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.2.tgz", + "integrity": "sha1-NKMFW6vgTOQkZ7YH1wAHLH/2v0I=" + }, + "ltx": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/ltx/-/ltx-2.6.2.tgz", + "integrity": "sha1-cD5EN9XjlNJsAxT9j9Xevtjgmdk=", + "requires": { + "inherits": "2.0.3" + } + }, + "minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=", + "requires": { + "brace-expansion": "1.1.6" + } + }, + "mkpath": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz", + "integrity": "sha1-dVSm+Nhxg0zJe1RisSLEwSTW3pE=" + }, + "mockery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/mockery/-/mockery-1.7.0.tgz", + "integrity": "sha1-9O3g2HUMHJcnwnLqLGBiniyaHE8=" + }, + "node-uuid": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz", + "integrity": "sha1-baWhdmjEs91ZYjvaEc9/pMH2Cm8=" + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "requires": { + "abbrev": "1.0.9" + } + }, + "normalize-path": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.0.1.tgz", + "integrity": "sha1-R4hqwWYnYNQmG32XnSQXCdPOP3o=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "q": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", + "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=" + }, + "readable-stream": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.2.tgz", + "integrity": "sha1-qeb+w8fdqF+LsbO6cChgRVb8gl4=", + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } + }, + "sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" + }, + "shelljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", + "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "tar-stream": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.2.tgz", + "integrity": "sha1-+8bG6DwaGdTLSMfZYXH8JI7/x78=", + "requires": { + "bl": "1.1.2", + "end-of-stream": "1.1.0", + "readable-stream": "2.2.2", + "xtend": "4.0.1" + } + }, + "touch": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/touch/-/touch-0.0.3.tgz", + "integrity": "sha1-Ua7z1ElXHU8oel2Hyci0kYGg2x0=", + "requires": { + "nopt": "1.0.10" + }, + "dependencies": { + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "requires": { + "abbrev": "1.0.9" + } + } + } + }, + "traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=" + }, + "tunnel": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", + "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" + }, + "typed-rest-client": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-0.12.0.tgz", + "integrity": "sha1-Y3b1Un9CfaEh3K/f1+QeEyHgcgw=", + "requires": { + "tunnel": "0.0.4", + "underscore": "1.8.3" + } + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" + }, + "vsts-task-lib": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/vsts-task-lib/-/vsts-task-lib-2.0.5.tgz", + "integrity": "sha1-y9WrIy6rtxDJaXkFMYcmlZHA1RA=", + "requires": { + "minimatch": "3.0.3", + "mockery": "1.7.0", + "q": "1.5.1", + "semver": "5.5.0", + "shelljs": "0.3.0", + "uuid": "3.2.1" + }, + "dependencies": { + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" + }, + "uuid": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", + "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" + } + } + }, + "webdeployment-common": { + "version": "file:../../_build/Tasks/Common/webdeployment-common-1.0.0.tgz", + "requires": { + "archiver": "1.2.0", + "decompress-zip": "0.3.0", + "ltx": "2.6.2", + "q": "1.4.1", + "vsts-task-lib": "2.0.1-preview", + "winreg": "1.2.2", + "xml2js": "0.4.13" + }, + "dependencies": { + "vsts-task-lib": { + "version": "2.0.1-preview", + "resolved": "https://registry.npmjs.org/vsts-task-lib/-/vsts-task-lib-2.0.1-preview.tgz", + "integrity": "sha1-rfx4BRaPtJLVcD7eZIXOt4G2SrQ=", + "requires": { + "minimatch": "3.0.3", + "mockery": "1.7.0", + "node-uuid": "1.4.7", + "q": "1.4.1", + "semver": "5.5.0", + "shelljs": "0.3.0" + } + } + } + }, + "winreg": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.2.tgz", + "integrity": "sha1-hQmvo7ccW70RCm18YkfsZ3NsWY8=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xml2js": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.13.tgz", + "integrity": "sha1-+EQ+B0Oeb/ktmVKPSbvTScyfMGs=", + "requires": { + "sax": "1.2.1", + "xmlbuilder": "8.2.2" + } + }, + "xmlbuilder": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-8.2.2.tgz", + "integrity": "sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "zip-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.1.0.tgz", + "integrity": "sha1-KtR5//wWjgWoiOjDSP9oE7PxNzM=", + "requires": { + "archiver-utils": "1.3.0", + "compress-commons": "1.1.0", + "lodash": "4.17.2", + "readable-stream": "2.2.2" + } + } + } +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/package.json b/Tasks/AzureRmWebAppDeploymentV3/package.json new file mode 100644 index 000000000000..28092ab9080b --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/package.json @@ -0,0 +1,26 @@ +{ + "name": "vsts-tasks-azurermappservicedeployment", + "version": "1.0.0", + "description": "VSTS Azure RM App Service Deployment", + "main": "AzureRmWebAppDeployment.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/Microsoft/vsts-tasks.git" + }, + "author": "Microsoft Corporation", + "license": "MIT", + "bugs": { + "url": "https://github.com/Microsoft/vsts-tasks/issues" + }, + "homepage": "https://github.com/Microsoft/vsts-tasks#readme", + "dependencies": { + "azure-arm-rest": "file:../../_build/Tasks/Common/azure-arm-rest-1.0.2.tgz", + "q": "1.4.1", + "uuid": "3.1.0", + "webdeployment-common": "file:../../_build/Tasks/Common/webdeployment-common-1.0.0.tgz", + "xml2js": "0.4.13" + } +} diff --git a/Tasks/AzureRmWebAppDeploymentV3/parameterparser.ts b/Tasks/AzureRmWebAppDeploymentV3/parameterparser.ts new file mode 100644 index 000000000000..d5dfca116d0f --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/parameterparser.ts @@ -0,0 +1,127 @@ +// TODO: This whole file is copied from AzureResourceGroupDeployment task. Move this parser to common lib +// Similar parser is used in Grid UI extension. Try to move the code to some place where all can use it. + +export function parse(input: string) { + var result = {}; + var index = 0; + var obj = { name: "", value: "" }; + while (index < input.length) { + var literalData = findLiteral(input, index); + var nextIndex = literalData.currentPosition; + var specialCharacterFlag = literalData.specialCharacterFlag + var literal = input.substr(index, nextIndex - index).trim(); + if (isName(literal, specialCharacterFlag)) { + if (obj.name) { + result[obj.name] = { value: obj.value }; + obj = { name: "", value: "" }; + } + obj.name = literal.substr(1, literal.length); + } + else { + obj.value = literal; + result[obj.name] = { value: obj.value }; + obj = { name: "", value: "" }; + } + index = nextIndex + 1; + } + if (obj.name) { + result[obj.name] = { value: obj.value }; + } + for (var name in result) { + result[name].value = result[name].value.replace(/^"(.*)"$/, '$1'); + } + return result; +} + +function isName(literal: string, specialCharacterFlag: boolean): boolean { + return literal[0] === '-' && !specialCharacterFlag && isNaN(Number(literal)); +} + +function findLiteral(input, currentPosition) { + var specialCharacterFlag = false; + for (; currentPosition < input.length; currentPosition++) { + if (input[currentPosition] == " " || input[currentPosition] == "\t") { + for (; currentPosition < input.length; currentPosition++) { + if (input[currentPosition + 1] != " " || input[currentPosition + 1] != "\t") { + break; + } + } + break; + } + else if (input[currentPosition] == "(") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, ")"); + specialCharacterFlag = true; + } + else if (input[currentPosition] == "[") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, "]"); + specialCharacterFlag = true; + } + else if (input[currentPosition] == "{") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, "}"); + specialCharacterFlag = true; + } + else if (input[currentPosition] == "\"") { + //keep going till this one closes + currentPosition = findClosingQuoteIndex(input, currentPosition + 1, "\""); + specialCharacterFlag = true; + } + else if (input[currentPosition] == "'") { + //keep going till this one closes + currentPosition = findClosingQuoteIndex(input, currentPosition + 1, "'"); + specialCharacterFlag = true; + } + else if (input[currentPosition] == "`") { + currentPosition++; + specialCharacterFlag = true; + if (currentPosition >= input.length) { + break; + } + } + } + return { currentPosition: currentPosition, specialCharacterFlag: specialCharacterFlag }; +} + +function findClosingBracketIndex(input, currentPosition, closingBracket): number { + for (; currentPosition < input.length; currentPosition++) { + if (input[currentPosition] == closingBracket) { + break; + } + else if (input[currentPosition] == "(") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, ")"); + } + else if (input[currentPosition] == "[") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, "]"); + } + else if (input[currentPosition] == "{") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, "}"); + } + else if (input[currentPosition] == "\"") { + currentPosition = findClosingQuoteIndex(input, currentPosition + 1, "\""); + } + else if (input[currentPosition] == "'") { + currentPosition = findClosingQuoteIndex(input, currentPosition + 1, "'"); + } + else if (input[currentPosition] == "`") { + currentPosition++; + if (currentPosition >= input.length) { + break; + } + } + } + return currentPosition; +} + +function findClosingQuoteIndex(input, currentPosition, closingQuote) { + for (; currentPosition < input.length; currentPosition++) { + if (input[currentPosition] == closingQuote) { + break; + } + else if (input[currentPosition] == "`") { + currentPosition++; + if (currentPosition >= input.length) { + break; + } + } + } + return currentPosition; +} diff --git a/Tasks/AzureRmWebAppDeploymentV3/postDeploymentScript/deleteLogFile.cmd b/Tasks/AzureRmWebAppDeploymentV3/postDeploymentScript/deleteLogFile.cmd new file mode 100644 index 000000000000..37bd932fcda6 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/postDeploymentScript/deleteLogFile.cmd @@ -0,0 +1,24 @@ +@echo off + +DEL "mainCmdFile_%1.cmd" + +DEL "kuduPostDeploymentScript_%1.cmd" + +:: Do not delete file if the execution is not completed within time range +:: This can help in retrieving the logs and script result + +if exist "script_result_%1.txt" ( + + echo remove log files + + DEL "stdout_%1.txt" + + DEL "stderr_%1.txt" + + DEL "script_result_%1.txt" +) + +:: Delete the file after execution +echo remove delete_log_file + +DEL "%~f0" >nul 2>&1 diff --git a/Tasks/AzureRmWebAppDeploymentV3/postDeploymentScript/deleteLogFile.sh b/Tasks/AzureRmWebAppDeploymentV3/postDeploymentScript/deleteLogFile.sh new file mode 100644 index 000000000000..55d178ca993b --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/postDeploymentScript/deleteLogFile.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +rm "mainCmdFile_$1.sh" + +rm "kuduPostDeploymentScript_$1.sh" + +# Do not delete file if the execution is not completed within time range +# This can help in retrieving the logs and script result + +if [ -f "script_result_$1.txt" ] +then + echo "Removing log files." + rm "stdout_$1.txt" + rm "stderr_$1.txt" + rm "script_result_$1.txt" +else + echo "Execution is not over." +fi + +# Delete the file after execution +echo "Removing the delete_log_file_$1.sh file." + +rm "delete_log_file_$1.sh" diff --git a/Tasks/AzureRmWebAppDeploymentV3/postDeploymentScript/mainCmdFile.cmd b/Tasks/AzureRmWebAppDeploymentV3/postDeploymentScript/mainCmdFile.cmd new file mode 100644 index 000000000000..54e0897a5844 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/postDeploymentScript/mainCmdFile.cmd @@ -0,0 +1,9 @@ +@echo off + +:: Send stdout and stderr to seperate file +call cmd /c "kuduPostDeploymentScript_%1.cmd" > "stdout_%1.txt" 2> "stderr_%1.txt" + +:: write return code of previous command to script_result file +:: only return code (Numeric code) should present inside script_result + +echo %errorlevel% > "script_result_%1.txt" \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/postDeploymentScript/mainCmdFile.sh b/Tasks/AzureRmWebAppDeploymentV3/postDeploymentScript/mainCmdFile.sh new file mode 100644 index 000000000000..1956fdbe981f --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/postDeploymentScript/mainCmdFile.sh @@ -0,0 +1,4 @@ +#!/bin/bash +# Send stdout and stderr to seperate file +sh "kuduPostDeploymentScript_$1.sh" 2> "stderr_$1.txt" 1> "stdout_$1.txt" +echo "$?" > "script_result_$1.txt" \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/task.json b/Tasks/AzureRmWebAppDeploymentV3/task.json new file mode 100644 index 000000000000..889ec51927ef --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/task.json @@ -0,0 +1,754 @@ +{ + "id": "497D490F-EEA7-4F2B-AB94-48D9C1ACDCB1", + "name": "AzureRmWebAppDeployment", + "friendlyName": "Azure App Service Deploy", + "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", + "helpMarkDown": "[More Information](https://aka.ms/azurermwebdeployreadme)", + "category": "Deploy", + "visibility": [ + "Build", + "Release" + ], + "runsOn": [ + "Agent" + ], + "author": "Microsoft Corporation", + "version": { + "Major": 3, + "Minor": 4, + "Patch": 0 + }, + "releaseNotes": "What's new in Version 3.0:
  Supports File Transformations (XDT)
  Supports Variable Substitutions(XML, JSON)
Click [here](https://aka.ms/azurermwebdeployreadme) for more Information.", + "minimumAgentVersion": "2.104.1", + "groups": [ + { + "name": "FileTransformsAndVariableSubstitution", + "displayName": "File Transforms & Variable Substitution Options", + "isExpanded": false, + "visibleRule": "WebAppKind != linux && WebAppKind != applinux && WebAppKind != \"\"" + }, + { + "name": "AdditionalDeploymentOptions", + "displayName": "Additional Deployment Options", + "isExpanded": false, + "visibleRule": "WebAppKind != linux && WebAppKind != applinux && WebAppKind != \"\"" + }, + { + "name": "PostDeploymentAction", + "displayName": "Post Deployment Action", + "isExpanded": false, + "visibleRule": "WebAppKind != \"\"" + }, + { + "name": "ApplicationAndConfigurationSettings", + "displayName": "Application and Configuration Settings", + "isExpanded": false + }, + { + "name": "output", + "displayName": "Output", + "isExpanded": true, + "visibleRule": "WebAppKind != \"\"" + } + ], + "inputs": [ + { + "name": "ConnectedServiceName", + "aliases": ["azureSubscription"], + "type": "connectedService:AzureRM", + "label": "Azure subscription", + "defaultValue": "", + "required": true, + "helpMarkDown": "Select the Azure Resource Manager subscription for the deployment." + }, + { + "name": "WebAppKind", + "aliases": ["appType"], + "type": "pickList", + "label": "App type", + "defaultValue": "app", + "required": true, + "options": { + "app": "Web App", + "applinux": "Linux Web App", + "functionapp": "Function App", + "api": "API App", + "mobileapp": "Mobile App" + }, + "properties": { + "EditableOptions": "true" + }, + "helpMarkDown": "Select type of web app to deploy.
Note: Select Linux Web App for built-in platform images or custom container image deployments." + }, + { + "name": "WebAppName", + "type": "pickList", + "label": "App Service name", + "defaultValue": "", + "required": true, + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "Enter or Select the name of an existing Azure App Service. App services based on selected app type will only be listed." + }, + { + "name": "DeployToSlotFlag", + "type": "boolean", + "label": "Deploy to slot", + "defaultValue": "false", + "required": false, + "helpMarkDown": "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.", + "visibleRule": "WebAppKind != \"\"" + }, + { + "name": "ResourceGroupName", + "type": "pickList", + "label": "Resource group", + "defaultValue": "", + "required": true, + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "Enter or Select the Azure Resource group that contains the Azure App Service specified above.", + "visibleRule": "DeployToSlotFlag = true" + }, + { + "name": "SlotName", + "type": "pickList", + "label": "Slot", + "defaultValue": "", + "required": true, + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "Enter or Select an existing Slot other than the Production slot.", + "visibleRule": "DeployToSlotFlag = true" + }, + { + "name": "ImageSource", + "type": "pickList", + "label": "Image Source", + "defaultValue": "Registry", + "options": { + "Registry": "Container Registry", + "Builtin": "Built-in Image" + }, + "required": false, + "properties": { + "EditableOptions": "false", + "PopulateDefaultValue": "true" + }, + "helpMarkDown": "App Service on Linux offers two different options to publish your application
Custom image deployment or App deployment with a built-in platform image. [Learn More](https://go.microsoft.com/fwlink/?linkid=862490)", + "visibleRule": "WebAppKind = applinux || WebAppKind = linux" + }, + { + "name": "AzureContainerRegistry", + "type": "pickList", + "label": "Registry", + "defaultValue": "", + "required": true, + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "A globally unique top-level domain name for your specific registry.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "visibleRule": "ImageSource = AzureContainerRegistry" + }, + { + "name": "AzureContainerRegistryLoginServer", + "type": "pickList", + "label": "Registry Login Server Name", + "defaultValue": "", + "required": false, + "properties": { + "EditableOptions": "False", + "PopulateDefaultValue": "True" + }, + "helpMarkDown": "Enter or Select an Azure container registry login server name.", + "visibleRule": "ImageSource = invalidimagesource" + }, + { + "name": "AzureContainerRegistryImage", + "type": "pickList", + "label": "Image", + "defaultValue": "", + "required": true, + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "Name of the repository where the container images are stored.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "visibleRule": "ImageSource = AzureContainerRegistry" + }, + { + "name": "AzureContainerRegistryTag", + "type": "pickList", + "label": "Tag", + "defaultValue": "", + "required": false, + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "Tags are optional, it is the mechanism that registries use to give Docker images a version.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'.", + "visibleRule": "ImageSource = AzureContainerRegistry" + }, + { + "name": "DockerRepositoryAccess", + "type": "radio", + "label": "Repository Access", + "required": true, + "options": { + "private": "Private", + "public": "Public" + }, + "defaultValue": "public", + "helpMarkDown": "Select the Docker repository access.", + "visibleRule": "ImageSource = invalidImage" + }, + { + "name": "RegistryConnectedServiceName", + "aliases": ["dockerRegistryConnection"], + "type": "connectedService:dockerregistry", + "label": "Registry Connection", + "required": true, + "defaultValue": "", + "helpMarkDown": "Select the registry connection.", + "visibleRule": "DockerRepositoryAccess = private || ImageSource = PrivateRegistry" + }, + { + "name": "PrivateRegistryImage", + "type": "pickList", + "label": "Image", + "defaultValue": "", + "required": true, + "visibleRule": "ImageSource = PrivateRegistry", + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "Name of the repository where the container images are stored.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'." + }, + { + "name": "PrivateRegistryTag", + "type": "pickList", + "label": "Tag", + "defaultValue": "", + "required": false, + "visibleRule": "ImageSource = PrivateRegistry", + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "Tags are optional, it is the mechanism that registries use to give Docker images a version.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'." + }, + { + "name": "DockerNamespace", + "type": "string", + "label": "Registry or Namespace", + "defaultValue": "", + "required": true, + "visibleRule": "WebAppKind != app && WebAppKind != functionapp && WebAppKind != api && WebAppKind != mobileapp && ImageSource = Registry", + "helpMarkDown": "A globally unique top-level domain name for your specific registry or namespace.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'." + }, + { + "name": "DockerRepository", + "type": "string", + "label": "Image", + "defaultValue": "", + "required": true, + "visibleRule": "WebAppKind != app && WebAppKind != functionapp && WebAppKind != api && WebAppKind != mobileapp && ImageSource = Registry", + "helpMarkDown": "Name of the repository where the container images are stored.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'." + }, + { + "name": "DockerImageTag", + "type": "string", + "label": "Tag", + "defaultValue": "", + "required": false, + "visibleRule": "WebAppKind != app && WebAppKind != functionapp && WebAppKind != api && WebAppKind != mobileapp && ImageSource = Registry", + "helpMarkDown": "Tags are optional, it is the mechanism that registries use to give Docker images a version.
Note: Fully qualified image name will be of the format: '`/`:`'. For example, 'myregistry.azurecr.io/nginx:latest'." + }, + { + "name": "VirtualApplication", + "type": "string", + "label": "Virtual application", + "defaultValue": "", + "required": false, + "visibleRule": "WebAppKind != linux && WebAppKind != applinux && WebAppKind != \"\"", + "helpMarkDown": "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." + }, + { + "name": "Package", + "type": "filePath", + "label": "Package or folder", + "defaultValue": "$(System.DefaultWorkingDirectory)/**/*.zip", + "required": true, + "visibleRule": "WebAppKind != linux && WebAppKind != applinux && WebAppKind != \"\"", + "helpMarkDown": "File path to the package or a folder containing app service contents generated by MSBuild or a compressed zip or war file.
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.
For example, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip or $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war." + }, + { + "name": "BuiltinLinuxPackage", + "aliases": ["packageForLinux"], + "type": "filePath", + "label": "Package or folder", + "defaultValue": "$(System.DefaultWorkingDirectory)/**/*.zip", + "required": true, + "visibleRule": "WebAppKind != app && WebAppKind != functionapp && WebAppKind != api && WebAppKind != mobileapp && ImageSource = Builtin", + "helpMarkDown": "File path to the package or a folder containing app service contents generated by MSBuild or a compressed zip or war file.
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.
For example, $(System.DefaultWorkingDirectory)/\\*\\*/\\*.zip or $(System.DefaultWorkingDirectory)/\\*\\*/\\*.war." + }, + { + "name": "RuntimeStack", + "type": "pickList", + "label": "Runtime Stack", + "defaultValue": "", + "required": true, + "options": { + "node|4.4": "Node.js 4.4", + "node|4.5": "Node.js 4.5", + "node|6.2": "Node.js 6.2", + "node|6.6": "Node.js 6.6", + "node|6.9": "Node.js 6.9", + "node|6.10": "Node.js 6.10", + "node|6.11": "Node.js 6.11", + "node|8.0": "Node.js 8.0", + "node|8.1": "Node.js 8.1", + "php|5.6": "PHP 5.6", + "php|7.0": "PHP 7.0", + "dotnetcore|1.0": ".NET Core 1.0", + "dotnetcore|1.1": ".NET Core 1.1", + "dotnetcore|2.0": ".NET Core 2.0", + "ruby|2.3": "Ruby 2.3" + }, + "helpMarkDown": "Select the framework and version.", + "visibleRule": "WebAppKind != app && WebAppKind != functionapp && WebAppKind != api && WebAppKind != mobileapp && ImageSource = Builtin" + }, + { + "name": "StartupCommand", + "type": "string", + "label": "Startup command ", + "defaultValue": "", + "required": false, + "visibleRule": "WebAppKind = applinux || WebAppKind = linux", + "helpMarkDown": "Enter the start up command." + }, + { + "name": "WebAppUri", + "type": "string", + "label": "App Service URL", + "required": false, + "defaultValue": "", + "groupName": "output", + "helpMarkDown": "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." + }, + { + "name": "ScriptType", + "type": "pickList", + "label": "Deployment script type", + "defaultValue": "", + "options": { + "": "Select deployment script type (inline or file)", + "Inline Script": "Inline Script", + "File Path": "Script File Path" + }, + "groupName": "PostDeploymentAction", + "helpMarkDown": "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)." + }, + { + "name": "InlineScript", + "type": "multiLine", + "label": "Inline Script", + "defaultValue": ":: You can provide your deployment commands here. One command per line.", + "groupName": "PostDeploymentAction", + "required": true, + "visibleRule": "ScriptType == Inline Script", + "properties": { + "resizable": "true", + "rows": "10", + "maxLength": "500" + } + }, + { + "name": "ScriptPath", + "type": "filePath", + "label": "Deployment script path", + "required": true, + "groupName": "PostDeploymentAction", + "visibleRule": "ScriptType == File Path" + }, + { + "name": "GenerateWebConfig", + "type": "boolean", + "label": "Generate Web.config", + "defaultValue": "false", + "required": false, + "groupName": "FileTransformsAndVariableSubstitution", + "helpMarkDown": "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)." + }, + { + "name": "WebConfigParameters", + "type": "multiLine", + "label": "Web.config parameters", + "required": true, + "defaultValue": "", + "visibleRule": "GenerateWebConfig == true", + "groupName": "FileTransformsAndVariableSubstitution", + "helpMarkDown": "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).", + "properties": { + "editorExtension": "ms.vss-services-azure.webconfig-parameters-grid" + } + }, + { + "name": "AppSettings", + "type": "multiLine", + "label": "App settings", + "defaultValue": "", + "required": false, + "groupName": "ApplicationAndConfigurationSettings", + "helpMarkDown": "Edit web app application settings following the syntax -key value . Value containing spaces should be enclosed in double quotes.
Example : -Port 5000 -RequestTimeout 5000
-WEBSITE_TIME_ZONE \"Eastern Standard Time\"", + "properties": { + "editorExtension": "ms.vss-services-azure.parameters-grid" + } + }, + { + "name": "ConfigurationSettings", + "type": "multiLine", + "label": "Configuration settings", + "defaultValue": "", + "required": false, + "groupName": "ApplicationAndConfigurationSettings", + "helpMarkDown": "Edit web app configuration settings following the syntax -key value. Value containing spaces should be enclosed in double quotes.
Example : -phpVersion 5.6 -linuxFxVersion: node|6.11", + "properties": { + "editorExtension": "ms.vss-services-azure.parameters-grid" + } + }, + { + "name": "TakeAppOfflineFlag", + "type": "boolean", + "label": "Take App Offline", + "defaultValue": "false", + "required": false, + "groupName": "AdditionalDeploymentOptions", + "helpMarkDown": "Select the option to take the Azure App Service offline by placing an app_offline.htm file in the root directory of the App Service before the sync operation begins. The file will be removed after the sync operation completes successfully." + }, + { + "name": "UseWebDeploy", + "type": "boolean", + "label": "Publish using Web Deploy", + "required": false, + "defaultValue": "false", + "groupName": "AdditionalDeploymentOptions", + "helpMarkDown": "Publish using Web Deploy options are supported only when using Windows agent. On other platforms, the task relies on [Kudu REST APIs](https://github.com/projectkudu/kudu/wiki/REST-API) to deploy the Azure App Service, and following options are not supported" + }, + { + "name": "SetParametersFile", + "type": "filePath", + "label": "SetParameters file", + "defaultValue": "", + "required": false, + "groupName": "AdditionalDeploymentOptions", + "visibleRule": "UseWebDeploy == true", + "helpMarkDown": "Optional: location of the SetParameters.xml file to use." + }, + { + "name": "RemoveAdditionalFilesFlag", + "type": "boolean", + "label": "Remove additional files at destination", + "defaultValue": "false", + "required": false, + "groupName": "AdditionalDeploymentOptions", + "visibleRule": "UseWebDeploy == true", + "helpMarkDown": "Select the option to delete files on the Azure App Service that have no matching files in the App Service package or folder.

Note: This will also remove all files related to any extension installed on this Azure App Service. To prevent this, select 'Exclude files from App_Data folder' checkbox. " + }, + { + "name": "ExcludeFilesFromAppDataFlag", + "type": "boolean", + "label": "Exclude files from the App_Data folder", + "defaultValue": "false", + "required": false, + "groupName": "AdditionalDeploymentOptions", + "visibleRule": "UseWebDeploy == true", + "helpMarkDown": "Select the option to prevent files in the App_Data folder from being deployed to the Azure App Service." + }, + { + "name": "AdditionalArguments", + "type": "string", + "label": "Additional arguments", + "required": false, + "defaultValue": "", + "groupName": "AdditionalDeploymentOptions", + "visibleRule": "UseWebDeploy == true", + "helpMarkDown": "Additional Web Deploy arguments following the syntax -key:value .
These will be applied when deploying the Azure App Service. Example: -disableLink:AppPoolExtension -disableLink:ContentExtension.
For more examples of Web Deploy operation settings, refer to [this](https://go.microsoft.com/fwlink/?linkid=838471)." + }, + { + "name": "RenameFilesFlag", + "type": "boolean", + "label": "Rename locked files", + "defaultValue": "false", + "required": false, + "visibleRule": "UseWebDeploy == true", + "groupName": "AdditionalDeploymentOptions", + "helpMarkDown": "Select the option to enable msdeploy flag MSDEPLOY_RENAME_LOCKED_FILES=1 in Azure App Service application settings. The option if set enables msdeploy to rename locked files that are locked during app deployment" + }, + { + "name": "XmlTransformation", + "aliases": ["enableXmlTransform"], + "type": "boolean", + "label": "XML transformation", + "required": false, + "defaultValue": false, + "groupName": "FileTransformsAndVariableSubstitution", + "helpMarkDown": "The config transforms will be run for `*.Release.config` and `*..config` on the `*.config file`.
Config transforms will be run prior to the Variable Substitution.
XML transformations are supported only for Windows platform." + }, + { + "name": "XmlVariableSubstitution", + "aliases": ["enableXmlVariableSubstitution"], + "type": "boolean", + "label": "XML variable substitution", + "required": false, + "defaultValue": false, + "groupName": "FileTransformsAndVariableSubstitution", + "helpMarkDown": "Variables defined in the Build or Release Definition will be matched against the 'key' or 'name' entries in the appSettings, applicationSettings, and connectionStrings sections of any config file and parameters.xml. Variable Substitution is run after config transforms.

Note: If same variables are defined in the Release Definition and in the Environment, then the Environment variables will supersede the Release Definition variables.
" + }, + { + "name": "JSONFiles", + "type": "multiLine", + "label": "JSON variable substitution", + "required": false, + "defaultValue": "", + "groupName": "FileTransformsAndVariableSubstitution", + "helpMarkDown": "Provide new line separated list of JSON files to substitute the variable values. Files names are to be provided relative to the root folder.
To substitute JSON variables that are nested or hierarchical, specify them using JSONPath expressions.

For example, to replace the value of ‘ConnectionString’ in the sample below, you need to define a variable as ‘Data.DefaultConnection.ConnectionString’ in the build/release definition (or release definition’s environment).
{
  \"Data\": {
    \"DefaultConnection\": {
      \"ConnectionString\": \"Server=(localdb)\\SQLEXPRESS;Database=MyDB;Trusted_Connection=True\"
    }
  }
}
Variable Substitution is run after configuration transforms.

Note: Build/Release’s system definition variables are excluded in substitution" + } + ], + "dataSourceBindings": [ + { + "target": "WebAppName", + "endpointId": "$(ConnectedServiceName)", + "dataSourceName": "AzureRMWebAppNamesByType", + "parameters": { + "WebAppKind": "$(WebAppKind)" + } + }, + { + "target": "ResourceGroupName", + "endpointId": "$(ConnectedServiceName)", + "dataSourceName": "AzureRMWebAppResourceGroup", + "parameters": { + "WebAppName": "$(WebAppName)" + } + }, + { + "target": "SlotName", + "endpointId": "$(ConnectedServiceName)", + "dataSourceName": "AzureRMWebAppSlotsId", + "parameters": { + "WebAppName": "$(WebAppName)", + "ResourceGroupName": "$(ResourceGroupName)" + }, + "resultTemplate": "{\"Value\":\"{{{ #extractResource slots}}}\",\"DisplayValue\":\"{{{ #extractResource slots}}}\"}" + }, + { + "target": "AzureContainerRegistry", + "endpointId": "$(ConnectedServiceName)", + "dataSourceName": "AzureRMContainerRegistries", + "resultTemplate": "{\"Value\":\"{{{ name }}}\",\"DisplayValue\":\"{{{ name }}}\"}" + }, + { + "target": "AzureContainerRegistryLoginServer", + "endpointId": "$(ConnectedServiceName)", + "dataSourceName": "AzureContainerRegistryLoginServer", + "parameters": { + "AzureContainerRegistry": "$(AzureContainerRegistry)" + }, + "resultTemplate": "{\"Value\":\"{{{ #stringReplace '.azurecr.io' '' loginServer }}}\",\"DisplayValue\":\"{{{ #stringReplace '.azurecr.io' '' loginServer }}}\"}" + }, + { + "target": "AzureContainerRegistryImage", + "endpointId": "$(ConnectedServiceName)", + "dataSourceName": "AzureContainerRegistryImages", + "parameters": { + "AzureContainerRegistryLoginServer": "$(AzureContainerRegistryLoginServer)" + } + }, + { + "target": "AzureContainerRegistryTag", + "endpointId": "$(ConnectedServiceName)", + "dataSourceName": "AzureContainerRegistryTags", + "parameters": { + "AzureContainerRegistryLoginServer": "$(AzureContainerRegistryLoginServer)", + "AzureContainerRegistryImage": "$(AzureContainerRegistryImage)" + } + }, + { + "target": "DockerNamespace", + "endpointId": "$(RegistryConnectedServiceName)", + "dataSourceName": "Namespaces" + }, + { + "target": "DockerRepository", + "endpointId": "$(RegistryConnectedServiceName)", + "dataSourceName": "Repos", + "parameters": { + "namespaces": "$(DockerNamespace)" + } + }, + { + "target": "DockerImageTag", + "endpointId": "$(RegistryConnectedServiceName)", + "dataSourceName": "Tags", + "parameters": { + "DockerNamespace": "$(DockerNamespace)", + "DockerRepository": "$(DockerRepository)" + } + }, + { + "target": "PrivateRegistryImage", + "endpointId": "$(RegistryConnectedServiceName)", + "endpointUrl": "{{endpoint.url}}v2/_catalog", + "resultSelector": "jsonpath:$.repositories[*]", + "authorizationHeader": "Basic {{ #base64 endpoint.username \":\" endpoint.password }}" + }, + { + "target": "PrivateRegistryTag", + "endpointId": "$(RegistryConnectedServiceName)", + "endpointUrl": "{{endpoint.url}}v2/$(PrivateRegistryImage)/tags/list", + "resultSelector": "jsonpath:$.tags[*]", + "authorizationHeader": "Basic {{ #base64 endpoint.username \":\" endpoint.password }}" + } + ], + "instanceNameFormat": "Azure App Service Deploy: $(WebAppName)", + "execution": { + "Node": { + "target": "azurermwebappdeployment.js" + } + }, + "messages": { + "Invalidwebapppackageorfolderpathprovided": "Invalid App Service package or folder path provided: %s", + "SetParamFilenotfound0": "Set parameters file not found: %s", + "XDTTransformationsappliedsuccessfully": "XML Transformations applied successfully", + "GotconnectiondetailsforazureRMWebApp0": "Got connection details for Azure App Service:'%s'", + "ErrorNoSuchDeployingMethodExists": "Error : No such deploying method exists", + "UnabletoretrieveconnectiondetailsforazureRMWebApp": "Unable to retrieve connection details for Azure App Service : %s. Status Code: %s (%s)", + "UnabletoretrieveResourceID": "Unable to retrieve connection details for Azure Resource:'%s'. Status Code: %s", + "CouldnotfetchaccesstokenforAzureStatusCode": "Could not fetch access token for Azure. Status Code: %s (%s)", + "Successfullyupdateddeploymenthistory": "Successfully updated deployment History at %s", + "Failedtoupdatedeploymenthistory": "Failed to update deployment history. Error: %s", + "WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "WARNING : Cannot update deployment status : SCM endpoint is not enabled for this website", + "Unabletoretrievewebconfigdetails": "Unable to retrieve App Service configuration details. Status Code: '%s'", + "Unabletoretrievewebappsettings": "Unable to retrieve App Service application settings. [Status Code: '%s', Error Message: '%s']", + "Unabletoupdatewebappsettings": "Unable to update App service application settings. Status Code: '%s'", + "CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "Cannot update deployment status : Unique Deployment ID cannot be retrieved", + "PackageDeploymentSuccess": "Successfully deployed web package to App Service.", + "PackageDeploymentFailed": "Failed to deploy web package to App Service.", + "Runningcommand": "Running command: %s", + "Deployingwebapplicationatvirtualpathandphysicalpath": "Deploying web package : %s at virtual path (physical path) : %s (%s)", + "Successfullydeployedpackageusingkuduserviceat": "Successfully deployed package %s using kudu service at %s", + "Failedtodeploywebapppackageusingkuduservice": "Failed to deploy App Service package using kudu service : %s", + "Unabletodeploywebappresponsecode": "Unable to deploy App Service due to error code : %s", + "MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "MSDeploy generated packages are only supported for Windows platform.", + "UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "Unsupported installed version: %s found for MSDeploy. version should be at least 3 or above", + "UnabletofindthelocationofMSDeployfromregistryonmachineError": "Unable to find the location of MS Deploy from registry on machine (Error : %s)", + "Nopackagefoundwithspecifiedpattern": "No package found with specified pattern: %s", + "MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "More than one package matched with specified pattern: %s. Please restrain the search pattern.", + "Trytodeploywebappagainwithappofflineoptionselected": "Try to deploy app service again with Take application offline option selected.", + "Trytodeploywebappagainwithrenamefileoptionselected": "Try to deploy app service again with Rename locked files option selected.", + "NOJSONfilematchedwithspecificpattern": "NO JSON file matched with specific pattern: %s.", + "Configfiledoesntexists": "Configuration file %s doesn't exist.", + "Failedtowritetoconfigfilewitherror": "Failed to write to config file %s with error : %s", + "AppOfflineModeenabled": "App offline mode enabled.", + "Failedtoenableappofflinemode": "Failed to enable app offline mode. Status Code: %s (%s)", + "AppOflineModedisabled": "App offline mode disabled.", + "FailedtodisableAppOfflineMode": "Failed to disable App offline mode. Status Code: %s (%s)", + "CannotPerformXdtTransformationOnNonWindowsPlatform": "Cannot perform XML transformations on a non-Windows platform.", + "XdtTransformationErrorWhileTransforming": "XML transformation error while transforming %s using %s.", + "PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "Publish using webdeploy options are supported only when using Windows agent", + "ResourceDoesntExist": "Resource '%s' doesn't exist. Resource should exist before deployment.", + "EncodeNotSupported": "Detected file encoding of the file %s as %s. Variable substitution is not supported with file encoding %s. Supported encodings are UTF-8 and UTF-16 LE.", + "UnknownFileEncodeError": "Unable to detect encoding of the file %s (typeCode: %s). Supported encodings are UTF-8 and UTF-16 LE.", + "ShortFileBufferError": "File buffer is too short to detect encoding type : %s", + "FailedToUpdateAzureRMWebAppConfigDetails": "Failed to update App Service configuration details. Error: %s", + "SuccessfullyUpdatedAzureRMWebAppConfigDetails": "Successfully updated App Service configuration details", + "RequestedURLforkuduphysicalpath": "Requested URL for kudu physical path : %s", + "Physicalpathalreadyexists": "Physical path '%s' already exists", + "KuduPhysicalpathCreatedSuccessfully": "Kudu physical path created successfully : %s", + "FailedtocreateKuduPhysicalPath": "Failed to create kudu physical path. Error : %s", + "FailedtocheckphysicalPath": "Failed to check kudu physical path. Error Code: %s", + "VirtualApplicationDoesNotExist": "Virtual application doesn't exists : %s", + "JSONParseError": "Unable to parse JSON file: %s. Error: %s", + "JSONvariablesubstitutionappliedsuccessfully": "JSON variable substitution applied successfully.", + "XMLvariablesubstitutionappliedsuccessfully": "XML variable substitution applied successfully.", + "failedtoUploadFileToKudu": "Unable to upload file: %s to Kudu (%s). Status Code: %s", + "failedtoUploadFileToKuduError": "Unable to upload file: %s to Kudu (%s). Error: %s", + "ExecuteScriptOnKudu": "Executing given script on Kudu service.", + "FailedToRunScriptOnKuduError": "Unable to run the script on Kudu Service. Error: %s", + "FailedToRunScriptOnKudu": "Unable to run the script on Kudu: %s. Status Code: %s", + "ScriptExecutionOnKuduSuccess": "Successfully executed script on Kudu.", + "ScriptExecutionOnKuduFailed": "Executed script returned '%s' as return code. Error: %s", + "FailedtoDeleteFileFromKudu": "Unable to delete file: %s from Kudu (%s). Status Code: %s", + "FailedtoDeleteFileFromKuduError": "Unable to delete file: %s from Kudu (%s). Error: %s", + "ScriptFileNotFound": "Script file '%s' not found.", + "InvalidScriptFile": "Invalid script file '%s' provided. Valid extensions are .bat and .cmd for windows and .sh for linux", + "RetryForTimeoutIssue": "Script execution failed with timeout issue. Retrying once again.", + "stdoutFromScript": "Standard output from script: ", + "stderrFromScript": "Standard error from script: ", + "WebConfigAlreadyExists": "web.config file already exists. Not generating.", + "SuccessfullyGeneratedWebConfig": "Successfully generated web.config file", + "FailedToGenerateWebConfig": "Failed to generate web.config. %s", + "FailedToGetKuduFileContent": "Unable to get file content: %s . Status code: %s (%s)", + "FailedToGetKuduFileContentError": "Unable to get file content: %s. Error: %s", + "ScriptStatusTimeout": "Unable to fetch script status due to timeout.", + "PollingForFileTimeOut": "Unable to fetch script status due to timeout. You can increase the timeout limit by setting 'appservicedeploy.retrytimeout' variable to number of minutes required.", + "InvalidPollOption": "Invalid polling option provided: %s.", + "MissingAppTypeWebConfigParameters": "Attribute '-appType' is missing in the Web.config parameters. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask', 'node' and 'Go'.
For example, '-appType python_Bottle' (sans-quotes) in case of Python Bottle framework..", + "AutoDetectDjangoSettingsFailed": "Unable to detect DJANGO_SETTINGS_MODULE 'settings.py' file path. Ensure that the 'settings.py' file exists or provide the correct path in Web.config parameter input in the following format '-DJANGO_SETTINGS_MODULE .settings'", + "FailedToApplyTransformation": "Unable to apply transformation for the given package. Verify the following.", + "FailedToApplyTransformationReason1": "1. Whether the Transformation is already applied for the MSBuild generated package during build. If yes, remove the tag for each config in the csproj file and rebuild. ", + "FailedToApplyTransformationReason2": "2. Ensure that the config file and transformation files are present in the same folder inside the package.", + "AutoParameterizationMessage": "ConnectionString attributes in Web.config is parameterized by default. Note that the transformation has no effect on connectionString attributes as the value is overridden during deployment by 'Parameters.xml or 'SetParameters.xml' files. You can disable the auto-parameterization by setting /p:AutoParameterizationWebConfigConnectionStrings=False during MSBuild package generation.", + "UnsupportedAppType": "App type '%s' not supported in Web.config generation. Valid values for '-appType' are: 'python_Bottle', 'python_Django', 'python_Flask' and 'node'", + "UnableToFetchAuthorityURL": "Unable to fetch authority url.", + "UnableToFetchActiveDirectory": "Unable to fetch active directory resource id.", + "SuccessfullyUpdatedRuntimeStackAndStartupCommand": "Successfully updated the Runtime Stack and Startup Command.", + "FailedToUpdateRuntimeStackAndStartupCommand": "Failed to update the Runtime Stack and Startup Command. Error: %s.", + "SuccessfullyUpdatedWebAppSettings": "Successfully updated the App settings.", + "FailedToUpdateAppSettingsInConfigDetails": "Failed to update the App settings. Error: %s.", + "UnableToGetAzureRMWebAppMetadata": "Failed to fetch AzureRM WebApp metadata. ErrorCode: %s", + "UnableToUpdateAzureRMWebAppMetadata": "Unable to update AzureRM WebApp metadata. Error Code: %s", + "Unabletoretrieveazureregistrycredentials": "Unable to retrieve Azure Container Registry credentails.[Status Code: '%s']", + "UnableToReadResponseBody": "Unable to read response body. Error: %s", + "UnableToUpdateWebAppConfigDetails": "Unable to update WebApp config details. StatusCode: '%s'", + "AddingReleaseAnnotation": "Adding release annotation for the Application Insights resource '%s'", + "SuccessfullyAddedReleaseAnnotation": "Successfully added release annotation to the Application Insight : %s", + "FailedAddingReleaseAnnotation": "Failed to add release annotation. %s", + "RenameLockedFilesEnabled": "Rename locked files enabled for App Service.", + "FailedToEnableRenameLockedFiles": "Failed to enable rename locked files. Error: %s", + "WebJobsInProgressIssue": "Few WebJobs in running state prevents the deployment from removing the files. You can disable 'Remove additional files at destinaton' option or Stop continuous Jobs before deployment.", + "FailedToFetchKuduAppSettings": "Failed to fetch Kudu App Settings. Error: %s", + "FailedToCreatePath": "Failed to create path '%s' from Kudu. Error: %s", + "FailedToDeleteFile": "Failed to delete file '%s/%s' from Kudu. Error: %s", + "FailedToUploadFile": "Failed to upload file '%s/%s' from Kudu. Error: %s", + "FailedToGetFileContent": "Failed to get file content '%s/%s' from Kudu. Error: %s", + "FailedToListPath": "Failed to list path '%s' from Kudu. Error: %s", + "RetryToDeploy": "Retrying to deploy the package.", + "FailedToGetAppServiceDetails": "Failed to fetch App Service '%s' details. Error: %s", + "FailedToGetAppServicePublishingProfile": "Failed to fetch App Service '%s' publishing profile. Error: %s", + "FailedToUpdateAppServiceMetadata": "Failed to update App service '%s' Meta data. Error: %s", + "FailedToGetAppServiceMetadata": "Failed to get App service '%s' Meta data. Error: %s", + "FailedToPatchAppServiceConfiguration": "Failed to patch App Service '%s' configuration. Error: %s", + "FailedToUpdateAppServiceConfiguration": "Failed to update App service '%s' configuration. Error: %s", + "FailedToGetAppServiceConfiguration": "Failed to get App service '%s' configuration. Error: %s", + "FailedToGetAppServicePublishingCredentials": "Failed to fetch App Service '%s' publishing credentials. Error: %s", + "FailedToGetAppServiceApplicationSettings": "Failed to get App service '%s' application settings. Error: %s", + "FailedToUpdateAppServiceApplicationSettings": "Failed to update App service '%s' application settings. Error: %s", + "UpdatingAppServiceConfigurationSettings": "Updating App Service Configuration settings. Data: %s", + "UpdatedAppServiceConfigurationSettings": "Updated App Service Configuration settings.", + "UpdatingAppServiceApplicationSettings": "Updating App Service Application settings. Data: %s", + "UpdatedAppServiceApplicationSettings": "Updated App Service Application settings and Kudu Application settings.", + "MultipleResourceGroupFoundForAppService": "Multiple resource group found for App Service '%s'.", + "PackageDeploymentUsingZipDeployFailed": "Package deployment using ZIP Deploy failed. Refer logs for more details.", + "PackageDeploymentInitiated": "Package deployment using ZIP Deploy initiated.", + "FailedToGetDeploymentLogs": "Failed to get deployment logs. Error: %s", + "GoExeNameNotPresent": "Go exe name is not present", + "WarDeploymentRetry": "Retrying war file deployment as it did not expand successfully earlier.", + "Updatemachinetoenablesecuretlsprotocol" : "Make sure the machine is using TLS 1.2 protocol or higher. Check https://aka.ms/enableTlsv2 for more information on how to enable TLS in your machine.", + "FailedToGetResourceID": "Failed to get resource ID for resource type '%s' and resource name '%s'. Error: %s", + "CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "Could not fetch access token for Managed Service Principal. Please configure Managed Service Identity (MSI) for virtual machine 'https://aka.ms/azure-msi-docs'. Status code: %s, status message: %s", + "ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release pipeline", + "ASE_WebDeploySSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to pass -allowUntrusted in additional arguments of web deploy option." + } +} diff --git a/Tasks/AzureRmWebAppDeploymentV3/task.loc.json b/Tasks/AzureRmWebAppDeploymentV3/task.loc.json new file mode 100644 index 000000000000..18856fe7db6f --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/task.loc.json @@ -0,0 +1,766 @@ +{ + "id": "497D490F-EEA7-4F2B-AB94-48D9C1ACDCB1", + "name": "AzureRmWebAppDeployment", + "friendlyName": "ms-resource:loc.friendlyName", + "description": "ms-resource:loc.description", + "helpMarkDown": "ms-resource:loc.helpMarkDown", + "category": "Deploy", + "visibility": [ + "Build", + "Release" + ], + "runsOn": [ + "Agent" + ], + "author": "Microsoft Corporation", + "version": { + "Major": 3, + "Minor": 4, + "Patch": 0 + }, + "releaseNotes": "ms-resource:loc.releaseNotes", + "minimumAgentVersion": "2.104.1", + "groups": [ + { + "name": "FileTransformsAndVariableSubstitution", + "displayName": "ms-resource:loc.group.displayName.FileTransformsAndVariableSubstitution", + "isExpanded": false, + "visibleRule": "WebAppKind != linux && WebAppKind != applinux && WebAppKind != \"\"" + }, + { + "name": "AdditionalDeploymentOptions", + "displayName": "ms-resource:loc.group.displayName.AdditionalDeploymentOptions", + "isExpanded": false, + "visibleRule": "WebAppKind != linux && WebAppKind != applinux && WebAppKind != \"\"" + }, + { + "name": "PostDeploymentAction", + "displayName": "ms-resource:loc.group.displayName.PostDeploymentAction", + "isExpanded": false, + "visibleRule": "WebAppKind != \"\"" + }, + { + "name": "ApplicationAndConfigurationSettings", + "displayName": "ms-resource:loc.group.displayName.ApplicationAndConfigurationSettings", + "isExpanded": false + }, + { + "name": "output", + "displayName": "ms-resource:loc.group.displayName.output", + "isExpanded": true, + "visibleRule": "WebAppKind != \"\"" + } + ], + "inputs": [ + { + "name": "ConnectedServiceName", + "aliases": [ + "azureSubscription" + ], + "type": "connectedService:AzureRM", + "label": "ms-resource:loc.input.label.ConnectedServiceName", + "defaultValue": "", + "required": true, + "helpMarkDown": "ms-resource:loc.input.help.ConnectedServiceName" + }, + { + "name": "WebAppKind", + "aliases": [ + "appType" + ], + "type": "pickList", + "label": "ms-resource:loc.input.label.WebAppKind", + "defaultValue": "app", + "required": true, + "options": { + "app": "Web App", + "applinux": "Linux Web App", + "functionapp": "Function App", + "api": "API App", + "mobileapp": "Mobile App" + }, + "properties": { + "EditableOptions": "true" + }, + "helpMarkDown": "ms-resource:loc.input.help.WebAppKind" + }, + { + "name": "WebAppName", + "type": "pickList", + "label": "ms-resource:loc.input.label.WebAppName", + "defaultValue": "", + "required": true, + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "ms-resource:loc.input.help.WebAppName" + }, + { + "name": "DeployToSlotFlag", + "type": "boolean", + "label": "ms-resource:loc.input.label.DeployToSlotFlag", + "defaultValue": "false", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.DeployToSlotFlag", + "visibleRule": "WebAppKind != \"\"" + }, + { + "name": "ResourceGroupName", + "type": "pickList", + "label": "ms-resource:loc.input.label.ResourceGroupName", + "defaultValue": "", + "required": true, + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "ms-resource:loc.input.help.ResourceGroupName", + "visibleRule": "DeployToSlotFlag = true" + }, + { + "name": "SlotName", + "type": "pickList", + "label": "ms-resource:loc.input.label.SlotName", + "defaultValue": "", + "required": true, + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "ms-resource:loc.input.help.SlotName", + "visibleRule": "DeployToSlotFlag = true" + }, + { + "name": "ImageSource", + "type": "pickList", + "label": "ms-resource:loc.input.label.ImageSource", + "defaultValue": "Registry", + "options": { + "Registry": "Container Registry", + "Builtin": "Built-in Image" + }, + "required": false, + "properties": { + "EditableOptions": "false", + "PopulateDefaultValue": "true" + }, + "helpMarkDown": "ms-resource:loc.input.help.ImageSource", + "visibleRule": "WebAppKind = applinux || WebAppKind = linux" + }, + { + "name": "AzureContainerRegistry", + "type": "pickList", + "label": "ms-resource:loc.input.label.AzureContainerRegistry", + "defaultValue": "", + "required": true, + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "ms-resource:loc.input.help.AzureContainerRegistry", + "visibleRule": "ImageSource = AzureContainerRegistry" + }, + { + "name": "AzureContainerRegistryLoginServer", + "type": "pickList", + "label": "ms-resource:loc.input.label.AzureContainerRegistryLoginServer", + "defaultValue": "", + "required": false, + "properties": { + "EditableOptions": "False", + "PopulateDefaultValue": "True" + }, + "helpMarkDown": "ms-resource:loc.input.help.AzureContainerRegistryLoginServer", + "visibleRule": "ImageSource = invalidimagesource" + }, + { + "name": "AzureContainerRegistryImage", + "type": "pickList", + "label": "ms-resource:loc.input.label.AzureContainerRegistryImage", + "defaultValue": "", + "required": true, + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "ms-resource:loc.input.help.AzureContainerRegistryImage", + "visibleRule": "ImageSource = AzureContainerRegistry" + }, + { + "name": "AzureContainerRegistryTag", + "type": "pickList", + "label": "ms-resource:loc.input.label.AzureContainerRegistryTag", + "defaultValue": "", + "required": false, + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "ms-resource:loc.input.help.AzureContainerRegistryTag", + "visibleRule": "ImageSource = AzureContainerRegistry" + }, + { + "name": "DockerRepositoryAccess", + "type": "radio", + "label": "ms-resource:loc.input.label.DockerRepositoryAccess", + "required": true, + "options": { + "private": "Private", + "public": "Public" + }, + "defaultValue": "public", + "helpMarkDown": "ms-resource:loc.input.help.DockerRepositoryAccess", + "visibleRule": "ImageSource = invalidImage" + }, + { + "name": "RegistryConnectedServiceName", + "aliases": [ + "dockerRegistryConnection" + ], + "type": "connectedService:dockerregistry", + "label": "ms-resource:loc.input.label.RegistryConnectedServiceName", + "required": true, + "defaultValue": "", + "helpMarkDown": "ms-resource:loc.input.help.RegistryConnectedServiceName", + "visibleRule": "DockerRepositoryAccess = private || ImageSource = PrivateRegistry" + }, + { + "name": "PrivateRegistryImage", + "type": "pickList", + "label": "ms-resource:loc.input.label.PrivateRegistryImage", + "defaultValue": "", + "required": true, + "visibleRule": "ImageSource = PrivateRegistry", + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "ms-resource:loc.input.help.PrivateRegistryImage" + }, + { + "name": "PrivateRegistryTag", + "type": "pickList", + "label": "ms-resource:loc.input.label.PrivateRegistryTag", + "defaultValue": "", + "required": false, + "visibleRule": "ImageSource = PrivateRegistry", + "properties": { + "EditableOptions": "True" + }, + "helpMarkDown": "ms-resource:loc.input.help.PrivateRegistryTag" + }, + { + "name": "DockerNamespace", + "type": "string", + "label": "ms-resource:loc.input.label.DockerNamespace", + "defaultValue": "", + "required": true, + "visibleRule": "WebAppKind != app && WebAppKind != functionapp && WebAppKind != api && WebAppKind != mobileapp && ImageSource = Registry", + "helpMarkDown": "ms-resource:loc.input.help.DockerNamespace" + }, + { + "name": "DockerRepository", + "type": "string", + "label": "ms-resource:loc.input.label.DockerRepository", + "defaultValue": "", + "required": true, + "visibleRule": "WebAppKind != app && WebAppKind != functionapp && WebAppKind != api && WebAppKind != mobileapp && ImageSource = Registry", + "helpMarkDown": "ms-resource:loc.input.help.DockerRepository" + }, + { + "name": "DockerImageTag", + "type": "string", + "label": "ms-resource:loc.input.label.DockerImageTag", + "defaultValue": "", + "required": false, + "visibleRule": "WebAppKind != app && WebAppKind != functionapp && WebAppKind != api && WebAppKind != mobileapp && ImageSource = Registry", + "helpMarkDown": "ms-resource:loc.input.help.DockerImageTag" + }, + { + "name": "VirtualApplication", + "type": "string", + "label": "ms-resource:loc.input.label.VirtualApplication", + "defaultValue": "", + "required": false, + "visibleRule": "WebAppKind != linux && WebAppKind != applinux && WebAppKind != \"\"", + "helpMarkDown": "ms-resource:loc.input.help.VirtualApplication" + }, + { + "name": "Package", + "type": "filePath", + "label": "ms-resource:loc.input.label.Package", + "defaultValue": "$(System.DefaultWorkingDirectory)/**/*.zip", + "required": true, + "visibleRule": "WebAppKind != linux && WebAppKind != applinux && WebAppKind != \"\"", + "helpMarkDown": "ms-resource:loc.input.help.Package" + }, + { + "name": "BuiltinLinuxPackage", + "aliases": [ + "packageForLinux" + ], + "type": "filePath", + "label": "ms-resource:loc.input.label.BuiltinLinuxPackage", + "defaultValue": "$(System.DefaultWorkingDirectory)/**/*.zip", + "required": true, + "visibleRule": "WebAppKind != app && WebAppKind != functionapp && WebAppKind != api && WebAppKind != mobileapp && ImageSource = Builtin", + "helpMarkDown": "ms-resource:loc.input.help.BuiltinLinuxPackage" + }, + { + "name": "RuntimeStack", + "type": "pickList", + "label": "ms-resource:loc.input.label.RuntimeStack", + "defaultValue": "", + "required": true, + "options": { + "node|4.4": "Node.js 4.4", + "node|4.5": "Node.js 4.5", + "node|6.2": "Node.js 6.2", + "node|6.6": "Node.js 6.6", + "node|6.9": "Node.js 6.9", + "node|6.10": "Node.js 6.10", + "node|6.11": "Node.js 6.11", + "node|8.0": "Node.js 8.0", + "node|8.1": "Node.js 8.1", + "php|5.6": "PHP 5.6", + "php|7.0": "PHP 7.0", + "dotnetcore|1.0": ".NET Core 1.0", + "dotnetcore|1.1": ".NET Core 1.1", + "dotnetcore|2.0": ".NET Core 2.0", + "ruby|2.3": "Ruby 2.3" + }, + "helpMarkDown": "ms-resource:loc.input.help.RuntimeStack", + "visibleRule": "WebAppKind != app && WebAppKind != functionapp && WebAppKind != api && WebAppKind != mobileapp && ImageSource = Builtin" + }, + { + "name": "StartupCommand", + "type": "string", + "label": "ms-resource:loc.input.label.StartupCommand", + "defaultValue": "", + "required": false, + "visibleRule": "WebAppKind = applinux || WebAppKind = linux", + "helpMarkDown": "ms-resource:loc.input.help.StartupCommand" + }, + { + "name": "WebAppUri", + "type": "string", + "label": "ms-resource:loc.input.label.WebAppUri", + "required": false, + "defaultValue": "", + "groupName": "output", + "helpMarkDown": "ms-resource:loc.input.help.WebAppUri" + }, + { + "name": "ScriptType", + "type": "pickList", + "label": "ms-resource:loc.input.label.ScriptType", + "defaultValue": "", + "options": { + "": "Select deployment script type (inline or file)", + "Inline Script": "Inline Script", + "File Path": "Script File Path" + }, + "groupName": "PostDeploymentAction", + "helpMarkDown": "ms-resource:loc.input.help.ScriptType" + }, + { + "name": "InlineScript", + "type": "multiLine", + "label": "ms-resource:loc.input.label.InlineScript", + "defaultValue": ":: You can provide your deployment commands here. One command per line.", + "groupName": "PostDeploymentAction", + "required": true, + "visibleRule": "ScriptType == Inline Script", + "properties": { + "resizable": "true", + "rows": "10", + "maxLength": "500" + } + }, + { + "name": "ScriptPath", + "type": "filePath", + "label": "ms-resource:loc.input.label.ScriptPath", + "required": true, + "groupName": "PostDeploymentAction", + "visibleRule": "ScriptType == File Path" + }, + { + "name": "GenerateWebConfig", + "type": "boolean", + "label": "ms-resource:loc.input.label.GenerateWebConfig", + "defaultValue": "false", + "required": false, + "groupName": "FileTransformsAndVariableSubstitution", + "helpMarkDown": "ms-resource:loc.input.help.GenerateWebConfig" + }, + { + "name": "WebConfigParameters", + "type": "multiLine", + "label": "ms-resource:loc.input.label.WebConfigParameters", + "required": true, + "defaultValue": "", + "visibleRule": "GenerateWebConfig == true", + "groupName": "FileTransformsAndVariableSubstitution", + "helpMarkDown": "ms-resource:loc.input.help.WebConfigParameters", + "properties": { + "editorExtension": "ms.vss-services-azure.webconfig-parameters-grid" + } + }, + { + "name": "AppSettings", + "type": "multiLine", + "label": "ms-resource:loc.input.label.AppSettings", + "defaultValue": "", + "required": false, + "groupName": "ApplicationAndConfigurationSettings", + "helpMarkDown": "ms-resource:loc.input.help.AppSettings", + "properties": { + "editorExtension": "ms.vss-services-azure.parameters-grid" + } + }, + { + "name": "ConfigurationSettings", + "type": "multiLine", + "label": "ms-resource:loc.input.label.ConfigurationSettings", + "defaultValue": "", + "required": false, + "groupName": "ApplicationAndConfigurationSettings", + "helpMarkDown": "ms-resource:loc.input.help.ConfigurationSettings", + "properties": { + "editorExtension": "ms.vss-services-azure.parameters-grid" + } + }, + { + "name": "TakeAppOfflineFlag", + "type": "boolean", + "label": "ms-resource:loc.input.label.TakeAppOfflineFlag", + "defaultValue": "false", + "required": false, + "groupName": "AdditionalDeploymentOptions", + "helpMarkDown": "ms-resource:loc.input.help.TakeAppOfflineFlag" + }, + { + "name": "UseWebDeploy", + "type": "boolean", + "label": "ms-resource:loc.input.label.UseWebDeploy", + "required": false, + "defaultValue": "false", + "groupName": "AdditionalDeploymentOptions", + "helpMarkDown": "ms-resource:loc.input.help.UseWebDeploy" + }, + { + "name": "SetParametersFile", + "type": "filePath", + "label": "ms-resource:loc.input.label.SetParametersFile", + "defaultValue": "", + "required": false, + "groupName": "AdditionalDeploymentOptions", + "visibleRule": "UseWebDeploy == true", + "helpMarkDown": "ms-resource:loc.input.help.SetParametersFile" + }, + { + "name": "RemoveAdditionalFilesFlag", + "type": "boolean", + "label": "ms-resource:loc.input.label.RemoveAdditionalFilesFlag", + "defaultValue": "false", + "required": false, + "groupName": "AdditionalDeploymentOptions", + "visibleRule": "UseWebDeploy == true", + "helpMarkDown": "ms-resource:loc.input.help.RemoveAdditionalFilesFlag" + }, + { + "name": "ExcludeFilesFromAppDataFlag", + "type": "boolean", + "label": "ms-resource:loc.input.label.ExcludeFilesFromAppDataFlag", + "defaultValue": "false", + "required": false, + "groupName": "AdditionalDeploymentOptions", + "visibleRule": "UseWebDeploy == true", + "helpMarkDown": "ms-resource:loc.input.help.ExcludeFilesFromAppDataFlag" + }, + { + "name": "AdditionalArguments", + "type": "string", + "label": "ms-resource:loc.input.label.AdditionalArguments", + "required": false, + "defaultValue": "", + "groupName": "AdditionalDeploymentOptions", + "visibleRule": "UseWebDeploy == true", + "helpMarkDown": "ms-resource:loc.input.help.AdditionalArguments" + }, + { + "name": "RenameFilesFlag", + "type": "boolean", + "label": "ms-resource:loc.input.label.RenameFilesFlag", + "defaultValue": "false", + "required": false, + "visibleRule": "UseWebDeploy == true", + "groupName": "AdditionalDeploymentOptions", + "helpMarkDown": "ms-resource:loc.input.help.RenameFilesFlag" + }, + { + "name": "XmlTransformation", + "aliases": [ + "enableXmlTransform" + ], + "type": "boolean", + "label": "ms-resource:loc.input.label.XmlTransformation", + "required": false, + "defaultValue": false, + "groupName": "FileTransformsAndVariableSubstitution", + "helpMarkDown": "ms-resource:loc.input.help.XmlTransformation" + }, + { + "name": "XmlVariableSubstitution", + "aliases": [ + "enableXmlVariableSubstitution" + ], + "type": "boolean", + "label": "ms-resource:loc.input.label.XmlVariableSubstitution", + "required": false, + "defaultValue": false, + "groupName": "FileTransformsAndVariableSubstitution", + "helpMarkDown": "ms-resource:loc.input.help.XmlVariableSubstitution" + }, + { + "name": "JSONFiles", + "type": "multiLine", + "label": "ms-resource:loc.input.label.JSONFiles", + "required": false, + "defaultValue": "", + "groupName": "FileTransformsAndVariableSubstitution", + "helpMarkDown": "ms-resource:loc.input.help.JSONFiles" + } + ], + "dataSourceBindings": [ + { + "target": "WebAppName", + "endpointId": "$(ConnectedServiceName)", + "dataSourceName": "AzureRMWebAppNamesByType", + "parameters": { + "WebAppKind": "$(WebAppKind)" + } + }, + { + "target": "ResourceGroupName", + "endpointId": "$(ConnectedServiceName)", + "dataSourceName": "AzureRMWebAppResourceGroup", + "parameters": { + "WebAppName": "$(WebAppName)" + } + }, + { + "target": "SlotName", + "endpointId": "$(ConnectedServiceName)", + "dataSourceName": "AzureRMWebAppSlotsId", + "parameters": { + "WebAppName": "$(WebAppName)", + "ResourceGroupName": "$(ResourceGroupName)" + }, + "resultTemplate": "{\"Value\":\"{{{ #extractResource slots}}}\",\"DisplayValue\":\"{{{ #extractResource slots}}}\"}" + }, + { + "target": "AzureContainerRegistry", + "endpointId": "$(ConnectedServiceName)", + "dataSourceName": "AzureRMContainerRegistries", + "resultTemplate": "{\"Value\":\"{{{ name }}}\",\"DisplayValue\":\"{{{ name }}}\"}" + }, + { + "target": "AzureContainerRegistryLoginServer", + "endpointId": "$(ConnectedServiceName)", + "dataSourceName": "AzureContainerRegistryLoginServer", + "parameters": { + "AzureContainerRegistry": "$(AzureContainerRegistry)" + }, + "resultTemplate": "{\"Value\":\"{{{ #stringReplace '.azurecr.io' '' loginServer }}}\",\"DisplayValue\":\"{{{ #stringReplace '.azurecr.io' '' loginServer }}}\"}" + }, + { + "target": "AzureContainerRegistryImage", + "endpointId": "$(ConnectedServiceName)", + "dataSourceName": "AzureContainerRegistryImages", + "parameters": { + "AzureContainerRegistryLoginServer": "$(AzureContainerRegistryLoginServer)" + } + }, + { + "target": "AzureContainerRegistryTag", + "endpointId": "$(ConnectedServiceName)", + "dataSourceName": "AzureContainerRegistryTags", + "parameters": { + "AzureContainerRegistryLoginServer": "$(AzureContainerRegistryLoginServer)", + "AzureContainerRegistryImage": "$(AzureContainerRegistryImage)" + } + }, + { + "target": "DockerNamespace", + "endpointId": "$(RegistryConnectedServiceName)", + "dataSourceName": "Namespaces" + }, + { + "target": "DockerRepository", + "endpointId": "$(RegistryConnectedServiceName)", + "dataSourceName": "Repos", + "parameters": { + "namespaces": "$(DockerNamespace)" + } + }, + { + "target": "DockerImageTag", + "endpointId": "$(RegistryConnectedServiceName)", + "dataSourceName": "Tags", + "parameters": { + "DockerNamespace": "$(DockerNamespace)", + "DockerRepository": "$(DockerRepository)" + } + }, + { + "target": "PrivateRegistryImage", + "endpointId": "$(RegistryConnectedServiceName)", + "endpointUrl": "{{endpoint.url}}v2/_catalog", + "resultSelector": "jsonpath:$.repositories[*]", + "authorizationHeader": "Basic {{ #base64 endpoint.username \":\" endpoint.password }}" + }, + { + "target": "PrivateRegistryTag", + "endpointId": "$(RegistryConnectedServiceName)", + "endpointUrl": "{{endpoint.url}}v2/$(PrivateRegistryImage)/tags/list", + "resultSelector": "jsonpath:$.tags[*]", + "authorizationHeader": "Basic {{ #base64 endpoint.username \":\" endpoint.password }}" + } + ], + "instanceNameFormat": "ms-resource:loc.instanceNameFormat", + "execution": { + "Node": { + "target": "azurermwebappdeployment.js" + } + }, + "messages": { + "Invalidwebapppackageorfolderpathprovided": "ms-resource:loc.messages.Invalidwebapppackageorfolderpathprovided", + "SetParamFilenotfound0": "ms-resource:loc.messages.SetParamFilenotfound0", + "XDTTransformationsappliedsuccessfully": "ms-resource:loc.messages.XDTTransformationsappliedsuccessfully", + "GotconnectiondetailsforazureRMWebApp0": "ms-resource:loc.messages.GotconnectiondetailsforazureRMWebApp0", + "ErrorNoSuchDeployingMethodExists": "ms-resource:loc.messages.ErrorNoSuchDeployingMethodExists", + "UnabletoretrieveconnectiondetailsforazureRMWebApp": "ms-resource:loc.messages.UnabletoretrieveconnectiondetailsforazureRMWebApp", + "UnabletoretrieveResourceID": "ms-resource:loc.messages.UnabletoretrieveResourceID", + "CouldnotfetchaccesstokenforAzureStatusCode": "ms-resource:loc.messages.CouldnotfetchaccesstokenforAzureStatusCode", + "Successfullyupdateddeploymenthistory": "ms-resource:loc.messages.Successfullyupdateddeploymenthistory", + "Failedtoupdatedeploymenthistory": "ms-resource:loc.messages.Failedtoupdatedeploymenthistory", + "WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite": "ms-resource:loc.messages.WARNINGCannotupdatedeploymentstatusSCMendpointisnotenabledforthiswebsite", + "Unabletoretrievewebconfigdetails": "ms-resource:loc.messages.Unabletoretrievewebconfigdetails", + "Unabletoretrievewebappsettings": "ms-resource:loc.messages.Unabletoretrievewebappsettings", + "Unabletoupdatewebappsettings": "ms-resource:loc.messages.Unabletoupdatewebappsettings", + "CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved": "ms-resource:loc.messages.CannotupdatedeploymentstatusuniquedeploymentIdCannotBeRetrieved", + "PackageDeploymentSuccess": "ms-resource:loc.messages.PackageDeploymentSuccess", + "PackageDeploymentFailed": "ms-resource:loc.messages.PackageDeploymentFailed", + "Runningcommand": "ms-resource:loc.messages.Runningcommand", + "Deployingwebapplicationatvirtualpathandphysicalpath": "ms-resource:loc.messages.Deployingwebapplicationatvirtualpathandphysicalpath", + "Successfullydeployedpackageusingkuduserviceat": "ms-resource:loc.messages.Successfullydeployedpackageusingkuduserviceat", + "Failedtodeploywebapppackageusingkuduservice": "ms-resource:loc.messages.Failedtodeploywebapppackageusingkuduservice", + "Unabletodeploywebappresponsecode": "ms-resource:loc.messages.Unabletodeploywebappresponsecode", + "MSDeploygeneratedpackageareonlysupportedforWindowsplatform": "ms-resource:loc.messages.MSDeploygeneratedpackageareonlysupportedforWindowsplatform", + "UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove": "ms-resource:loc.messages.UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove", + "UnabletofindthelocationofMSDeployfromregistryonmachineError": "ms-resource:loc.messages.UnabletofindthelocationofMSDeployfromregistryonmachineError", + "Nopackagefoundwithspecifiedpattern": "ms-resource:loc.messages.Nopackagefoundwithspecifiedpattern", + "MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern": "ms-resource:loc.messages.MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern", + "Trytodeploywebappagainwithappofflineoptionselected": "ms-resource:loc.messages.Trytodeploywebappagainwithappofflineoptionselected", + "Trytodeploywebappagainwithrenamefileoptionselected": "ms-resource:loc.messages.Trytodeploywebappagainwithrenamefileoptionselected", + "NOJSONfilematchedwithspecificpattern": "ms-resource:loc.messages.NOJSONfilematchedwithspecificpattern", + "Configfiledoesntexists": "ms-resource:loc.messages.Configfiledoesntexists", + "Failedtowritetoconfigfilewitherror": "ms-resource:loc.messages.Failedtowritetoconfigfilewitherror", + "AppOfflineModeenabled": "ms-resource:loc.messages.AppOfflineModeenabled", + "Failedtoenableappofflinemode": "ms-resource:loc.messages.Failedtoenableappofflinemode", + "AppOflineModedisabled": "ms-resource:loc.messages.AppOflineModedisabled", + "FailedtodisableAppOfflineMode": "ms-resource:loc.messages.FailedtodisableAppOfflineMode", + "CannotPerformXdtTransformationOnNonWindowsPlatform": "ms-resource:loc.messages.CannotPerformXdtTransformationOnNonWindowsPlatform", + "XdtTransformationErrorWhileTransforming": "ms-resource:loc.messages.XdtTransformationErrorWhileTransforming", + "PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent": "ms-resource:loc.messages.PublishusingwebdeployoptionsaresupportedonlywhenusingWindowsagent", + "ResourceDoesntExist": "ms-resource:loc.messages.ResourceDoesntExist", + "EncodeNotSupported": "ms-resource:loc.messages.EncodeNotSupported", + "UnknownFileEncodeError": "ms-resource:loc.messages.UnknownFileEncodeError", + "ShortFileBufferError": "ms-resource:loc.messages.ShortFileBufferError", + "FailedToUpdateAzureRMWebAppConfigDetails": "ms-resource:loc.messages.FailedToUpdateAzureRMWebAppConfigDetails", + "SuccessfullyUpdatedAzureRMWebAppConfigDetails": "ms-resource:loc.messages.SuccessfullyUpdatedAzureRMWebAppConfigDetails", + "RequestedURLforkuduphysicalpath": "ms-resource:loc.messages.RequestedURLforkuduphysicalpath", + "Physicalpathalreadyexists": "ms-resource:loc.messages.Physicalpathalreadyexists", + "KuduPhysicalpathCreatedSuccessfully": "ms-resource:loc.messages.KuduPhysicalpathCreatedSuccessfully", + "FailedtocreateKuduPhysicalPath": "ms-resource:loc.messages.FailedtocreateKuduPhysicalPath", + "FailedtocheckphysicalPath": "ms-resource:loc.messages.FailedtocheckphysicalPath", + "VirtualApplicationDoesNotExist": "ms-resource:loc.messages.VirtualApplicationDoesNotExist", + "JSONParseError": "ms-resource:loc.messages.JSONParseError", + "JSONvariablesubstitutionappliedsuccessfully": "ms-resource:loc.messages.JSONvariablesubstitutionappliedsuccessfully", + "XMLvariablesubstitutionappliedsuccessfully": "ms-resource:loc.messages.XMLvariablesubstitutionappliedsuccessfully", + "failedtoUploadFileToKudu": "ms-resource:loc.messages.failedtoUploadFileToKudu", + "failedtoUploadFileToKuduError": "ms-resource:loc.messages.failedtoUploadFileToKuduError", + "ExecuteScriptOnKudu": "ms-resource:loc.messages.ExecuteScriptOnKudu", + "FailedToRunScriptOnKuduError": "ms-resource:loc.messages.FailedToRunScriptOnKuduError", + "FailedToRunScriptOnKudu": "ms-resource:loc.messages.FailedToRunScriptOnKudu", + "ScriptExecutionOnKuduSuccess": "ms-resource:loc.messages.ScriptExecutionOnKuduSuccess", + "ScriptExecutionOnKuduFailed": "ms-resource:loc.messages.ScriptExecutionOnKuduFailed", + "FailedtoDeleteFileFromKudu": "ms-resource:loc.messages.FailedtoDeleteFileFromKudu", + "FailedtoDeleteFileFromKuduError": "ms-resource:loc.messages.FailedtoDeleteFileFromKuduError", + "ScriptFileNotFound": "ms-resource:loc.messages.ScriptFileNotFound", + "InvalidScriptFile": "ms-resource:loc.messages.InvalidScriptFile", + "RetryForTimeoutIssue": "ms-resource:loc.messages.RetryForTimeoutIssue", + "stdoutFromScript": "ms-resource:loc.messages.stdoutFromScript", + "stderrFromScript": "ms-resource:loc.messages.stderrFromScript", + "WebConfigAlreadyExists": "ms-resource:loc.messages.WebConfigAlreadyExists", + "SuccessfullyGeneratedWebConfig": "ms-resource:loc.messages.SuccessfullyGeneratedWebConfig", + "FailedToGenerateWebConfig": "ms-resource:loc.messages.FailedToGenerateWebConfig", + "FailedToGetKuduFileContent": "ms-resource:loc.messages.FailedToGetKuduFileContent", + "FailedToGetKuduFileContentError": "ms-resource:loc.messages.FailedToGetKuduFileContentError", + "ScriptStatusTimeout": "ms-resource:loc.messages.ScriptStatusTimeout", + "PollingForFileTimeOut": "ms-resource:loc.messages.PollingForFileTimeOut", + "InvalidPollOption": "ms-resource:loc.messages.InvalidPollOption", + "MissingAppTypeWebConfigParameters": "ms-resource:loc.messages.MissingAppTypeWebConfigParameters", + "AutoDetectDjangoSettingsFailed": "ms-resource:loc.messages.AutoDetectDjangoSettingsFailed", + "FailedToApplyTransformation": "ms-resource:loc.messages.FailedToApplyTransformation", + "FailedToApplyTransformationReason1": "ms-resource:loc.messages.FailedToApplyTransformationReason1", + "FailedToApplyTransformationReason2": "ms-resource:loc.messages.FailedToApplyTransformationReason2", + "AutoParameterizationMessage": "ms-resource:loc.messages.AutoParameterizationMessage", + "UnsupportedAppType": "ms-resource:loc.messages.UnsupportedAppType", + "UnableToFetchAuthorityURL": "ms-resource:loc.messages.UnableToFetchAuthorityURL", + "UnableToFetchActiveDirectory": "ms-resource:loc.messages.UnableToFetchActiveDirectory", + "SuccessfullyUpdatedRuntimeStackAndStartupCommand": "ms-resource:loc.messages.SuccessfullyUpdatedRuntimeStackAndStartupCommand", + "FailedToUpdateRuntimeStackAndStartupCommand": "ms-resource:loc.messages.FailedToUpdateRuntimeStackAndStartupCommand", + "SuccessfullyUpdatedWebAppSettings": "ms-resource:loc.messages.SuccessfullyUpdatedWebAppSettings", + "FailedToUpdateAppSettingsInConfigDetails": "ms-resource:loc.messages.FailedToUpdateAppSettingsInConfigDetails", + "UnableToGetAzureRMWebAppMetadata": "ms-resource:loc.messages.UnableToGetAzureRMWebAppMetadata", + "UnableToUpdateAzureRMWebAppMetadata": "ms-resource:loc.messages.UnableToUpdateAzureRMWebAppMetadata", + "Unabletoretrieveazureregistrycredentials": "ms-resource:loc.messages.Unabletoretrieveazureregistrycredentials", + "UnableToReadResponseBody": "ms-resource:loc.messages.UnableToReadResponseBody", + "UnableToUpdateWebAppConfigDetails": "ms-resource:loc.messages.UnableToUpdateWebAppConfigDetails", + "AddingReleaseAnnotation": "ms-resource:loc.messages.AddingReleaseAnnotation", + "SuccessfullyAddedReleaseAnnotation": "ms-resource:loc.messages.SuccessfullyAddedReleaseAnnotation", + "FailedAddingReleaseAnnotation": "ms-resource:loc.messages.FailedAddingReleaseAnnotation", + "RenameLockedFilesEnabled": "ms-resource:loc.messages.RenameLockedFilesEnabled", + "FailedToEnableRenameLockedFiles": "ms-resource:loc.messages.FailedToEnableRenameLockedFiles", + "WebJobsInProgressIssue": "ms-resource:loc.messages.WebJobsInProgressIssue", + "FailedToFetchKuduAppSettings": "ms-resource:loc.messages.FailedToFetchKuduAppSettings", + "FailedToCreatePath": "ms-resource:loc.messages.FailedToCreatePath", + "FailedToDeleteFile": "ms-resource:loc.messages.FailedToDeleteFile", + "FailedToUploadFile": "ms-resource:loc.messages.FailedToUploadFile", + "FailedToGetFileContent": "ms-resource:loc.messages.FailedToGetFileContent", + "FailedToListPath": "ms-resource:loc.messages.FailedToListPath", + "RetryToDeploy": "ms-resource:loc.messages.RetryToDeploy", + "FailedToGetAppServiceDetails": "ms-resource:loc.messages.FailedToGetAppServiceDetails", + "FailedToGetAppServicePublishingProfile": "ms-resource:loc.messages.FailedToGetAppServicePublishingProfile", + "FailedToUpdateAppServiceMetadata": "ms-resource:loc.messages.FailedToUpdateAppServiceMetadata", + "FailedToGetAppServiceMetadata": "ms-resource:loc.messages.FailedToGetAppServiceMetadata", + "FailedToPatchAppServiceConfiguration": "ms-resource:loc.messages.FailedToPatchAppServiceConfiguration", + "FailedToUpdateAppServiceConfiguration": "ms-resource:loc.messages.FailedToUpdateAppServiceConfiguration", + "FailedToGetAppServiceConfiguration": "ms-resource:loc.messages.FailedToGetAppServiceConfiguration", + "FailedToGetAppServicePublishingCredentials": "ms-resource:loc.messages.FailedToGetAppServicePublishingCredentials", + "FailedToGetAppServiceApplicationSettings": "ms-resource:loc.messages.FailedToGetAppServiceApplicationSettings", + "FailedToUpdateAppServiceApplicationSettings": "ms-resource:loc.messages.FailedToUpdateAppServiceApplicationSettings", + "UpdatingAppServiceConfigurationSettings": "ms-resource:loc.messages.UpdatingAppServiceConfigurationSettings", + "UpdatedAppServiceConfigurationSettings": "ms-resource:loc.messages.UpdatedAppServiceConfigurationSettings", + "UpdatingAppServiceApplicationSettings": "ms-resource:loc.messages.UpdatingAppServiceApplicationSettings", + "UpdatedAppServiceApplicationSettings": "ms-resource:loc.messages.UpdatedAppServiceApplicationSettings", + "MultipleResourceGroupFoundForAppService": "ms-resource:loc.messages.MultipleResourceGroupFoundForAppService", + "PackageDeploymentUsingZipDeployFailed": "ms-resource:loc.messages.PackageDeploymentUsingZipDeployFailed", + "PackageDeploymentInitiated": "ms-resource:loc.messages.PackageDeploymentInitiated", + "FailedToGetDeploymentLogs": "ms-resource:loc.messages.FailedToGetDeploymentLogs", + "GoExeNameNotPresent": "ms-resource:loc.messages.GoExeNameNotPresent", + "WarDeploymentRetry": "ms-resource:loc.messages.WarDeploymentRetry", + "Updatemachinetoenablesecuretlsprotocol": "ms-resource:loc.messages.Updatemachinetoenablesecuretlsprotocol", + "FailedToGetResourceID": "ms-resource:loc.messages.FailedToGetResourceID", + "CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode": "ms-resource:loc.messages.CouldNotFetchAccessTokenforMSIDueToMSINotConfiguredProperlyStatusCode", + "ASE_SSLIssueRecommendation": "ms-resource:loc.messages.ASE_SSLIssueRecommendation", + "ASE_WebDeploySSLIssueRecommendation": "ms-resource:loc.messages.ASE_WebDeploySSLIssueRecommendation" + } +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/tsconfig.json b/Tasks/AzureRmWebAppDeploymentV3/tsconfig.json new file mode 100644 index 000000000000..0438b79f69ac --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/tsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "target": "ES6", + "module": "commonjs" + } +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/typings.json b/Tasks/AzureRmWebAppDeploymentV3/typings.json new file mode 100644 index 000000000000..aac1c714b07f --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/typings.json @@ -0,0 +1,9 @@ +{ + "name": "vsts-tasks-azurermappservicedeployment", + "dependencies": {}, + "globalDependencies": { + "mocha": "registry:dt/mocha#2.2.5+20160720003353", + "node": "registry:dt/node#6.0.0+20160920093002", + "q": "registry:dt/q#0.0.0+20160613154756" + } +} diff --git a/Tasks/AzureRmWebAppDeploymentV3/typings/globals/mocha/index.d.ts b/Tasks/AzureRmWebAppDeploymentV3/typings/globals/mocha/index.d.ts new file mode 100644 index 000000000000..ae7de0faa03c --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/typings/globals/mocha/index.d.ts @@ -0,0 +1,202 @@ +// Generated by typings +// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/a361a8ab3c327f208d3f82ad206971d4a63d8c25/mocha/mocha.d.ts +interface MochaSetupOptions { + //milliseconds to wait before considering a test slow + slow?: number; + + // timeout in milliseconds + timeout?: number; + + // ui name "bdd", "tdd", "exports" etc + ui?: string; + + //array of accepted globals + globals?: any[]; + + // reporter instance (function or string), defaults to `mocha.reporters.Spec` + reporter?: any; + + // bail on the first test failure + bail?: boolean; + + // ignore global leaks + ignoreLeaks?: boolean; + + // grep string or regexp to filter tests with + grep?: any; +} + +declare var mocha: Mocha; +declare var describe: Mocha.IContextDefinition; +declare var xdescribe: Mocha.IContextDefinition; +// alias for `describe` +declare var context: Mocha.IContextDefinition; +// alias for `describe` +declare var suite: Mocha.IContextDefinition; +declare var it: Mocha.ITestDefinition; +declare var xit: Mocha.ITestDefinition; +// alias for `it` +declare var test: Mocha.ITestDefinition; +declare var specify: Mocha.ITestDefinition; + +interface MochaDone { + (error?: any): any; +} + +interface ActionFunction { + (done: MochaDone): any | PromiseLike +} + +declare function setup(action: ActionFunction): void; +declare function teardown(action: ActionFunction): void; +declare function suiteSetup(action: ActionFunction): void; +declare function suiteTeardown(action: ActionFunction): void; +declare function before(action: ActionFunction): void; +declare function before(description: string, action: ActionFunction): void; +declare function after(action: ActionFunction): void; +declare function after(description: string, action: ActionFunction): void; +declare function beforeEach(action: ActionFunction): void; +declare function beforeEach(description: string, action: ActionFunction): void; +declare function afterEach(action: ActionFunction): void; +declare function afterEach(description: string, action: ActionFunction): void; + +declare class Mocha { + currentTest: Mocha.ITestDefinition; + constructor(options?: { + grep?: RegExp; + ui?: string; + reporter?: string; + timeout?: number; + bail?: boolean; + }); + + /** Setup mocha with the given options. */ + setup(options: MochaSetupOptions): Mocha; + bail(value?: boolean): Mocha; + addFile(file: string): Mocha; + /** Sets reporter by name, defaults to "spec". */ + reporter(name: string): Mocha; + /** Sets reporter constructor, defaults to mocha.reporters.Spec. */ + reporter(reporter: (runner: Mocha.IRunner, options: any) => any): Mocha; + ui(value: string): Mocha; + grep(value: string): Mocha; + grep(value: RegExp): Mocha; + invert(): Mocha; + ignoreLeaks(value: boolean): Mocha; + checkLeaks(): Mocha; + /** + * Function to allow assertion libraries to throw errors directly into mocha. + * This is useful when running tests in a browser because window.onerror will + * only receive the 'message' attribute of the Error. + */ + throwError(error: Error): void; + /** Enables growl support. */ + growl(): Mocha; + globals(value: string): Mocha; + globals(values: string[]): Mocha; + useColors(value: boolean): Mocha; + useInlineDiffs(value: boolean): Mocha; + timeout(value: number): Mocha; + slow(value: number): Mocha; + enableTimeouts(value: boolean): Mocha; + asyncOnly(value: boolean): Mocha; + noHighlighting(value: boolean): Mocha; + /** Runs tests and invokes `onComplete()` when finished. */ + run(onComplete?: (failures: number) => void): Mocha.IRunner; +} + +// merge the Mocha class declaration with a module +declare namespace Mocha { + /** Partial interface for Mocha's `Runnable` class. */ + interface IRunnable { + title: string; + fn: Function; + async: boolean; + sync: boolean; + timedOut: boolean; + } + + /** Partial interface for Mocha's `Suite` class. */ + interface ISuite { + parent: ISuite; + title: string; + + fullTitle(): string; + } + + /** Partial interface for Mocha's `Test` class. */ + interface ITest extends IRunnable { + parent: ISuite; + pending: boolean; + + fullTitle(): string; + } + + /** Partial interface for Mocha's `Runner` class. */ + interface IRunner {} + + interface IContextDefinition { + (description: string, spec: () => void): ISuite; + only(description: string, spec: () => void): ISuite; + skip(description: string, spec: () => void): void; + timeout(ms: number): void; + } + + interface ITestDefinition { + (expectation: string, assertion?: ActionFunction): ITest; + only(expectation: string, assertion?: ActionFunction): ITest; + skip(expectation: string, assertion?: ActionFunction): void; + timeout(ms: number): void; + state: "failed" | "passed"; + } + + export module reporters { + export class Base { + stats: { + suites: number; + tests: number; + passes: number; + pending: number; + failures: number; + }; + + constructor(runner: IRunner); + } + + export class Doc extends Base {} + export class Dot extends Base {} + export class HTML extends Base {} + export class HTMLCov extends Base {} + export class JSON extends Base {} + export class JSONCov extends Base {} + export class JSONStream extends Base {} + export class Landing extends Base {} + export class List extends Base {} + export class Markdown extends Base {} + export class Min extends Base {} + export class Nyan extends Base {} + export class Progress extends Base { + /** + * @param options.open String used to indicate the start of the progress bar. + * @param options.complete String used to indicate a complete test on the progress bar. + * @param options.incomplete String used to indicate an incomplete test on the progress bar. + * @param options.close String used to indicate the end of the progress bar. + */ + constructor(runner: IRunner, options?: { + open?: string; + complete?: string; + incomplete?: string; + close?: string; + }); + } + export class Spec extends Base {} + export class TAP extends Base {} + export class XUnit extends Base { + constructor(runner: IRunner, options?: any); + } + } +} + +declare module "mocha" { + export = Mocha; +} diff --git a/Tasks/AzureRmWebAppDeploymentV3/typings/globals/mocha/typings.json b/Tasks/AzureRmWebAppDeploymentV3/typings/globals/mocha/typings.json new file mode 100644 index 000000000000..aab9d1c1302c --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/typings/globals/mocha/typings.json @@ -0,0 +1,8 @@ +{ + "resolution": "main", + "tree": { + "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/a361a8ab3c327f208d3f82ad206971d4a63d8c25/mocha/mocha.d.ts", + "raw": "registry:dt/mocha#2.2.5+20160720003353", + "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/a361a8ab3c327f208d3f82ad206971d4a63d8c25/mocha/mocha.d.ts" + } +} diff --git a/Tasks/AzureRmWebAppDeploymentV3/typings/globals/node/index.d.ts b/Tasks/AzureRmWebAppDeploymentV3/typings/globals/node/index.d.ts new file mode 100644 index 000000000000..1dc54b352d88 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/typings/globals/node/index.d.ts @@ -0,0 +1,3350 @@ +// Generated by typings +// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/ab8d917787092fdfb16390f2bee6de8ab5c1783c/node/node.d.ts +interface Error { + stack?: string; +} + +interface ErrorConstructor { + captureStackTrace(targetObject: Object, constructorOpt?: Function): void; + stackTraceLimit: number; +} + +// compat for TypeScript 1.8 +// if you use with --target es3 or --target es5 and use below definitions, +// use the lib.es6.d.ts that is bundled with TypeScript 1.8. +interface MapConstructor { } +interface WeakMapConstructor { } +interface SetConstructor { } +interface WeakSetConstructor { } + +/************************************************ +* * +* GLOBAL * +* * +************************************************/ +declare var process: NodeJS.Process; +declare var global: NodeJS.Global; + +declare var __filename: string; +declare var __dirname: string; + +declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; +declare function clearTimeout(timeoutId: NodeJS.Timer): void; +declare function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; +declare function clearInterval(intervalId: NodeJS.Timer): void; +declare function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; +declare function clearImmediate(immediateId: any): void; + +interface NodeRequireFunction { + (id: string): any; +} + +interface NodeRequire extends NodeRequireFunction { + resolve(id: string): string; + cache: any; + extensions: any; + main: any; +} + +declare var require: NodeRequire; + +interface NodeModule { + exports: any; + require: NodeRequireFunction; + id: string; + filename: string; + loaded: boolean; + parent: any; + children: any[]; +} + +declare var module: NodeModule; + +// Same as module.exports +declare var exports: any; +declare var SlowBuffer: { + new (str: string, encoding?: string): Buffer; + new (size: number): Buffer; + new (size: Uint8Array): Buffer; + new (array: any[]): Buffer; + prototype: Buffer; + isBuffer(obj: any): boolean; + byteLength(string: string, encoding?: string): number; + concat(list: Buffer[], totalLength?: number): Buffer; +}; + + +// Buffer class +type BufferEncoding = "ascii" | "utf8" | "utf16le" | "ucs2" | "binary" | "hex"; +interface Buffer extends NodeBuffer { } + +/** + * Raw data is stored in instances of the Buffer class. + * A Buffer is similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap. A Buffer cannot be resized. + * Valid string encodings: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' + */ +declare var Buffer: { + /** + * Allocates a new buffer containing the given {str}. + * + * @param str String to store in buffer. + * @param encoding encoding to use, optional. Default is 'utf8' + */ + new (str: string, encoding?: string): Buffer; + /** + * Allocates a new buffer of {size} octets. + * + * @param size count of octets to allocate. + */ + new (size: number): Buffer; + /** + * Allocates a new buffer containing the given {array} of octets. + * + * @param array The octets to store. + */ + new (array: Uint8Array): Buffer; + /** + * Produces a Buffer backed by the same allocated memory as + * the given {ArrayBuffer}. + * + * + * @param arrayBuffer The ArrayBuffer with which to share memory. + */ + new (arrayBuffer: ArrayBuffer): Buffer; + /** + * Allocates a new buffer containing the given {array} of octets. + * + * @param array The octets to store. + */ + new (array: any[]): Buffer; + /** + * Copies the passed {buffer} data onto a new {Buffer} instance. + * + * @param buffer The buffer to copy. + */ + new (buffer: Buffer): Buffer; + prototype: Buffer; + /** + * Allocates a new Buffer using an {array} of octets. + * + * @param array + */ + from(array: any[]): Buffer; + /** + * When passed a reference to the .buffer property of a TypedArray instance, + * the newly created Buffer will share the same allocated memory as the TypedArray. + * The optional {byteOffset} and {length} arguments specify a memory range + * within the {arrayBuffer} that will be shared by the Buffer. + * + * @param arrayBuffer The .buffer property of a TypedArray or a new ArrayBuffer() + * @param byteOffset + * @param length + */ + from(arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number): Buffer; + /** + * Copies the passed {buffer} data onto a new Buffer instance. + * + * @param buffer + */ + from(buffer: Buffer): Buffer; + /** + * Creates a new Buffer containing the given JavaScript string {str}. + * If provided, the {encoding} parameter identifies the character encoding. + * If not provided, {encoding} defaults to 'utf8'. + * + * @param str + */ + from(str: string, encoding?: string): Buffer; + /** + * Returns true if {obj} is a Buffer + * + * @param obj object to test. + */ + isBuffer(obj: any): obj is Buffer; + /** + * Returns true if {encoding} is a valid encoding argument. + * Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' + * + * @param encoding string to test. + */ + isEncoding(encoding: string): boolean; + /** + * Gives the actual byte length of a string. encoding defaults to 'utf8'. + * This is not the same as String.prototype.length since that returns the number of characters in a string. + * + * @param string string to test. + * @param encoding encoding used to evaluate (defaults to 'utf8') + */ + byteLength(string: string, encoding?: string): number; + /** + * Returns a buffer which is the result of concatenating all the buffers in the list together. + * + * If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer. + * If the list has exactly one item, then the first item of the list is returned. + * If the list has more than one item, then a new Buffer is created. + * + * @param list An array of Buffer objects to concatenate + * @param totalLength Total length of the buffers when concatenated. + * If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly. + */ + concat(list: Buffer[], totalLength?: number): Buffer; + /** + * The same as buf1.compare(buf2). + */ + compare(buf1: Buffer, buf2: Buffer): number; + /** + * Allocates a new buffer of {size} octets. + * + * @param size count of octets to allocate. + * @param fill if specified, buffer will be initialized by calling buf.fill(fill). + * If parameter is omitted, buffer will be filled with zeros. + * @param encoding encoding used for call to buf.fill while initalizing + */ + alloc(size: number, fill?: string | Buffer | number, encoding?: string): Buffer; + /** + * Allocates a new buffer of {size} octets, leaving memory not initialized, so the contents + * of the newly created Buffer are unknown and may contain sensitive data. + * + * @param size count of octets to allocate + */ + allocUnsafe(size: number): Buffer; + /** + * Allocates a new non-pooled buffer of {size} octets, leaving memory not initialized, so the contents + * of the newly created Buffer are unknown and may contain sensitive data. + * + * @param size count of octets to allocate + */ + allocUnsafeSlow(size: number): Buffer; +}; + +/************************************************ +* * +* GLOBAL INTERFACES * +* * +************************************************/ +declare namespace NodeJS { + export interface ErrnoException extends Error { + errno?: string; + code?: string; + path?: string; + syscall?: string; + stack?: string; + } + + export class EventEmitter { + addListener(event: string|symbol, listener: Function): this; + on(event: string|symbol, listener: Function): this; + once(event: string|symbol, listener: Function): this; + removeListener(event: string|symbol, listener: Function): this; + removeAllListeners(event?: string|symbol): this; + setMaxListeners(n: number): this; + getMaxListeners(): number; + listeners(event: string|symbol): Function[]; + emit(event: string|symbol, ...args: any[]): boolean; + listenerCount(type: string|symbol): number; + // Added in Node 6... + prependListener(event: string|symbol, listener: Function): this; + prependOnceListener(event: string|symbol, listener: Function): this; + eventNames(): (string|symbol)[]; + } + + export interface ReadableStream extends EventEmitter { + readable: boolean; + read(size?: number): string | Buffer; + setEncoding(encoding: string): void; + pause(): ReadableStream; + resume(): ReadableStream; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: string): void; + unshift(chunk: Buffer): void; + wrap(oldStream: ReadableStream): ReadableStream; + } + + export interface WritableStream extends EventEmitter { + writable: boolean; + write(buffer: Buffer | string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + } + + export interface ReadWriteStream extends ReadableStream, WritableStream { + pause(): ReadWriteStream; + resume(): ReadWriteStream; + } + + export interface Events extends EventEmitter { } + + export interface Domain extends Events { + run(fn: Function): void; + add(emitter: Events): void; + remove(emitter: Events): void; + bind(cb: (err: Error, data: any) => any): any; + intercept(cb: (data: any) => any): any; + dispose(): void; + + addListener(event: string, listener: Function): this; + on(event: string, listener: Function): this; + once(event: string, listener: Function): this; + removeListener(event: string, listener: Function): this; + removeAllListeners(event?: string): this; + } + + export interface MemoryUsage { + rss: number; + heapTotal: number; + heapUsed: number; + } + + export interface ProcessVersions { + http_parser: string; + node: string; + v8: string; + ares: string; + uv: string; + zlib: string; + modules: string; + openssl: string; + } + + export interface Process extends EventEmitter { + stdout: WritableStream; + stderr: WritableStream; + stdin: ReadableStream; + argv: string[]; + execArgv: string[]; + execPath: string; + abort(): void; + chdir(directory: string): void; + cwd(): string; + env: any; + exit(code?: number): void; + exitCode: number; + getgid(): number; + setgid(id: number): void; + setgid(id: string): void; + getuid(): number; + setuid(id: number): void; + setuid(id: string): void; + version: string; + versions: ProcessVersions; + config: { + target_defaults: { + cflags: any[]; + default_configuration: string; + defines: string[]; + include_dirs: string[]; + libraries: string[]; + }; + variables: { + clang: number; + host_arch: string; + node_install_npm: boolean; + node_install_waf: boolean; + node_prefix: string; + node_shared_openssl: boolean; + node_shared_v8: boolean; + node_shared_zlib: boolean; + node_use_dtrace: boolean; + node_use_etw: boolean; + node_use_openssl: boolean; + target_arch: string; + v8_no_strict_aliasing: number; + v8_use_snapshot: boolean; + visibility: string; + }; + }; + kill(pid: number, signal?: string | number): void; + pid: number; + title: string; + arch: string; + platform: string; + memoryUsage(): MemoryUsage; + nextTick(callback: Function, ...args: any[]): void; + umask(mask?: number): number; + uptime(): number; + hrtime(time?: number[]): number[]; + domain: Domain; + + // Worker + send?(message: any, sendHandle?: any): void; + disconnect(): void; + connected: boolean; + } + + export interface Global { + Array: typeof Array; + ArrayBuffer: typeof ArrayBuffer; + Boolean: typeof Boolean; + Buffer: typeof Buffer; + DataView: typeof DataView; + Date: typeof Date; + Error: typeof Error; + EvalError: typeof EvalError; + Float32Array: typeof Float32Array; + Float64Array: typeof Float64Array; + Function: typeof Function; + GLOBAL: Global; + Infinity: typeof Infinity; + Int16Array: typeof Int16Array; + Int32Array: typeof Int32Array; + Int8Array: typeof Int8Array; + Intl: typeof Intl; + JSON: typeof JSON; + Map: MapConstructor; + Math: typeof Math; + NaN: typeof NaN; + Number: typeof Number; + Object: typeof Object; + Promise: Function; + RangeError: typeof RangeError; + ReferenceError: typeof ReferenceError; + RegExp: typeof RegExp; + Set: SetConstructor; + String: typeof String; + Symbol: Function; + SyntaxError: typeof SyntaxError; + TypeError: typeof TypeError; + URIError: typeof URIError; + Uint16Array: typeof Uint16Array; + Uint32Array: typeof Uint32Array; + Uint8Array: typeof Uint8Array; + Uint8ClampedArray: Function; + WeakMap: WeakMapConstructor; + WeakSet: WeakSetConstructor; + clearImmediate: (immediateId: any) => void; + clearInterval: (intervalId: NodeJS.Timer) => void; + clearTimeout: (timeoutId: NodeJS.Timer) => void; + console: typeof console; + decodeURI: typeof decodeURI; + decodeURIComponent: typeof decodeURIComponent; + encodeURI: typeof encodeURI; + encodeURIComponent: typeof encodeURIComponent; + escape: (str: string) => string; + eval: typeof eval; + global: Global; + isFinite: typeof isFinite; + isNaN: typeof isNaN; + parseFloat: typeof parseFloat; + parseInt: typeof parseInt; + process: Process; + root: Global; + setImmediate: (callback: (...args: any[]) => void, ...args: any[]) => any; + setInterval: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; + setTimeout: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; + undefined: typeof undefined; + unescape: (str: string) => string; + gc: () => void; + v8debug?: any; + } + + export interface Timer { + ref(): void; + unref(): void; + } +} + +interface IterableIterator { } + +/** + * @deprecated + */ +interface NodeBuffer extends Uint8Array { + write(string: string, offset?: number, length?: number, encoding?: string): number; + toString(encoding?: string, start?: number, end?: number): string; + toJSON(): {type: 'Buffer', data: any[]}; + equals(otherBuffer: Buffer): boolean; + compare(otherBuffer: Buffer, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): number; + copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; + slice(start?: number, end?: number): Buffer; + writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number; + readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number; + readIntLE(offset: number, byteLength: number, noAssert?: boolean): number; + readIntBE(offset: number, byteLength: number, noAssert?: boolean): number; + readUInt8(offset: number, noAssert?: boolean): number; + readUInt16LE(offset: number, noAssert?: boolean): number; + readUInt16BE(offset: number, noAssert?: boolean): number; + readUInt32LE(offset: number, noAssert?: boolean): number; + readUInt32BE(offset: number, noAssert?: boolean): number; + readInt8(offset: number, noAssert?: boolean): number; + readInt16LE(offset: number, noAssert?: boolean): number; + readInt16BE(offset: number, noAssert?: boolean): number; + readInt32LE(offset: number, noAssert?: boolean): number; + readInt32BE(offset: number, noAssert?: boolean): number; + readFloatLE(offset: number, noAssert?: boolean): number; + readFloatBE(offset: number, noAssert?: boolean): number; + readDoubleLE(offset: number, noAssert?: boolean): number; + readDoubleBE(offset: number, noAssert?: boolean): number; + swap16(): Buffer; + swap32(): Buffer; + swap64(): Buffer; + writeUInt8(value: number, offset: number, noAssert?: boolean): number; + writeUInt16LE(value: number, offset: number, noAssert?: boolean): number; + writeUInt16BE(value: number, offset: number, noAssert?: boolean): number; + writeUInt32LE(value: number, offset: number, noAssert?: boolean): number; + writeUInt32BE(value: number, offset: number, noAssert?: boolean): number; + writeInt8(value: number, offset: number, noAssert?: boolean): number; + writeInt16LE(value: number, offset: number, noAssert?: boolean): number; + writeInt16BE(value: number, offset: number, noAssert?: boolean): number; + writeInt32LE(value: number, offset: number, noAssert?: boolean): number; + writeInt32BE(value: number, offset: number, noAssert?: boolean): number; + writeFloatLE(value: number, offset: number, noAssert?: boolean): number; + writeFloatBE(value: number, offset: number, noAssert?: boolean): number; + writeDoubleLE(value: number, offset: number, noAssert?: boolean): number; + writeDoubleBE(value: number, offset: number, noAssert?: boolean): number; + fill(value: any, offset?: number, end?: number): this; + indexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number; + lastIndexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number; + entries(): IterableIterator<[number, number]>; + includes(value: string | number | Buffer, byteOffset?: number, encoding?: string): boolean; + keys(): IterableIterator; + values(): IterableIterator; +} + +/************************************************ +* * +* MODULES * +* * +************************************************/ +declare module "buffer" { + export var INSPECT_MAX_BYTES: number; + var BuffType: typeof Buffer; + var SlowBuffType: typeof SlowBuffer; + export { BuffType as Buffer, SlowBuffType as SlowBuffer }; +} + +declare module "querystring" { + export interface StringifyOptions { + encodeURIComponent?: Function; + } + + export interface ParseOptions { + maxKeys?: number; + decodeURIComponent?: Function; + } + + export function stringify(obj: T, sep?: string, eq?: string, options?: StringifyOptions): string; + export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): any; + export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): T; + export function escape(str: string): string; + export function unescape(str: string): string; +} + +declare module "events" { + export class EventEmitter extends NodeJS.EventEmitter { + static EventEmitter: EventEmitter; + static listenerCount(emitter: EventEmitter, event: string|symbol): number; // deprecated + static defaultMaxListeners: number; + + addListener(event: string|symbol, listener: Function): this; + on(event: string|symbol, listener: Function): this; + once(event: string|symbol, listener: Function): this; + prependListener(event: string|symbol, listener: Function): this; + prependOnceListener(event: string|symbol, listener: Function): this; + removeListener(event: string|symbol, listener: Function): this; + removeAllListeners(event?: string|symbol): this; + setMaxListeners(n: number): this; + getMaxListeners(): number; + listeners(event: string|symbol): Function[]; + emit(event: string|symbol, ...args: any[]): boolean; + eventNames(): (string|symbol)[]; + listenerCount(type: string|symbol): number; + } +} + +declare module "http" { + import * as events from "events"; + import * as net from "net"; + import * as stream from "stream"; + + export interface RequestOptions { + protocol?: string; + host?: string; + hostname?: string; + family?: number; + port?: number; + localAddress?: string; + socketPath?: string; + method?: string; + path?: string; + headers?: { [key: string]: any }; + auth?: string; + agent?: Agent | boolean; + } + + export interface Server extends net.Server { + setTimeout(msecs: number, callback: Function): void; + maxHeadersCount: number; + timeout: number; + listening: boolean; + } + /** + * @deprecated Use IncomingMessage + */ + export interface ServerRequest extends IncomingMessage { + connection: net.Socket; + } + export interface ServerResponse extends stream.Writable { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + writeContinue(): void; + writeHead(statusCode: number, reasonPhrase?: string, headers?: any): void; + writeHead(statusCode: number, headers?: any): void; + statusCode: number; + statusMessage: string; + headersSent: boolean; + setHeader(name: string, value: string | string[]): void; + setTimeout(msecs: number, callback: Function): ServerResponse; + sendDate: boolean; + getHeader(name: string): string; + removeHeader(name: string): void; + write(chunk: any, encoding?: string): any; + addTrailers(headers: any): void; + finished: boolean; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + export interface ClientRequest extends stream.Writable { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + write(chunk: any, encoding?: string): void; + abort(): void; + setTimeout(timeout: number, callback?: Function): void; + setNoDelay(noDelay?: boolean): void; + setSocketKeepAlive(enable?: boolean, initialDelay?: number): void; + + setHeader(name: string, value: string | string[]): void; + getHeader(name: string): string; + removeHeader(name: string): void; + addTrailers(headers: any): void; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + export interface IncomingMessage extends stream.Readable { + httpVersion: string; + httpVersionMajor: string; + httpVersionMinor: string; + connection: net.Socket; + headers: any; + rawHeaders: string[]; + trailers: any; + rawTrailers: any; + setTimeout(msecs: number, callback: Function): NodeJS.Timer; + /** + * Only valid for request obtained from http.Server. + */ + method?: string; + /** + * Only valid for request obtained from http.Server. + */ + url?: string; + /** + * Only valid for response obtained from http.ClientRequest. + */ + statusCode?: number; + /** + * Only valid for response obtained from http.ClientRequest. + */ + statusMessage?: string; + socket: net.Socket; + destroy(error?: Error): void; + } + /** + * @deprecated Use IncomingMessage + */ + export interface ClientResponse extends IncomingMessage { } + + export interface AgentOptions { + /** + * Keep sockets around in a pool to be used by other requests in the future. Default = false + */ + keepAlive?: boolean; + /** + * When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = 1000. + * Only relevant if keepAlive is set to true. + */ + keepAliveMsecs?: number; + /** + * Maximum number of sockets to allow per host. Default for Node 0.10 is 5, default for Node 0.12 is Infinity + */ + maxSockets?: number; + /** + * Maximum number of sockets to leave open in a free state. Only relevant if keepAlive is set to true. Default = 256. + */ + maxFreeSockets?: number; + } + + export class Agent { + maxSockets: number; + sockets: any; + requests: any; + + constructor(opts?: AgentOptions); + + /** + * Destroy any sockets that are currently in use by the agent. + * It is usually not necessary to do this. However, if you are using an agent with KeepAlive enabled, + * then it is best to explicitly shut down the agent when you know that it will no longer be used. Otherwise, + * sockets may hang open for quite a long time before the server terminates them. + */ + destroy(): void; + } + + export var METHODS: string[]; + + export var STATUS_CODES: { + [errorCode: number]: string; + [errorCode: string]: string; + }; + export function createServer(requestListener?: (request: IncomingMessage, response: ServerResponse) => void): Server; + export function createClient(port?: number, host?: string): any; + export function request(options: RequestOptions, callback?: (res: IncomingMessage) => void): ClientRequest; + export function get(options: any, callback?: (res: IncomingMessage) => void): ClientRequest; + export var globalAgent: Agent; +} + +declare module "cluster" { + import * as child from "child_process"; + import * as events from "events"; + import * as net from "net"; + + // interfaces + export interface ClusterSettings { + execArgv?: string[]; // default: process.execArgv + exec?: string; + args?: string[]; + silent?: boolean; + stdio?: any[]; + uid?: number; + gid?: number; + } + + export interface ClusterSetupMasterSettings { + exec?: string; // default: process.argv[1] + args?: string[]; // default: process.argv.slice(2) + silent?: boolean; // default: false + stdio?: any[]; + } + + export interface Address { + address: string; + port: number; + addressType: number | "udp4" | "udp6"; // 4, 6, -1, "udp4", "udp6" + } + + export class Worker extends events.EventEmitter { + id: string; + process: child.ChildProcess; + suicide: boolean; + send(message: any, sendHandle?: any): boolean; + kill(signal?: string): void; + destroy(signal?: string): void; + disconnect(): void; + isConnected(): boolean; + isDead(): boolean; + exitedAfterDisconnect: boolean; + + /** + * events.EventEmitter + * 1. disconnect + * 2. error + * 3. exit + * 4. listening + * 5. message + * 6. online + */ + addListener(event: string, listener: Function): this; + addListener(event: "disconnect", listener: () => void): this; + addListener(event: "error", listener: (code: number, signal: string) => void): this; + addListener(event: "exit", listener: (code: number, signal: string) => void): this; + addListener(event: "listening", listener: (address: Address) => void): this; + addListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + addListener(event: "online", listener: () => void): this; + + on(event: string, listener: Function): this; + on(event: "disconnect", listener: () => void): this; + on(event: "error", listener: (code: number, signal: string) => void): this; + on(event: "exit", listener: (code: number, signal: string) => void): this; + on(event: "listening", listener: (address: Address) => void): this; + on(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + on(event: "online", listener: () => void): this; + + once(event: string, listener: Function): this; + once(event: "disconnect", listener: () => void): this; + once(event: "error", listener: (code: number, signal: string) => void): this; + once(event: "exit", listener: (code: number, signal: string) => void): this; + once(event: "listening", listener: (address: Address) => void): this; + once(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + once(event: "online", listener: () => void): this; + + prependListener(event: string, listener: Function): this; + prependListener(event: "disconnect", listener: () => void): this; + prependListener(event: "error", listener: (code: number, signal: string) => void): this; + prependListener(event: "exit", listener: (code: number, signal: string) => void): this; + prependListener(event: "listening", listener: (address: Address) => void): this; + prependListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + prependListener(event: "online", listener: () => void): this; + + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "disconnect", listener: () => void): this; + prependOnceListener(event: "error", listener: (code: number, signal: string) => void): this; + prependOnceListener(event: "exit", listener: (code: number, signal: string) => void): this; + prependOnceListener(event: "listening", listener: (address: Address) => void): this; + prependOnceListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + prependOnceListener(event: "online", listener: () => void): this; + } + + export interface Cluster extends events.EventEmitter { + Worker: Worker; + disconnect(callback?: Function): void; + fork(env?: any): Worker; + isMaster: boolean; + isWorker: boolean; + // TODO: cluster.schedulingPolicy + settings: ClusterSettings; + setupMaster(settings?: ClusterSetupMasterSettings): void; + worker: Worker; + workers: { + [index: string]: Worker + }; + + /** + * events.EventEmitter + * 1. disconnect + * 2. exit + * 3. fork + * 4. listening + * 5. message + * 6. online + * 7. setup + */ + addListener(event: string, listener: Function): this; + addListener(event: "disconnect", listener: (worker: Worker) => void): this; + addListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; + addListener(event: "fork", listener: (worker: Worker) => void): this; + addListener(event: "listening", listener: (worker: Worker, address: Address) => void): this; + addListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + addListener(event: "online", listener: (worker: Worker) => void): this; + addListener(event: "setup", listener: (settings: any) => void): this; + + on(event: string, listener: Function): this; + on(event: "disconnect", listener: (worker: Worker) => void): this; + on(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; + on(event: "fork", listener: (worker: Worker) => void): this; + on(event: "listening", listener: (worker: Worker, address: Address) => void): this; + on(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + on(event: "online", listener: (worker: Worker) => void): this; + on(event: "setup", listener: (settings: any) => void): this; + + once(event: string, listener: Function): this; + once(event: "disconnect", listener: (worker: Worker) => void): this; + once(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; + once(event: "fork", listener: (worker: Worker) => void): this; + once(event: "listening", listener: (worker: Worker, address: Address) => void): this; + once(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + once(event: "online", listener: (worker: Worker) => void): this; + once(event: "setup", listener: (settings: any) => void): this; + + prependListener(event: string, listener: Function): this; + prependListener(event: "disconnect", listener: (worker: Worker) => void): this; + prependListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; + prependListener(event: "fork", listener: (worker: Worker) => void): this; + prependListener(event: "listening", listener: (worker: Worker, address: Address) => void): this; + prependListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + prependListener(event: "online", listener: (worker: Worker) => void): this; + prependListener(event: "setup", listener: (settings: any) => void): this; + + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "disconnect", listener: (worker: Worker) => void): this; + prependOnceListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this; + prependOnceListener(event: "fork", listener: (worker: Worker) => void): this; + prependOnceListener(event: "listening", listener: (worker: Worker, address: Address) => void): this; + prependOnceListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined. + prependOnceListener(event: "online", listener: (worker: Worker) => void): this; + prependOnceListener(event: "setup", listener: (settings: any) => void): this; + + } + + export function disconnect(callback ?: Function): void; + export function fork(env?: any): Worker; + export var isMaster: boolean; + export var isWorker: boolean; + // TODO: cluster.schedulingPolicy + export var settings: ClusterSettings; + export function setupMaster(settings?: ClusterSetupMasterSettings): void; + export var worker: Worker; + export var workers: { + [index: string]: Worker + }; + + /** + * events.EventEmitter + * 1. disconnect + * 2. exit + * 3. fork + * 4. listening + * 5. message + * 6. online + * 7. setup + */ + export function addListener(event: string, listener: Function): Cluster; + export function addListener(event: "disconnect", listener: (worker: Worker) => void): Cluster; + export function addListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; + export function addListener(event: "fork", listener: (worker: Worker) => void): Cluster; + export function addListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; + export function addListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. + export function addListener(event: "online", listener: (worker: Worker) => void): Cluster; + export function addListener(event: "setup", listener: (settings: any) => void): Cluster; + + export function on(event: string, listener: Function): Cluster; + export function on(event: "disconnect", listener: (worker: Worker) => void): Cluster; + export function on(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; + export function on(event: "fork", listener: (worker: Worker) => void): Cluster; + export function on(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; + export function on(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. + export function on(event: "online", listener: (worker: Worker) => void): Cluster; + export function on(event: "setup", listener: (settings: any) => void): Cluster; + + export function once(event: string, listener: Function): Cluster; + export function once(event: "disconnect", listener: (worker: Worker) => void): Cluster; + export function once(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; + export function once(event: "fork", listener: (worker: Worker) => void): Cluster; + export function once(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; + export function once(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. + export function once(event: "online", listener: (worker: Worker) => void): Cluster; + export function once(event: "setup", listener: (settings: any) => void): Cluster; + + export function removeListener(event: string, listener: Function): Cluster; + export function removeAllListeners(event?: string): Cluster; + export function setMaxListeners(n: number): Cluster; + export function getMaxListeners(): number; + export function listeners(event: string): Function[]; + export function emit(event: string, ...args: any[]): boolean; + export function listenerCount(type: string): number; + + export function prependListener(event: string, listener: Function): Cluster; + export function prependListener(event: "disconnect", listener: (worker: Worker) => void): Cluster; + export function prependListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; + export function prependListener(event: "fork", listener: (worker: Worker) => void): Cluster; + export function prependListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; + export function prependListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. + export function prependListener(event: "online", listener: (worker: Worker) => void): Cluster; + export function prependListener(event: "setup", listener: (settings: any) => void): Cluster; + + export function prependOnceListener(event: string, listener: Function): Cluster; + export function prependOnceListener(event: "disconnect", listener: (worker: Worker) => void): Cluster; + export function prependOnceListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): Cluster; + export function prependOnceListener(event: "fork", listener: (worker: Worker) => void): Cluster; + export function prependOnceListener(event: "listening", listener: (worker: Worker, address: Address) => void): Cluster; + export function prependOnceListener(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): Cluster; // the handle is a net.Socket or net.Server object, or undefined. + export function prependOnceListener(event: "online", listener: (worker: Worker) => void): Cluster; + export function prependOnceListener(event: "setup", listener: (settings: any) => void): Cluster; + + export function eventNames(): string[]; +} + +declare module "zlib" { + import * as stream from "stream"; + export interface ZlibOptions { chunkSize?: number; windowBits?: number; level?: number; memLevel?: number; strategy?: number; dictionary?: any; } + + export interface Gzip extends stream.Transform { } + export interface Gunzip extends stream.Transform { } + export interface Deflate extends stream.Transform { } + export interface Inflate extends stream.Transform { } + export interface DeflateRaw extends stream.Transform { } + export interface InflateRaw extends stream.Transform { } + export interface Unzip extends stream.Transform { } + + export function createGzip(options?: ZlibOptions): Gzip; + export function createGunzip(options?: ZlibOptions): Gunzip; + export function createDeflate(options?: ZlibOptions): Deflate; + export function createInflate(options?: ZlibOptions): Inflate; + export function createDeflateRaw(options?: ZlibOptions): DeflateRaw; + export function createInflateRaw(options?: ZlibOptions): InflateRaw; + export function createUnzip(options?: ZlibOptions): Unzip; + + export function deflate(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function deflateSync(buf: Buffer, options?: ZlibOptions): any; + export function deflateRaw(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function deflateRawSync(buf: Buffer, options?: ZlibOptions): any; + export function gzip(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function gzipSync(buf: Buffer, options?: ZlibOptions): any; + export function gunzip(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function gunzipSync(buf: Buffer, options?: ZlibOptions): any; + export function inflate(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function inflateSync(buf: Buffer, options?: ZlibOptions): any; + export function inflateRaw(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function inflateRawSync(buf: Buffer, options?: ZlibOptions): any; + export function unzip(buf: Buffer, callback: (error: Error, result: any) => void): void; + export function unzipSync(buf: Buffer, options?: ZlibOptions): any; + + // Constants + export var Z_NO_FLUSH: number; + export var Z_PARTIAL_FLUSH: number; + export var Z_SYNC_FLUSH: number; + export var Z_FULL_FLUSH: number; + export var Z_FINISH: number; + export var Z_BLOCK: number; + export var Z_TREES: number; + export var Z_OK: number; + export var Z_STREAM_END: number; + export var Z_NEED_DICT: number; + export var Z_ERRNO: number; + export var Z_STREAM_ERROR: number; + export var Z_DATA_ERROR: number; + export var Z_MEM_ERROR: number; + export var Z_BUF_ERROR: number; + export var Z_VERSION_ERROR: number; + export var Z_NO_COMPRESSION: number; + export var Z_BEST_SPEED: number; + export var Z_BEST_COMPRESSION: number; + export var Z_DEFAULT_COMPRESSION: number; + export var Z_FILTERED: number; + export var Z_HUFFMAN_ONLY: number; + export var Z_RLE: number; + export var Z_FIXED: number; + export var Z_DEFAULT_STRATEGY: number; + export var Z_BINARY: number; + export var Z_TEXT: number; + export var Z_ASCII: number; + export var Z_UNKNOWN: number; + export var Z_DEFLATED: number; + export var Z_NULL: number; +} + +declare module "os" { + export interface CpuInfo { + model: string; + speed: number; + times: { + user: number; + nice: number; + sys: number; + idle: number; + irq: number; + }; + } + + export interface NetworkInterfaceInfo { + address: string; + netmask: string; + family: string; + mac: string; + internal: boolean; + } + + export function hostname(): string; + export function loadavg(): number[]; + export function uptime(): number; + export function freemem(): number; + export function totalmem(): number; + export function cpus(): CpuInfo[]; + export function type(): string; + export function release(): string; + export function networkInterfaces(): { [index: string]: NetworkInterfaceInfo[] }; + export function homedir(): string; + export function userInfo(options?: { encoding: string }): { username: string, uid: number, gid: number, shell: any, homedir: string } + export var constants: { + UV_UDP_REUSEADDR: number, + errno: { + SIGHUP: number; + SIGINT: number; + SIGQUIT: number; + SIGILL: number; + SIGTRAP: number; + SIGABRT: number; + SIGIOT: number; + SIGBUS: number; + SIGFPE: number; + SIGKILL: number; + SIGUSR1: number; + SIGSEGV: number; + SIGUSR2: number; + SIGPIPE: number; + SIGALRM: number; + SIGTERM: number; + SIGCHLD: number; + SIGSTKFLT: number; + SIGCONT: number; + SIGSTOP: number; + SIGTSTP: number; + SIGTTIN: number; + SIGTTOU: number; + SIGURG: number; + SIGXCPU: number; + SIGXFSZ: number; + SIGVTALRM: number; + SIGPROF: number; + SIGWINCH: number; + SIGIO: number; + SIGPOLL: number; + SIGPWR: number; + SIGSYS: number; + SIGUNUSED: number; + }, + signals: { + E2BIG: number; + EACCES: number; + EADDRINUSE: number; + EADDRNOTAVAIL: number; + EAFNOSUPPORT: number; + EAGAIN: number; + EALREADY: number; + EBADF: number; + EBADMSG: number; + EBUSY: number; + ECANCELED: number; + ECHILD: number; + ECONNABORTED: number; + ECONNREFUSED: number; + ECONNRESET: number; + EDEADLK: number; + EDESTADDRREQ: number; + EDOM: number; + EDQUOT: number; + EEXIST: number; + EFAULT: number; + EFBIG: number; + EHOSTUNREACH: number; + EIDRM: number; + EILSEQ: number; + EINPROGRESS: number; + EINTR: number; + EINVAL: number; + EIO: number; + EISCONN: number; + EISDIR: number; + ELOOP: number; + EMFILE: number; + EMLINK: number; + EMSGSIZE: number; + EMULTIHOP: number; + ENAMETOOLONG: number; + ENETDOWN: number; + ENETRESET: number; + ENETUNREACH: number; + ENFILE: number; + ENOBUFS: number; + ENODATA: number; + ENODEV: number; + ENOENT: number; + ENOEXEC: number; + ENOLCK: number; + ENOLINK: number; + ENOMEM: number; + ENOMSG: number; + ENOPROTOOPT: number; + ENOSPC: number; + ENOSR: number; + ENOSTR: number; + ENOSYS: number; + ENOTCONN: number; + ENOTDIR: number; + ENOTEMPTY: number; + ENOTSOCK: number; + ENOTSUP: number; + ENOTTY: number; + ENXIO: number; + EOPNOTSUPP: number; + EOVERFLOW: number; + EPERM: number; + EPIPE: number; + EPROTO: number; + EPROTONOSUPPORT: number; + EPROTOTYPE: number; + ERANGE: number; + EROFS: number; + ESPIPE: number; + ESRCH: number; + ESTALE: number; + ETIME: number; + ETIMEDOUT: number; + ETXTBSY: number; + EWOULDBLOCK: number; + EXDEV: number; + }, + }; + export function arch(): string; + export function platform(): string; + export function tmpdir(): string; + export var EOL: string; + export function endianness(): "BE" | "LE"; +} + +declare module "https" { + import * as tls from "tls"; + import * as events from "events"; + import * as http from "http"; + + export interface ServerOptions { + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + crl?: any; + ciphers?: string; + honorCipherOrder?: boolean; + requestCert?: boolean; + rejectUnauthorized?: boolean; + NPNProtocols?: any; + SNICallback?: (servername: string, cb: (err: Error, ctx: tls.SecureContext) => any) => any; + } + + export interface RequestOptions extends http.RequestOptions { + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + ciphers?: string; + rejectUnauthorized?: boolean; + secureProtocol?: string; + } + + export interface Agent extends http.Agent { } + + export interface AgentOptions extends http.AgentOptions { + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + ciphers?: string; + rejectUnauthorized?: boolean; + secureProtocol?: string; + maxCachedSessions?: number; + } + + export var Agent: { + new (options?: AgentOptions): Agent; + }; + export interface Server extends tls.Server { } + export function createServer(options: ServerOptions, requestListener?: Function): Server; + export function request(options: RequestOptions, callback?: (res: http.IncomingMessage) => void): http.ClientRequest; + export function get(options: RequestOptions, callback?: (res: http.IncomingMessage) => void): http.ClientRequest; + export var globalAgent: Agent; +} + +declare module "punycode" { + export function decode(string: string): string; + export function encode(string: string): string; + export function toUnicode(domain: string): string; + export function toASCII(domain: string): string; + export var ucs2: ucs2; + interface ucs2 { + decode(string: string): number[]; + encode(codePoints: number[]): string; + } + export var version: any; +} + +declare module "repl" { + import * as stream from "stream"; + import * as readline from "readline"; + + export interface ReplOptions { + prompt?: string; + input?: NodeJS.ReadableStream; + output?: NodeJS.WritableStream; + terminal?: boolean; + eval?: Function; + useColors?: boolean; + useGlobal?: boolean; + ignoreUndefined?: boolean; + writer?: Function; + completer?: Function; + replMode?: any; + breakEvalOnSigint?: any; + } + + export interface REPLServer extends readline.ReadLine { + defineCommand(keyword: string, cmd: Function | { help: string, action: Function }): void; + displayPrompt(preserveCursor?: boolean): void + } + + export function start(options: ReplOptions): REPLServer; +} + +declare module "readline" { + import * as events from "events"; + import * as stream from "stream"; + + export interface Key { + sequence?: string; + name?: string; + ctrl?: boolean; + meta?: boolean; + shift?: boolean; + } + + export interface ReadLine extends events.EventEmitter { + setPrompt(prompt: string): void; + prompt(preserveCursor?: boolean): void; + question(query: string, callback: (answer: string) => void): void; + pause(): ReadLine; + resume(): ReadLine; + close(): void; + write(data: string | Buffer, key?: Key): void; + } + + export interface Completer { + (line: string): CompleterResult; + (line: string, callback: (err: any, result: CompleterResult) => void): any; + } + + export interface CompleterResult { + completions: string[]; + line: string; + } + + export interface ReadLineOptions { + input: NodeJS.ReadableStream; + output?: NodeJS.WritableStream; + completer?: Completer; + terminal?: boolean; + historySize?: number; + } + + export function createInterface(input: NodeJS.ReadableStream, output?: NodeJS.WritableStream, completer?: Completer, terminal?: boolean): ReadLine; + export function createInterface(options: ReadLineOptions): ReadLine; + + export function cursorTo(stream: NodeJS.WritableStream, x: number, y: number): void; + export function moveCursor(stream: NodeJS.WritableStream, dx: number | string, dy: number | string): void; + export function clearLine(stream: NodeJS.WritableStream, dir: number): void; + export function clearScreenDown(stream: NodeJS.WritableStream): void; +} + +declare module "vm" { + export interface Context { } + export interface ScriptOptions { + filename?: string; + lineOffset?: number; + columnOffset?: number; + displayErrors?: boolean; + timeout?: number; + cachedData?: Buffer; + produceCachedData?: boolean; + } + export interface RunningScriptOptions { + filename?: string; + lineOffset?: number; + columnOffset?: number; + displayErrors?: boolean; + timeout?: number; + } + export class Script { + constructor(code: string, options?: ScriptOptions); + runInContext(contextifiedSandbox: Context, options?: RunningScriptOptions): any; + runInNewContext(sandbox?: Context, options?: RunningScriptOptions): any; + runInThisContext(options?: RunningScriptOptions): any; + } + export function createContext(sandbox?: Context): Context; + export function isContext(sandbox: Context): boolean; + export function runInContext(code: string, contextifiedSandbox: Context, options?: RunningScriptOptions): any; + export function runInDebugContext(code: string): any; + export function runInNewContext(code: string, sandbox?: Context, options?: RunningScriptOptions): any; + export function runInThisContext(code: string, options?: RunningScriptOptions): any; +} + +declare module "child_process" { + import * as events from "events"; + import * as stream from "stream"; + + export interface ChildProcess extends events.EventEmitter { + stdin: stream.Writable; + stdout: stream.Readable; + stderr: stream.Readable; + stdio: [stream.Writable, stream.Readable, stream.Readable]; + pid: number; + kill(signal?: string): void; + send(message: any, sendHandle?: any): boolean; + connected: boolean; + disconnect(): void; + unref(): void; + ref(): void; + } + + export interface SpawnOptions { + cwd?: string; + env?: any; + stdio?: any; + detached?: boolean; + uid?: number; + gid?: number; + shell?: boolean | string; + } + export function spawn(command: string, args?: string[], options?: SpawnOptions): ChildProcess; + + export interface ExecOptions { + cwd?: string; + env?: any; + shell?: string; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + uid?: number; + gid?: number; + } + export interface ExecOptionsWithStringEncoding extends ExecOptions { + encoding: BufferEncoding; + } + export interface ExecOptionsWithBufferEncoding extends ExecOptions { + encoding: string; // specify `null`. + } + export function exec(command: string, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + export function exec(command: string, options: ExecOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + // usage. child_process.exec("tsc", {encoding: null as string}, (err, stdout, stderr) => {}); + export function exec(command: string, options: ExecOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) => void): ChildProcess; + export function exec(command: string, options: ExecOptions, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + + export interface ExecFileOptions { + cwd?: string; + env?: any; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + uid?: number; + gid?: number; + } + export interface ExecFileOptionsWithStringEncoding extends ExecFileOptions { + encoding: BufferEncoding; + } + export interface ExecFileOptionsWithBufferEncoding extends ExecFileOptions { + encoding: string; // specify `null`. + } + export function execFile(file: string, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + export function execFile(file: string, options?: ExecFileOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + // usage. child_process.execFile("file.sh", {encoding: null as string}, (err, stdout, stderr) => {}); + export function execFile(file: string, options?: ExecFileOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) => void): ChildProcess; + export function execFile(file: string, options?: ExecFileOptions, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + export function execFile(file: string, args?: string[], callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + export function execFile(file: string, args?: string[], options?: ExecFileOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + // usage. child_process.execFile("file.sh", ["foo"], {encoding: null as string}, (err, stdout, stderr) => {}); + export function execFile(file: string, args?: string[], options?: ExecFileOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) => void): ChildProcess; + export function execFile(file: string, args?: string[], options?: ExecFileOptions, callback?: (error: Error, stdout: string, stderr: string) => void): ChildProcess; + + export interface ForkOptions { + cwd?: string; + env?: any; + execPath?: string; + execArgv?: string[]; + silent?: boolean; + uid?: number; + gid?: number; + } + export function fork(modulePath: string, args?: string[], options?: ForkOptions): ChildProcess; + + export interface SpawnSyncOptions { + cwd?: string; + input?: string | Buffer; + stdio?: any; + env?: any; + uid?: number; + gid?: number; + timeout?: number; + killSignal?: string; + maxBuffer?: number; + encoding?: string; + shell?: boolean | string; + } + export interface SpawnSyncOptionsWithStringEncoding extends SpawnSyncOptions { + encoding: BufferEncoding; + } + export interface SpawnSyncOptionsWithBufferEncoding extends SpawnSyncOptions { + encoding: string; // specify `null`. + } + export interface SpawnSyncReturns { + pid: number; + output: string[]; + stdout: T; + stderr: T; + status: number; + signal: string; + error: Error; + } + export function spawnSync(command: string): SpawnSyncReturns; + export function spawnSync(command: string, options?: SpawnSyncOptionsWithStringEncoding): SpawnSyncReturns; + export function spawnSync(command: string, options?: SpawnSyncOptionsWithBufferEncoding): SpawnSyncReturns; + export function spawnSync(command: string, options?: SpawnSyncOptions): SpawnSyncReturns; + export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptionsWithStringEncoding): SpawnSyncReturns; + export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptionsWithBufferEncoding): SpawnSyncReturns; + export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptions): SpawnSyncReturns; + + export interface ExecSyncOptions { + cwd?: string; + input?: string | Buffer; + stdio?: any; + env?: any; + shell?: string; + uid?: number; + gid?: number; + timeout?: number; + killSignal?: string; + maxBuffer?: number; + encoding?: string; + } + export interface ExecSyncOptionsWithStringEncoding extends ExecSyncOptions { + encoding: BufferEncoding; + } + export interface ExecSyncOptionsWithBufferEncoding extends ExecSyncOptions { + encoding: string; // specify `null`. + } + export function execSync(command: string): Buffer; + export function execSync(command: string, options?: ExecSyncOptionsWithStringEncoding): string; + export function execSync(command: string, options?: ExecSyncOptionsWithBufferEncoding): Buffer; + export function execSync(command: string, options?: ExecSyncOptions): Buffer; + + export interface ExecFileSyncOptions { + cwd?: string; + input?: string | Buffer; + stdio?: any; + env?: any; + uid?: number; + gid?: number; + timeout?: number; + killSignal?: string; + maxBuffer?: number; + encoding?: string; + } + export interface ExecFileSyncOptionsWithStringEncoding extends ExecFileSyncOptions { + encoding: BufferEncoding; + } + export interface ExecFileSyncOptionsWithBufferEncoding extends ExecFileSyncOptions { + encoding: string; // specify `null`. + } + export function execFileSync(command: string): Buffer; + export function execFileSync(command: string, options?: ExecFileSyncOptionsWithStringEncoding): string; + export function execFileSync(command: string, options?: ExecFileSyncOptionsWithBufferEncoding): Buffer; + export function execFileSync(command: string, options?: ExecFileSyncOptions): Buffer; + export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptionsWithStringEncoding): string; + export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptionsWithBufferEncoding): Buffer; + export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptions): Buffer; +} + +declare module "url" { + export interface Url { + href?: string; + protocol?: string; + auth?: string; + hostname?: string; + port?: string; + host?: string; + pathname?: string; + search?: string; + query?: string | any; + slashes?: boolean; + hash?: string; + path?: string; + } + + export function parse(urlStr: string, parseQueryString?: boolean, slashesDenoteHost?: boolean): Url; + export function format(url: Url): string; + export function resolve(from: string, to: string): string; +} + +declare module "dns" { + export interface MxRecord { + exchange: string, + priority: number + } + + export function lookup(domain: string, family: number, callback: (err: Error, address: string, family: number) => void): string; + export function lookup(domain: string, callback: (err: Error, address: string, family: number) => void): string; + export function resolve(domain: string, rrtype: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolve(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolve4(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolve6(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolveMx(domain: string, callback: (err: Error, addresses: MxRecord[]) =>void ): string[]; + export function resolveTxt(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolveSrv(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolveNs(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function resolveCname(domain: string, callback: (err: Error, addresses: string[]) => void): string[]; + export function reverse(ip: string, callback: (err: Error, domains: string[]) => void): string[]; + export function setServers(servers: string[]): void; + + //Error codes + export var NODATA: string; + export var FORMERR: string; + export var SERVFAIL: string; + export var NOTFOUND: string; + export var NOTIMP: string; + export var REFUSED: string; + export var BADQUERY: string; + export var BADNAME: string; + export var BADFAMILY: string; + export var BADRESP: string; + export var CONNREFUSED: string; + export var TIMEOUT: string; + export var EOF: string; + export var FILE: string; + export var NOMEM: string; + export var DESTRUCTION: string; + export var BADSTR: string; + export var BADFLAGS: string; + export var NONAME: string; + export var BADHINTS: string; + export var NOTINITIALIZED: string; + export var LOADIPHLPAPI: string; + export var ADDRGETNETWORKPARAMS: string; + export var CANCELLED: string; +} + +declare module "net" { + import * as stream from "stream"; + + export interface Socket extends stream.Duplex { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + connect(port: number, host?: string, connectionListener?: Function): void; + connect(path: string, connectionListener?: Function): void; + bufferSize: number; + setEncoding(encoding?: string): void; + write(data: any, encoding?: string, callback?: Function): void; + destroy(): void; + pause(): Socket; + resume(): Socket; + setTimeout(timeout: number, callback?: Function): void; + setNoDelay(noDelay?: boolean): void; + setKeepAlive(enable?: boolean, initialDelay?: number): void; + address(): { port: number; family: string; address: string; }; + unref(): void; + ref(): void; + + remoteAddress: string; + remoteFamily: string; + remotePort: number; + localAddress: string; + localPort: number; + bytesRead: number; + bytesWritten: number; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + + export var Socket: { + new (options?: { fd?: string; type?: string; allowHalfOpen?: boolean; }): Socket; + }; + + export interface ListenOptions { + port?: number; + host?: string; + backlog?: number; + path?: string; + exclusive?: boolean; + } + + export interface Server extends Socket { + listen(port: number, hostname?: string, backlog?: number, listeningListener?: Function): Server; + listen(port: number, hostname?: string, listeningListener?: Function): Server; + listen(port: number, backlog?: number, listeningListener?: Function): Server; + listen(port: number, listeningListener?: Function): Server; + listen(path: string, backlog?: number, listeningListener?: Function): Server; + listen(path: string, listeningListener?: Function): Server; + listen(handle: any, backlog?: number, listeningListener?: Function): Server; + listen(handle: any, listeningListener?: Function): Server; + listen(options: ListenOptions, listeningListener?: Function): Server; + close(callback?: Function): Server; + address(): { port: number; family: string; address: string; }; + getConnections(cb: (error: Error, count: number) => void): void; + ref(): Server; + unref(): Server; + maxConnections: number; + connections: number; + } + export function createServer(connectionListener?: (socket: Socket) => void): Server; + export function createServer(options?: { allowHalfOpen?: boolean; }, connectionListener?: (socket: Socket) => void): Server; + export function connect(options: { port: number, host?: string, localAddress?: string, localPort?: string, family?: number, allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; + export function connect(port: number, host?: string, connectionListener?: Function): Socket; + export function connect(path: string, connectionListener?: Function): Socket; + export function createConnection(options: { port: number, host?: string, localAddress?: string, localPort?: string, family?: number, allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; + export function createConnection(port: number, host?: string, connectionListener?: Function): Socket; + export function createConnection(path: string, connectionListener?: Function): Socket; + export function isIP(input: string): number; + export function isIPv4(input: string): boolean; + export function isIPv6(input: string): boolean; +} + +declare module "dgram" { + import * as events from "events"; + + interface RemoteInfo { + address: string; + port: number; + size: number; + } + + interface AddressInfo { + address: string; + family: string; + port: number; + } + + interface BindOptions { + port: number; + address?: string; + exclusive?: boolean; + } + + interface SocketOptions { + type: "udp4" | "udp6"; + reuseAddr?: boolean; + } + + export function createSocket(type: string, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket; + export function createSocket(options: SocketOptions, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket; + + export interface Socket extends events.EventEmitter { + send(msg: Buffer | String | any[], port: number, address: string, callback?: (error: Error, bytes: number) => void): void; + send(msg: Buffer | String | any[], offset: number, length: number, port: number, address: string, callback?: (error: Error, bytes: number) => void): void; + bind(port?: number, address?: string, callback?: () => void): void; + bind(options: BindOptions, callback?: Function): void; + close(callback?: any): void; + address(): AddressInfo; + setBroadcast(flag: boolean): void; + setTTL(ttl: number): void; + setMulticastTTL(ttl: number): void; + setMulticastLoopback(flag: boolean): void; + addMembership(multicastAddress: string, multicastInterface?: string): void; + dropMembership(multicastAddress: string, multicastInterface?: string): void; + ref(): void; + unref(): void; + } +} + +declare module "fs" { + import * as stream from "stream"; + import * as events from "events"; + + interface Stats { + isFile(): boolean; + isDirectory(): boolean; + isBlockDevice(): boolean; + isCharacterDevice(): boolean; + isSymbolicLink(): boolean; + isFIFO(): boolean; + isSocket(): boolean; + dev: number; + ino: number; + mode: number; + nlink: number; + uid: number; + gid: number; + rdev: number; + size: number; + blksize: number; + blocks: number; + atime: Date; + mtime: Date; + ctime: Date; + birthtime: Date; + } + + interface FSWatcher extends events.EventEmitter { + close(): void; + + /** + * events.EventEmitter + * 1. change + * 2. error + */ + addListener(event: string, listener: Function): this; + addListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; + addListener(event: "error", listener: (code: number, signal: string) => void): this; + + on(event: string, listener: Function): this; + on(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; + on(event: "error", listener: (code: number, signal: string) => void): this; + + once(event: string, listener: Function): this; + once(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; + once(event: "error", listener: (code: number, signal: string) => void): this; + + prependListener(event: string, listener: Function): this; + prependListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; + prependListener(event: "error", listener: (code: number, signal: string) => void): this; + + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "change", listener: (eventType: string, filename: string | Buffer) => void): this; + prependOnceListener(event: "error", listener: (code: number, signal: string) => void): this; + } + + export interface ReadStream extends stream.Readable { + close(): void; + destroy(): void; + + /** + * events.EventEmitter + * 1. open + * 2. close + */ + addListener(event: string, listener: Function): this; + addListener(event: "open", listener: (fd: number) => void): this; + addListener(event: "close", listener: () => void): this; + + on(event: string, listener: Function): this; + on(event: "open", listener: (fd: number) => void): this; + on(event: "close", listener: () => void): this; + + once(event: string, listener: Function): this; + once(event: "open", listener: (fd: number) => void): this; + once(event: "close", listener: () => void): this; + + prependListener(event: string, listener: Function): this; + prependListener(event: "open", listener: (fd: number) => void): this; + prependListener(event: "close", listener: () => void): this; + + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "open", listener: (fd: number) => void): this; + prependOnceListener(event: "close", listener: () => void): this; + } + + export interface WriteStream extends stream.Writable { + close(): void; + bytesWritten: number; + path: string | Buffer; + + /** + * events.EventEmitter + * 1. open + * 2. close + */ + addListener(event: string, listener: Function): this; + addListener(event: "open", listener: (fd: number) => void): this; + addListener(event: "close", listener: () => void): this; + + on(event: string, listener: Function): this; + on(event: "open", listener: (fd: number) => void): this; + on(event: "close", listener: () => void): this; + + once(event: string, listener: Function): this; + once(event: "open", listener: (fd: number) => void): this; + once(event: "close", listener: () => void): this; + + prependListener(event: string, listener: Function): this; + prependListener(event: "open", listener: (fd: number) => void): this; + prependListener(event: "close", listener: () => void): this; + + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "open", listener: (fd: number) => void): this; + prependOnceListener(event: "close", listener: () => void): this; + } + + /** + * Asynchronous rename. + * @param oldPath + * @param newPath + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function rename(oldPath: string, newPath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /** + * Synchronous rename + * @param oldPath + * @param newPath + */ + export function renameSync(oldPath: string, newPath: string): void; + export function truncate(path: string | Buffer, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function truncate(path: string | Buffer, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function truncateSync(path: string | Buffer, len?: number): void; + export function ftruncate(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function ftruncate(fd: number, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function ftruncateSync(fd: number, len?: number): void; + export function chown(path: string | Buffer, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chownSync(path: string | Buffer, uid: number, gid: number): void; + export function fchown(fd: number, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchownSync(fd: number, uid: number, gid: number): void; + export function lchown(path: string | Buffer, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchownSync(path: string | Buffer, uid: number, gid: number): void; + export function chmod(path: string | Buffer, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chmod(path: string | Buffer, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chmodSync(path: string | Buffer, mode: number): void; + export function chmodSync(path: string | Buffer, mode: string): void; + export function fchmod(fd: number, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchmod(fd: number, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchmodSync(fd: number, mode: number): void; + export function fchmodSync(fd: number, mode: string): void; + export function lchmod(path: string | Buffer, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchmod(path: string | Buffer, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchmodSync(path: string | Buffer, mode: number): void; + export function lchmodSync(path: string | Buffer, mode: string): void; + export function stat(path: string | Buffer, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function lstat(path: string | Buffer, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function fstat(fd: number, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function statSync(path: string | Buffer): Stats; + export function lstatSync(path: string | Buffer): Stats; + export function fstatSync(fd: number): Stats; + export function link(srcpath: string | Buffer, dstpath: string | Buffer, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function linkSync(srcpath: string | Buffer, dstpath: string | Buffer): void; + export function symlink(srcpath: string | Buffer, dstpath: string | Buffer, type?: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function symlinkSync(srcpath: string | Buffer, dstpath: string | Buffer, type?: string): void; + export function readlink(path: string | Buffer, callback?: (err: NodeJS.ErrnoException, linkString: string) => any): void; + export function readlinkSync(path: string | Buffer): string; + export function realpath(path: string | Buffer, callback?: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; + export function realpath(path: string | Buffer, cache: { [path: string]: string }, callback: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; + export function realpathSync(path: string | Buffer, cache?: { [path: string]: string }): string; + /* + * Asynchronous unlink - deletes the file specified in {path} + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function unlink(path: string | Buffer, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Synchronous unlink - deletes the file specified in {path} + * + * @param path + */ + export function unlinkSync(path: string | Buffer): void; + /* + * Asynchronous rmdir - removes the directory specified in {path} + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function rmdir(path: string | Buffer, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Synchronous rmdir - removes the directory specified in {path} + * + * @param path + */ + export function rmdirSync(path: string | Buffer): void; + /* + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdir(path: string | Buffer, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdir(path: string | Buffer, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdir(path: string | Buffer, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdirSync(path: string | Buffer, mode?: number): void; + /* + * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdirSync(path: string | Buffer, mode?: string): void; + /* + * Asynchronous mkdtemp - Creates a unique temporary directory. Generates six random characters to be appended behind a required prefix to create a unique temporary directory. + * + * @param prefix + * @param callback The created folder path is passed as a string to the callback's second parameter. + */ + export function mkdtemp(prefix: string, callback?: (err: NodeJS.ErrnoException, folder: string) => void): void; + /* + * Synchronous mkdtemp - Creates a unique temporary directory. Generates six random characters to be appended behind a required prefix to create a unique temporary directory. + * + * @param prefix + * @returns Returns the created folder path. + */ + export function mkdtempSync(prefix: string): string; + export function readdir(path: string | Buffer, callback?: (err: NodeJS.ErrnoException, files: string[]) => void): void; + export function readdirSync(path: string | Buffer): string[]; + export function close(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function closeSync(fd: number): void; + export function open(path: string | Buffer, flags: string | number, callback: (err: NodeJS.ErrnoException, fd: number) => void): void; + export function open(path: string | Buffer, flags: string | number, mode: number, callback: (err: NodeJS.ErrnoException, fd: number) => void): void; + export function openSync(path: string | Buffer, flags: string | number, mode?: number): number; + export function utimes(path: string | Buffer, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function utimes(path: string | Buffer, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function utimesSync(path: string | Buffer, atime: number, mtime: number): void; + export function utimesSync(path: string | Buffer, atime: Date, mtime: Date): void; + export function futimes(fd: number, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function futimes(fd: number, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function futimesSync(fd: number, atime: number, mtime: number): void; + export function futimesSync(fd: number, atime: Date, mtime: Date): void; + export function fsync(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fsyncSync(fd: number): void; + export function write(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; + export function write(fd: number, buffer: Buffer, offset: number, length: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; + export function write(fd: number, data: any, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + export function write(fd: number, data: any, offset: number, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + export function write(fd: number, data: any, offset: number, encoding: string, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + export function writeSync(fd: number, buffer: Buffer, offset: number, length: number, position?: number): number; + export function writeSync(fd: number, data: any, position?: number, enconding?: string): number; + export function read(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, bytesRead: number, buffer: Buffer) => void): void; + export function readSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param encoding + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, encoding: string, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, options: { encoding: string; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, options: { flag?: string; }, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + /* + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param encoding + */ + export function readFileSync(filename: string, encoding: string): string; + /* + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. + */ + export function readFileSync(filename: string, options: { encoding: string; flag?: string; }): string; + /* + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. + */ + export function readFileSync(filename: string, options?: { flag?: string; }): Buffer; + export function writeFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; + export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; + export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; + export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; + export function watchFile(filename: string, listener: (curr: Stats, prev: Stats) => void): void; + export function watchFile(filename: string, options: { persistent?: boolean; interval?: number; }, listener: (curr: Stats, prev: Stats) => void): void; + export function unwatchFile(filename: string, listener?: (curr: Stats, prev: Stats) => void): void; + export function watch(filename: string, listener?: (event: string, filename: string) => any): FSWatcher; + export function watch(filename: string, encoding: string, listener?: (event: string, filename: string | Buffer) => any): FSWatcher; + export function watch(filename: string, options: { persistent?: boolean; recursive?: boolean; encoding?: string }, listener?: (event: string, filename: string | Buffer) => any): FSWatcher; + export function exists(path: string | Buffer, callback?: (exists: boolean) => void): void; + export function existsSync(path: string | Buffer): boolean; + + interface Constants { + /** Constant for fs.access(). File is visible to the calling process. */ + F_OK: number; + + /** Constant for fs.access(). File can be read by the calling process. */ + R_OK: number; + + /** Constant for fs.access(). File can be written by the calling process. */ + W_OK: number; + + /** Constant for fs.access(). File can be executed by the calling process. */ + X_OK: number; + } + + export const constants: Constants; + + /** Tests a user's permissions for the file specified by path. */ + export function access(path: string | Buffer, callback: (err: NodeJS.ErrnoException) => void): void; + export function access(path: string | Buffer, mode: number, callback: (err: NodeJS.ErrnoException) => void): void; + /** Synchronous version of fs.access. This throws if any accessibility checks fail, and does nothing otherwise. */ + export function accessSync(path: string | Buffer, mode?: number): void; + export function createReadStream(path: string | Buffer, options?: { + flags?: string; + encoding?: string; + fd?: number; + mode?: number; + autoClose?: boolean; + start?: number; + end?: number; + }): ReadStream; + export function createWriteStream(path: string | Buffer, options?: { + flags?: string; + encoding?: string; + fd?: number; + mode?: number; + }): WriteStream; + export function fdatasync(fd: number, callback: Function): void; + export function fdatasyncSync(fd: number): void; +} + +declare module "path" { + + /** + * A parsed path object generated by path.parse() or consumed by path.format(). + */ + export interface ParsedPath { + /** + * The root of the path such as '/' or 'c:\' + */ + root: string; + /** + * The full directory path such as '/home/user/dir' or 'c:\path\dir' + */ + dir: string; + /** + * The file name including extension (if any) such as 'index.html' + */ + base: string; + /** + * The file extension (if any) such as '.html' + */ + ext: string; + /** + * The file name without extension (if any) such as 'index' + */ + name: string; + } + + /** + * Normalize a string path, reducing '..' and '.' parts. + * When multiple slashes are found, they're replaced by a single one; when the path contains a trailing slash, it is preserved. On Windows backslashes are used. + * + * @param p string path to normalize. + */ + export function normalize(p: string): string; + /** + * Join all arguments together and normalize the resulting path. + * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. + * + * @param paths string paths to join. + */ + export function join(...paths: any[]): string; + /** + * Join all arguments together and normalize the resulting path. + * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. + * + * @param paths string paths to join. + */ + export function join(...paths: string[]): string; + /** + * The right-most parameter is considered {to}. Other parameters are considered an array of {from}. + * + * Starting from leftmost {from} paramter, resolves {to} to an absolute path. + * + * If {to} isn't already absolute, {from} arguments are prepended in right to left order, until an absolute path is found. If after using all {from} paths still no absolute path is found, the current working directory is used as well. The resulting path is normalized, and trailing slashes are removed unless the path gets resolved to the root directory. + * + * @param pathSegments string paths to join. Non-string arguments are ignored. + */ + export function resolve(...pathSegments: any[]): string; + /** + * Determines whether {path} is an absolute path. An absolute path will always resolve to the same location, regardless of the working directory. + * + * @param path path to test. + */ + export function isAbsolute(path: string): boolean; + /** + * Solve the relative path from {from} to {to}. + * At times we have two absolute paths, and we need to derive the relative path from one to the other. This is actually the reverse transform of path.resolve. + * + * @param from + * @param to + */ + export function relative(from: string, to: string): string; + /** + * Return the directory name of a path. Similar to the Unix dirname command. + * + * @param p the path to evaluate. + */ + export function dirname(p: string): string; + /** + * Return the last portion of a path. Similar to the Unix basename command. + * Often used to extract the file name from a fully qualified path. + * + * @param p the path to evaluate. + * @param ext optionally, an extension to remove from the result. + */ + export function basename(p: string, ext?: string): string; + /** + * Return the extension of the path, from the last '.' to end of string in the last portion of the path. + * If there is no '.' in the last portion of the path or the first character of it is '.', then it returns an empty string + * + * @param p the path to evaluate. + */ + export function extname(p: string): string; + /** + * The platform-specific file separator. '\\' or '/'. + */ + export var sep: string; + /** + * The platform-specific file delimiter. ';' or ':'. + */ + export var delimiter: string; + /** + * Returns an object from a path string - the opposite of format(). + * + * @param pathString path to evaluate. + */ + export function parse(pathString: string): ParsedPath; + /** + * Returns a path string from an object - the opposite of parse(). + * + * @param pathString path to evaluate. + */ + export function format(pathObject: ParsedPath): string; + + export module posix { + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function isAbsolute(p: string): boolean; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; + export var delimiter: string; + export function parse(p: string): ParsedPath; + export function format(pP: ParsedPath): string; + } + + export module win32 { + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function isAbsolute(p: string): boolean; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; + export var delimiter: string; + export function parse(p: string): ParsedPath; + export function format(pP: ParsedPath): string; + } +} + +declare module "string_decoder" { + export interface NodeStringDecoder { + write(buffer: Buffer): string; + end(buffer?: Buffer): string; + } + export var StringDecoder: { + new (encoding?: string): NodeStringDecoder; + }; +} + +declare module "tls" { + import * as crypto from "crypto"; + import * as net from "net"; + import * as stream from "stream"; + + var CLIENT_RENEG_LIMIT: number; + var CLIENT_RENEG_WINDOW: number; + + export interface Certificate { + /** + * Country code. + */ + C: string; + /** + * Street. + */ + ST: string; + /** + * Locality. + */ + L: string; + /** + * Organization. + */ + O: string; + /** + * Organizational unit. + */ + OU: string; + /** + * Common name. + */ + CN: string; + } + + export interface CipherNameAndProtocol { + /** + * The cipher name. + */ + name: string; + /** + * SSL/TLS protocol version. + */ + version: string; + } + + export class TLSSocket extends stream.Duplex { + /** + * Returns the bound address, the address family name and port of the underlying socket as reported by + * the operating system. + * @returns {any} - An object with three properties, e.g. { port: 12346, family: 'IPv4', address: '127.0.0.1' }. + */ + address(): { port: number; family: string; address: string }; + /** + * A boolean that is true if the peer certificate was signed by one of the specified CAs, otherwise false. + */ + authorized: boolean; + /** + * The reason why the peer's certificate has not been verified. + * This property becomes available only when tlsSocket.authorized === false. + */ + authorizationError: Error; + /** + * Static boolean value, always true. + * May be used to distinguish TLS sockets from regular ones. + */ + encrypted: boolean; + /** + * Returns an object representing the cipher name and the SSL/TLS protocol version of the current connection. + * @returns {CipherNameAndProtocol} - Returns an object representing the cipher name + * and the SSL/TLS protocol version of the current connection. + */ + getCipher(): CipherNameAndProtocol; + /** + * Returns an object representing the peer's certificate. + * The returned object has some properties corresponding to the field of the certificate. + * If detailed argument is true the full chain with issuer property will be returned, + * if false only the top certificate without issuer property. + * If the peer does not provide a certificate, it returns null or an empty object. + * @param {boolean} detailed - If true; the full chain with issuer property will be returned. + * @returns {any} - An object representing the peer's certificate. + */ + getPeerCertificate(detailed?: boolean): { + subject: Certificate; + issuerInfo: Certificate; + issuer: Certificate; + raw: any; + valid_from: string; + valid_to: string; + fingerprint: string; + serialNumber: string; + }; + /** + * Could be used to speed up handshake establishment when reconnecting to the server. + * @returns {any} - ASN.1 encoded TLS session or undefined if none was negotiated. + */ + getSession(): any; + /** + * NOTE: Works only with client TLS sockets. + * Useful only for debugging, for session reuse provide session option to tls.connect(). + * @returns {any} - TLS session ticket or undefined if none was negotiated. + */ + getTLSTicket(): any; + /** + * The string representation of the local IP address. + */ + localAddress: string; + /** + * The numeric representation of the local port. + */ + localPort: string; + /** + * The string representation of the remote IP address. + * For example, '74.125.127.100' or '2001:4860:a005::68'. + */ + remoteAddress: string; + /** + * The string representation of the remote IP family. 'IPv4' or 'IPv6'. + */ + remoteFamily: string; + /** + * The numeric representation of the remote port. For example, 443. + */ + remotePort: number; + /** + * Initiate TLS renegotiation process. + * + * NOTE: Can be used to request peer's certificate after the secure connection has been established. + * ANOTHER NOTE: When running as the server, socket will be destroyed with an error after handshakeTimeout timeout. + * @param {TlsOptions} options - The options may contain the following fields: rejectUnauthorized, + * requestCert (See tls.createServer() for details). + * @param {Function} callback - callback(err) will be executed with null as err, once the renegotiation + * is successfully completed. + */ + renegotiate(options: TlsOptions, callback: (err: Error) => any): any; + /** + * Set maximum TLS fragment size (default and maximum value is: 16384, minimum is: 512). + * Smaller fragment size decreases buffering latency on the client: large fragments are buffered by + * the TLS layer until the entire fragment is received and its integrity is verified; + * large fragments can span multiple roundtrips, and their processing can be delayed due to packet + * loss or reordering. However, smaller fragments add extra TLS framing bytes and CPU overhead, + * which may decrease overall server throughput. + * @param {number} size - TLS fragment size (default and maximum value is: 16384, minimum is: 512). + * @returns {boolean} - Returns true on success, false otherwise. + */ + setMaxSendFragment(size: number): boolean; + } + + export interface TlsOptions { + host?: string; + port?: number; + pfx?: string | Buffer[]; + key?: string | string[] | Buffer | any[]; + passphrase?: string; + cert?: string | string[] | Buffer | Buffer[]; + ca?: string | string[] | Buffer | Buffer[]; + crl?: string | string[]; + ciphers?: string; + honorCipherOrder?: boolean; + requestCert?: boolean; + rejectUnauthorized?: boolean; + NPNProtocols?: string[] | Buffer; + SNICallback?: (servername: string, cb: (err: Error, ctx: SecureContext) => any) => any; + ecdhCurve?: string; + dhparam?: string | Buffer; + handshakeTimeout?: number; + ALPNProtocols?: string[] | Buffer; + sessionTimeout?: number; + ticketKeys?: any; + sessionIdContext?: string; + secureProtocol?: string; + } + + export interface ConnectionOptions { + host?: string; + port?: number; + socket?: net.Socket; + pfx?: string | Buffer + key?: string | string[] | Buffer | Buffer[]; + passphrase?: string; + cert?: string | string[] | Buffer | Buffer[]; + ca?: string | Buffer | (string | Buffer)[]; + rejectUnauthorized?: boolean; + NPNProtocols?: (string | Buffer)[]; + servername?: string; + path?: string; + ALPNProtocols?: (string | Buffer)[]; + checkServerIdentity?: (servername: string, cert: string | Buffer | (string | Buffer)[]) => any; + secureProtocol?: string; + secureContext?: Object; + session?: Buffer; + minDHSize?: number; + } + + export interface Server extends net.Server { + close(): Server; + address(): { port: number; family: string; address: string; }; + addContext(hostName: string, credentials: { + key: string; + cert: string; + ca: string; + }): void; + maxConnections: number; + connections: number; + } + + export interface ClearTextStream extends stream.Duplex { + authorized: boolean; + authorizationError: Error; + getPeerCertificate(): any; + getCipher: { + name: string; + version: string; + }; + address: { + port: number; + family: string; + address: string; + }; + remoteAddress: string; + remotePort: number; + } + + export interface SecurePair { + encrypted: any; + cleartext: any; + } + + export interface SecureContextOptions { + pfx?: string | Buffer; + key?: string | Buffer; + passphrase?: string; + cert?: string | Buffer; + ca?: string | Buffer; + crl?: string | string[] + ciphers?: string; + honorCipherOrder?: boolean; + } + + export interface SecureContext { + context: any; + } + + export function createServer(options: TlsOptions, secureConnectionListener?: (cleartextStream: ClearTextStream) => void): Server; + export function connect(options: ConnectionOptions, secureConnectionListener?: () => void): ClearTextStream; + export function connect(port: number, host?: string, options?: ConnectionOptions, secureConnectListener?: () => void): ClearTextStream; + export function connect(port: number, options?: ConnectionOptions, secureConnectListener?: () => void): ClearTextStream; + export function createSecurePair(credentials?: crypto.Credentials, isServer?: boolean, requestCert?: boolean, rejectUnauthorized?: boolean): SecurePair; + export function createSecureContext(details: SecureContextOptions): SecureContext; +} + +declare module "crypto" { + export interface Certificate { + exportChallenge(spkac: string | Buffer): Buffer; + exportPublicKey(spkac: string | Buffer): Buffer; + verifySpkac(spkac: Buffer): boolean; + } + export var Certificate: { + new (): Certificate; + (): Certificate; + } + + export var fips: boolean; + + export interface CredentialDetails { + pfx: string; + key: string; + passphrase: string; + cert: string; + ca: string | string[]; + crl: string | string[]; + ciphers: string; + } + export interface Credentials { context?: any; } + export function createCredentials(details: CredentialDetails): Credentials; + export function createHash(algorithm: string): Hash; + export function createHmac(algorithm: string, key: string | Buffer): Hmac; + + type Utf8AsciiLatin1Encoding = "utf8" | "ascii" | "latin1"; + type HexBase64Latin1Encoding = "latin1" | "hex" | "base64"; + type Utf8AsciiBinaryEncoding = "utf8" | "ascii" | "binary"; + type HexBase64BinaryEncoding = "binary" | "base64" | "hex"; + type ECDHKeyFormat = "compressed" | "uncompressed" | "hybrid"; + + export interface Hash extends NodeJS.ReadWriteStream { + update(data: string | Buffer): Hash; + update(data: string | Buffer, input_encoding: Utf8AsciiLatin1Encoding): Hash; + digest(): Buffer; + digest(encoding: HexBase64Latin1Encoding): string; + } + export interface Hmac extends NodeJS.ReadWriteStream { + update(data: string | Buffer): Hmac; + update(data: string | Buffer, input_encoding: Utf8AsciiLatin1Encoding): Hmac; + digest(): Buffer; + digest(encoding: HexBase64Latin1Encoding): string; + } + export function createCipher(algorithm: string, password: any): Cipher; + export function createCipheriv(algorithm: string, key: any, iv: any): Cipher; + export interface Cipher extends NodeJS.ReadWriteStream { + update(data: Buffer): Buffer; + update(data: string, input_encoding: Utf8AsciiBinaryEncoding): Buffer; + update(data: Buffer, input_encoding: any, output_encoding: HexBase64BinaryEncoding): string; + update(data: string, input_encoding: Utf8AsciiBinaryEncoding, output_encoding: HexBase64BinaryEncoding): string; + final(): Buffer; + final(output_encoding: string): string; + setAutoPadding(auto_padding?: boolean): void; + getAuthTag(): Buffer; + setAAD(buffer: Buffer): void; + } + export function createDecipher(algorithm: string, password: any): Decipher; + export function createDecipheriv(algorithm: string, key: any, iv: any): Decipher; + export interface Decipher extends NodeJS.ReadWriteStream { + update(data: Buffer): Buffer; + update(data: string, input_encoding: HexBase64BinaryEncoding): Buffer; + update(data: Buffer, input_encoding: any, output_encoding: Utf8AsciiBinaryEncoding): string; + update(data: string, input_encoding: HexBase64BinaryEncoding, output_encoding: Utf8AsciiBinaryEncoding): string; + final(): Buffer; + final(output_encoding: string): string; + setAutoPadding(auto_padding?: boolean): void; + setAuthTag(tag: Buffer): void; + setAAD(buffer: Buffer): void; + } + export function createSign(algorithm: string): Signer; + export interface Signer extends NodeJS.WritableStream { + update(data: string | Buffer): Signer; + update(data: string | Buffer, input_encoding: Utf8AsciiLatin1Encoding): Signer; + sign(private_key: string | { key: string; passphrase: string }): Buffer; + sign(private_key: string | { key: string; passphrase: string }, output_format: HexBase64Latin1Encoding): string; + } + export function createVerify(algorith: string): Verify; + export interface Verify extends NodeJS.WritableStream { + update(data: string | Buffer): Verify; + update(data: string | Buffer, input_encoding: Utf8AsciiLatin1Encoding): Verify; + verify(object: string, signature: Buffer): boolean; + verify(object: string, signature: string, signature_format: HexBase64Latin1Encoding): boolean; + } + export function createDiffieHellman(prime_length: number, generator?: number): DiffieHellman; + export function createDiffieHellman(prime: Buffer): DiffieHellman; + export function createDiffieHellman(prime: string, prime_encoding: HexBase64Latin1Encoding): DiffieHellman; + export function createDiffieHellman(prime: string, prime_encoding: HexBase64Latin1Encoding, generator: number | Buffer): DiffieHellman; + export function createDiffieHellman(prime: string, prime_encoding: HexBase64Latin1Encoding, generator: string, generator_encoding: HexBase64Latin1Encoding): DiffieHellman; + export interface DiffieHellman { + generateKeys(): Buffer; + generateKeys(encoding: HexBase64Latin1Encoding): string; + computeSecret(other_public_key: Buffer): Buffer; + computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding): Buffer; + computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding, output_encoding: HexBase64Latin1Encoding): string; + getPrime(): Buffer; + getPrime(encoding: HexBase64Latin1Encoding): string; + getGenerator(): Buffer; + getGenerator(encoding: HexBase64Latin1Encoding): string; + getPublicKey(): Buffer; + getPublicKey(encoding: HexBase64Latin1Encoding): string; + getPrivateKey(): Buffer; + getPrivateKey(encoding: HexBase64Latin1Encoding): string; + setPublicKey(public_key: Buffer): void; + setPublicKey(public_key: string, encoding: string): void; + setPrivateKey(private_key: Buffer): void; + setPrivateKey(private_key: string, encoding: string): void; + verifyError: number; + } + export function getDiffieHellman(group_name: string): DiffieHellman; + export function pbkdf2(password: string | Buffer, salt: string | Buffer, iterations: number, keylen: number, digest: string, callback: (err: Error, derivedKey: Buffer) => any): void; + export function pbkdf2Sync(password: string | Buffer, salt: string | Buffer, iterations: number, keylen: number, digest: string): Buffer; + export function randomBytes(size: number): Buffer; + export function randomBytes(size: number, callback: (err: Error, buf: Buffer) => void): void; + export function pseudoRandomBytes(size: number): Buffer; + export function pseudoRandomBytes(size: number, callback: (err: Error, buf: Buffer) => void): void; + export interface RsaPublicKey { + key: string; + padding?: number; + } + export interface RsaPrivateKey { + key: string; + passphrase?: string, + padding?: number; + } + export function publicEncrypt(public_key: string | RsaPublicKey, buffer: Buffer): Buffer + export function privateDecrypt(private_key: string | RsaPrivateKey, buffer: Buffer): Buffer + export function privateEncrypt(private_key: string | RsaPrivateKey, buffer: Buffer): Buffer + export function publicDecrypt(public_key: string | RsaPublicKey, buffer: Buffer): Buffer + export function getCiphers(): string[]; + export function getCurves(): string[]; + export function getHashes(): string[]; + export interface ECDH { + generateKeys(): Buffer; + generateKeys(encoding: HexBase64Latin1Encoding): string; + generateKeys(encoding: HexBase64Latin1Encoding, format: ECDHKeyFormat): string; + computeSecret(other_public_key: Buffer): Buffer; + computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding): Buffer; + computeSecret(other_public_key: string, input_encoding: HexBase64Latin1Encoding, output_encoding: HexBase64Latin1Encoding): string; + getPrivateKey(): Buffer; + getPrivateKey(encoding: HexBase64Latin1Encoding): string; + getPublicKey(): Buffer; + getPublicKey(encoding: HexBase64Latin1Encoding): string; + getPublicKey(encoding: HexBase64Latin1Encoding, format: ECDHKeyFormat): string; + setPrivateKey(private_key: Buffer): void; + setPrivateKey(private_key: string, encoding: HexBase64Latin1Encoding): void; + } + export function createECDH(curve_name: string): ECDH; + export var DEFAULT_ENCODING: string; +} + +declare module "stream" { + import * as events from "events"; + + class internal extends events.EventEmitter { + pipe(destination: T, options?: { end?: boolean; }): T; + } + namespace internal { + + export class Stream extends internal { } + + export interface ReadableOptions { + highWaterMark?: number; + encoding?: string; + objectMode?: boolean; + read?: (size?: number) => any; + } + + export class Readable extends events.EventEmitter implements NodeJS.ReadableStream { + readable: boolean; + constructor(opts?: ReadableOptions); + _read(size: number): void; + read(size?: number): any; + setEncoding(encoding: string): void; + pause(): Readable; + resume(): Readable; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: any): void; + wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; + push(chunk: any, encoding?: string): boolean; + + /** + * Event emitter + * The defined events on documents including: + * 1. close + * 2. data + * 3. end + * 4. readable + * 5. error + **/ + addListener(event: string, listener: Function): this; + addListener(event: string, listener: Function): this; + addListener(event: "close", listener: () => void): this; + addListener(event: "data", listener: (chunk: Buffer | string) => void): this; + addListener(event: "end", listener: () => void): this; + addListener(event: "readable", listener: () => void): this; + addListener(event: "error", listener: (err: Error) => void): this; + + emit(event: string, ...args: any[]): boolean; + emit(event: "close"): boolean; + emit(event: "data", chunk: Buffer | string): boolean; + emit(event: "end"): boolean; + emit(event: "readable"): boolean; + emit(event: "error", err: Error): boolean; + + on(event: string, listener: Function): this; + on(event: "close", listener: () => void): this; + on(event: "data", listener: (chunk: Buffer | string) => void): this; + on(event: "end", listener: () => void): this; + on(event: "readable", listener: () => void): this; + on(event: "error", listener: (err: Error) => void): this; + + once(event: string, listener: Function): this; + once(event: "close", listener: () => void): this; + once(event: "data", listener: (chunk: Buffer | string) => void): this; + once(event: "end", listener: () => void): this; + once(event: "readable", listener: () => void): this; + once(event: "error", listener: (err: Error) => void): this; + + prependListener(event: string, listener: Function): this; + prependListener(event: "close", listener: () => void): this; + prependListener(event: "data", listener: (chunk: Buffer | string) => void): this; + prependListener(event: "end", listener: () => void): this; + prependListener(event: "readable", listener: () => void): this; + prependListener(event: "error", listener: (err: Error) => void): this; + + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "close", listener: () => void): this; + prependOnceListener(event: "data", listener: (chunk: Buffer | string) => void): this; + prependOnceListener(event: "end", listener: () => void): this; + prependOnceListener(event: "readable", listener: () => void): this; + prependOnceListener(event: "error", listener: (err: Error) => void): this; + + removeListener(event: string, listener: Function): this; + removeListener(event: "close", listener: () => void): this; + removeListener(event: "data", listener: (chunk: Buffer | string) => void): this; + removeListener(event: "end", listener: () => void): this; + removeListener(event: "readable", listener: () => void): this; + removeListener(event: "error", listener: (err: Error) => void): this; + } + + export interface WritableOptions { + highWaterMark?: number; + decodeStrings?: boolean; + objectMode?: boolean; + write?: (chunk: string | Buffer, encoding: string, callback: Function) => any; + writev?: (chunks: { chunk: string | Buffer, encoding: string }[], callback: Function) => any; + } + + export class Writable extends events.EventEmitter implements NodeJS.WritableStream { + writable: boolean; + constructor(opts?: WritableOptions); + _write(chunk: any, encoding: string, callback: Function): void; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; + end(): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; + + /** + * Event emitter + * The defined events on documents including: + * 1. close + * 2. drain + * 3. error + * 4. finish + * 5. pipe + * 6. unpipe + **/ + addListener(event: string, listener: Function): this; + addListener(event: "close", listener: () => void): this; + addListener(event: "drain", listener: () => void): this; + addListener(event: "error", listener: (err: Error) => void): this; + addListener(event: "finish", listener: () => void): this; + addListener(event: "pipe", listener: (src: Readable) => void): this; + addListener(event: "unpipe", listener: (src: Readable) => void): this; + + emit(event: string, ...args: any[]): boolean; + emit(event: "close"): boolean; + emit(event: "drain", chunk: Buffer | string): boolean; + emit(event: "error", err: Error): boolean; + emit(event: "finish"): boolean; + emit(event: "pipe", src: Readable): boolean; + emit(event: "unpipe", src: Readable): boolean; + + on(event: string, listener: Function): this; + on(event: "close", listener: () => void): this; + on(event: "drain", listener: () => void): this; + on(event: "error", listener: (err: Error) => void): this; + on(event: "finish", listener: () => void): this; + on(event: "pipe", listener: (src: Readable) => void): this; + on(event: "unpipe", listener: (src: Readable) => void): this; + + once(event: string, listener: Function): this; + once(event: "close", listener: () => void): this; + once(event: "drain", listener: () => void): this; + once(event: "error", listener: (err: Error) => void): this; + once(event: "finish", listener: () => void): this; + once(event: "pipe", listener: (src: Readable) => void): this; + once(event: "unpipe", listener: (src: Readable) => void): this; + + prependListener(event: string, listener: Function): this; + prependListener(event: "close", listener: () => void): this; + prependListener(event: "drain", listener: () => void): this; + prependListener(event: "error", listener: (err: Error) => void): this; + prependListener(event: "finish", listener: () => void): this; + prependListener(event: "pipe", listener: (src: Readable) => void): this; + prependListener(event: "unpipe", listener: (src: Readable) => void): this; + + prependOnceListener(event: string, listener: Function): this; + prependOnceListener(event: "close", listener: () => void): this; + prependOnceListener(event: "drain", listener: () => void): this; + prependOnceListener(event: "error", listener: (err: Error) => void): this; + prependOnceListener(event: "finish", listener: () => void): this; + prependOnceListener(event: "pipe", listener: (src: Readable) => void): this; + prependOnceListener(event: "unpipe", listener: (src: Readable) => void): this; + + removeListener(event: string, listener: Function): this; + removeListener(event: "close", listener: () => void): this; + removeListener(event: "drain", listener: () => void): this; + removeListener(event: "error", listener: (err: Error) => void): this; + removeListener(event: "finish", listener: () => void): this; + removeListener(event: "pipe", listener: (src: Readable) => void): this; + removeListener(event: "unpipe", listener: (src: Readable) => void): this; + } + + export interface DuplexOptions extends ReadableOptions, WritableOptions { + allowHalfOpen?: boolean; + readableObjectMode?: boolean; + writableObjectMode?: boolean; + } + + // Note: Duplex extends both Readable and Writable. + export class Duplex extends Readable implements NodeJS.ReadWriteStream { + // Readable + pause(): Duplex; + resume(): Duplex; + // Writeable + writable: boolean; + constructor(opts?: DuplexOptions); + _write(chunk: any, encoding: string, callback: Function): void; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; + end(): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; + } + + export interface TransformOptions extends ReadableOptions, WritableOptions { + transform?: (chunk: string | Buffer, encoding: string, callback: Function) => any; + flush?: (callback: Function) => any; + } + + // Note: Transform lacks the _read and _write methods of Readable/Writable. + export class Transform extends events.EventEmitter implements NodeJS.ReadWriteStream { + readable: boolean; + writable: boolean; + constructor(opts?: TransformOptions); + _transform(chunk: any, encoding: string, callback: Function): void; + _flush(callback: Function): void; + read(size?: number): any; + setEncoding(encoding: string): void; + pause(): Transform; + resume(): Transform; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: any): void; + wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; + push(chunk: any, encoding?: string): boolean; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; + end(): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; + } + + export class PassThrough extends Transform { } + } + + export = internal; +} + +declare module "util" { + export interface InspectOptions { + showHidden?: boolean; + depth?: number; + colors?: boolean; + customInspect?: boolean; + } + + export function format(format: any, ...param: any[]): string; + export function debug(string: string): void; + export function error(...param: any[]): void; + export function puts(...param: any[]): void; + export function print(...param: any[]): void; + export function log(string: string): void; + export function inspect(object: any, showHidden?: boolean, depth?: number, color?: boolean): string; + export function inspect(object: any, options: InspectOptions): string; + export function isArray(object: any): boolean; + export function isRegExp(object: any): boolean; + export function isDate(object: any): boolean; + export function isError(object: any): boolean; + export function inherits(constructor: any, superConstructor: any): void; + export function debuglog(key: string): (msg: string, ...param: any[]) => void; + export function isBoolean(object: any): boolean; + export function isBuffer(object: any): boolean; + export function isFunction(object: any): boolean; + export function isNull(object: any): boolean; + export function isNullOrUndefined(object: any): boolean; + export function isNumber(object: any): boolean; + export function isObject(object: any): boolean; + export function isPrimitive(object: any): boolean; + export function isString(object: any): boolean; + export function isSymbol(object: any): boolean; + export function isUndefined(object: any): boolean; + export function deprecate(fn: Function, message: string): Function; +} + +declare module "assert" { + function internal(value: any, message?: string): void; + namespace internal { + export class AssertionError implements Error { + name: string; + message: string; + actual: any; + expected: any; + operator: string; + generatedMessage: boolean; + + constructor(options?: { + message?: string; actual?: any; expected?: any; + operator?: string; stackStartFunction?: Function + }); + } + + export function fail(actual: any, expected: any, message: string, operator: string): void; + export function ok(value: any, message?: string): void; + export function equal(actual: any, expected: any, message?: string): void; + export function notEqual(actual: any, expected: any, message?: string): void; + export function deepEqual(actual: any, expected: any, message?: string): void; + export function notDeepEqual(acutal: any, expected: any, message?: string): void; + export function strictEqual(actual: any, expected: any, message?: string): void; + export function notStrictEqual(actual: any, expected: any, message?: string): void; + export function deepStrictEqual(actual: any, expected: any, message?: string): void; + export function notDeepStrictEqual(actual: any, expected: any, message?: string): void; + export var throws: { + (block: Function, message?: string): void; + (block: Function, error: Function, message?: string): void; + (block: Function, error: RegExp, message?: string): void; + (block: Function, error: (err: any) => boolean, message?: string): void; + }; + + export var doesNotThrow: { + (block: Function, message?: string): void; + (block: Function, error: Function, message?: string): void; + (block: Function, error: RegExp, message?: string): void; + (block: Function, error: (err: any) => boolean, message?: string): void; + }; + + export function ifError(value: any): void; + } + + export = internal; +} + +declare module "tty" { + import * as net from "net"; + + export function isatty(fd: number): boolean; + export interface ReadStream extends net.Socket { + isRaw: boolean; + setRawMode(mode: boolean): void; + isTTY: boolean; + } + export interface WriteStream extends net.Socket { + columns: number; + rows: number; + isTTY: boolean; + } +} + +declare module "domain" { + import * as events from "events"; + + export class Domain extends events.EventEmitter implements NodeJS.Domain { + run(fn: Function): void; + add(emitter: events.EventEmitter): void; + remove(emitter: events.EventEmitter): void; + bind(cb: (err: Error, data: any) => any): any; + intercept(cb: (data: any) => any): any; + dispose(): void; + members: any[]; + enter(): void; + exit(): void; + } + + export function create(): Domain; +} + +declare module "constants" { + export var E2BIG: number; + export var EACCES: number; + export var EADDRINUSE: number; + export var EADDRNOTAVAIL: number; + export var EAFNOSUPPORT: number; + export var EAGAIN: number; + export var EALREADY: number; + export var EBADF: number; + export var EBADMSG: number; + export var EBUSY: number; + export var ECANCELED: number; + export var ECHILD: number; + export var ECONNABORTED: number; + export var ECONNREFUSED: number; + export var ECONNRESET: number; + export var EDEADLK: number; + export var EDESTADDRREQ: number; + export var EDOM: number; + export var EEXIST: number; + export var EFAULT: number; + export var EFBIG: number; + export var EHOSTUNREACH: number; + export var EIDRM: number; + export var EILSEQ: number; + export var EINPROGRESS: number; + export var EINTR: number; + export var EINVAL: number; + export var EIO: number; + export var EISCONN: number; + export var EISDIR: number; + export var ELOOP: number; + export var EMFILE: number; + export var EMLINK: number; + export var EMSGSIZE: number; + export var ENAMETOOLONG: number; + export var ENETDOWN: number; + export var ENETRESET: number; + export var ENETUNREACH: number; + export var ENFILE: number; + export var ENOBUFS: number; + export var ENODATA: number; + export var ENODEV: number; + export var ENOENT: number; + export var ENOEXEC: number; + export var ENOLCK: number; + export var ENOLINK: number; + export var ENOMEM: number; + export var ENOMSG: number; + export var ENOPROTOOPT: number; + export var ENOSPC: number; + export var ENOSR: number; + export var ENOSTR: number; + export var ENOSYS: number; + export var ENOTCONN: number; + export var ENOTDIR: number; + export var ENOTEMPTY: number; + export var ENOTSOCK: number; + export var ENOTSUP: number; + export var ENOTTY: number; + export var ENXIO: number; + export var EOPNOTSUPP: number; + export var EOVERFLOW: number; + export var EPERM: number; + export var EPIPE: number; + export var EPROTO: number; + export var EPROTONOSUPPORT: number; + export var EPROTOTYPE: number; + export var ERANGE: number; + export var EROFS: number; + export var ESPIPE: number; + export var ESRCH: number; + export var ETIME: number; + export var ETIMEDOUT: number; + export var ETXTBSY: number; + export var EWOULDBLOCK: number; + export var EXDEV: number; + export var WSAEINTR: number; + export var WSAEBADF: number; + export var WSAEACCES: number; + export var WSAEFAULT: number; + export var WSAEINVAL: number; + export var WSAEMFILE: number; + export var WSAEWOULDBLOCK: number; + export var WSAEINPROGRESS: number; + export var WSAEALREADY: number; + export var WSAENOTSOCK: number; + export var WSAEDESTADDRREQ: number; + export var WSAEMSGSIZE: number; + export var WSAEPROTOTYPE: number; + export var WSAENOPROTOOPT: number; + export var WSAEPROTONOSUPPORT: number; + export var WSAESOCKTNOSUPPORT: number; + export var WSAEOPNOTSUPP: number; + export var WSAEPFNOSUPPORT: number; + export var WSAEAFNOSUPPORT: number; + export var WSAEADDRINUSE: number; + export var WSAEADDRNOTAVAIL: number; + export var WSAENETDOWN: number; + export var WSAENETUNREACH: number; + export var WSAENETRESET: number; + export var WSAECONNABORTED: number; + export var WSAECONNRESET: number; + export var WSAENOBUFS: number; + export var WSAEISCONN: number; + export var WSAENOTCONN: number; + export var WSAESHUTDOWN: number; + export var WSAETOOMANYREFS: number; + export var WSAETIMEDOUT: number; + export var WSAECONNREFUSED: number; + export var WSAELOOP: number; + export var WSAENAMETOOLONG: number; + export var WSAEHOSTDOWN: number; + export var WSAEHOSTUNREACH: number; + export var WSAENOTEMPTY: number; + export var WSAEPROCLIM: number; + export var WSAEUSERS: number; + export var WSAEDQUOT: number; + export var WSAESTALE: number; + export var WSAEREMOTE: number; + export var WSASYSNOTREADY: number; + export var WSAVERNOTSUPPORTED: number; + export var WSANOTINITIALISED: number; + export var WSAEDISCON: number; + export var WSAENOMORE: number; + export var WSAECANCELLED: number; + export var WSAEINVALIDPROCTABLE: number; + export var WSAEINVALIDPROVIDER: number; + export var WSAEPROVIDERFAILEDINIT: number; + export var WSASYSCALLFAILURE: number; + export var WSASERVICE_NOT_FOUND: number; + export var WSATYPE_NOT_FOUND: number; + export var WSA_E_NO_MORE: number; + export var WSA_E_CANCELLED: number; + export var WSAEREFUSED: number; + export var SIGHUP: number; + export var SIGINT: number; + export var SIGILL: number; + export var SIGABRT: number; + export var SIGFPE: number; + export var SIGKILL: number; + export var SIGSEGV: number; + export var SIGTERM: number; + export var SIGBREAK: number; + export var SIGWINCH: number; + export var SSL_OP_ALL: number; + export var SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: number; + export var SSL_OP_CIPHER_SERVER_PREFERENCE: number; + export var SSL_OP_CISCO_ANYCONNECT: number; + export var SSL_OP_COOKIE_EXCHANGE: number; + export var SSL_OP_CRYPTOPRO_TLSEXT_BUG: number; + export var SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: number; + export var SSL_OP_EPHEMERAL_RSA: number; + export var SSL_OP_LEGACY_SERVER_CONNECT: number; + export var SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: number; + export var SSL_OP_MICROSOFT_SESS_ID_BUG: number; + export var SSL_OP_MSIE_SSLV2_RSA_PADDING: number; + export var SSL_OP_NETSCAPE_CA_DN_BUG: number; + export var SSL_OP_NETSCAPE_CHALLENGE_BUG: number; + export var SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG: number; + export var SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: number; + export var SSL_OP_NO_COMPRESSION: number; + export var SSL_OP_NO_QUERY_MTU: number; + export var SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION: number; + export var SSL_OP_NO_SSLv2: number; + export var SSL_OP_NO_SSLv3: number; + export var SSL_OP_NO_TICKET: number; + export var SSL_OP_NO_TLSv1: number; + export var SSL_OP_NO_TLSv1_1: number; + export var SSL_OP_NO_TLSv1_2: number; + export var SSL_OP_PKCS1_CHECK_1: number; + export var SSL_OP_PKCS1_CHECK_2: number; + export var SSL_OP_SINGLE_DH_USE: number; + export var SSL_OP_SINGLE_ECDH_USE: number; + export var SSL_OP_SSLEAY_080_CLIENT_DH_BUG: number; + export var SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG: number; + export var SSL_OP_TLS_BLOCK_PADDING_BUG: number; + export var SSL_OP_TLS_D5_BUG: number; + export var SSL_OP_TLS_ROLLBACK_BUG: number; + export var ENGINE_METHOD_DSA: number; + export var ENGINE_METHOD_DH: number; + export var ENGINE_METHOD_RAND: number; + export var ENGINE_METHOD_ECDH: number; + export var ENGINE_METHOD_ECDSA: number; + export var ENGINE_METHOD_CIPHERS: number; + export var ENGINE_METHOD_DIGESTS: number; + export var ENGINE_METHOD_STORE: number; + export var ENGINE_METHOD_PKEY_METHS: number; + export var ENGINE_METHOD_PKEY_ASN1_METHS: number; + export var ENGINE_METHOD_ALL: number; + export var ENGINE_METHOD_NONE: number; + export var DH_CHECK_P_NOT_SAFE_PRIME: number; + export var DH_CHECK_P_NOT_PRIME: number; + export var DH_UNABLE_TO_CHECK_GENERATOR: number; + export var DH_NOT_SUITABLE_GENERATOR: number; + export var NPN_ENABLED: number; + export var RSA_PKCS1_PADDING: number; + export var RSA_SSLV23_PADDING: number; + export var RSA_NO_PADDING: number; + export var RSA_PKCS1_OAEP_PADDING: number; + export var RSA_X931_PADDING: number; + export var RSA_PKCS1_PSS_PADDING: number; + export var POINT_CONVERSION_COMPRESSED: number; + export var POINT_CONVERSION_UNCOMPRESSED: number; + export var POINT_CONVERSION_HYBRID: number; + export var O_RDONLY: number; + export var O_WRONLY: number; + export var O_RDWR: number; + export var S_IFMT: number; + export var S_IFREG: number; + export var S_IFDIR: number; + export var S_IFCHR: number; + export var S_IFBLK: number; + export var S_IFIFO: number; + export var S_IFSOCK: number; + export var S_IRWXU: number; + export var S_IRUSR: number; + export var S_IWUSR: number; + export var S_IXUSR: number; + export var S_IRWXG: number; + export var S_IRGRP: number; + export var S_IWGRP: number; + export var S_IXGRP: number; + export var S_IRWXO: number; + export var S_IROTH: number; + export var S_IWOTH: number; + export var S_IXOTH: number; + export var S_IFLNK: number; + export var O_CREAT: number; + export var O_EXCL: number; + export var O_NOCTTY: number; + export var O_DIRECTORY: number; + export var O_NOATIME: number; + export var O_NOFOLLOW: number; + export var O_SYNC: number; + export var O_SYMLINK: number; + export var O_DIRECT: number; + export var O_NONBLOCK: number; + export var O_TRUNC: number; + export var O_APPEND: number; + export var F_OK: number; + export var R_OK: number; + export var W_OK: number; + export var X_OK: number; + export var UV_UDP_REUSEADDR: number; + export var SIGQUIT: number; + export var SIGTRAP: number; + export var SIGIOT: number; + export var SIGBUS: number; + export var SIGUSR1: number; + export var SIGUSR2: number; + export var SIGPIPE: number; + export var SIGALRM: number; + export var SIGCHLD: number; + export var SIGSTKFLT: number; + export var SIGCONT: number; + export var SIGSTOP: number; + export var SIGTSTP: number; + export var SIGTTIN: number; + export var SIGTTOU: number; + export var SIGURG: number; + export var SIGXCPU: number; + export var SIGXFSZ: number; + export var SIGVTALRM: number; + export var SIGPROF: number; + export var SIGIO: number; + export var SIGPOLL: number; + export var SIGPWR: number; + export var SIGSYS: number; + export var SIGUNUSED: number; + export var defaultCoreCipherList: string; + export var defaultCipherList: string; + export var ENGINE_METHOD_RSA: number; + export var ALPN_ENABLED: number; +} + +declare module "process" { + export = process; +} + +declare module "v8" { + interface HeapSpaceInfo { + space_name: string; + space_size: number; + space_used_size: number; + space_available_size: number; + physical_space_size: number; + } + export function getHeapStatistics(): { total_heap_size: number, total_heap_size_executable: number, total_physical_size: number, total_avaialble_size: number, used_heap_size: number, heap_size_limit: number }; + export function getHeapSpaceStatistics(): HeapSpaceInfo[]; + export function setFlagsFromString(flags: string): void; +} + +declare module "timers" { + export function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; + export function clearTimeout(timeoutId: NodeJS.Timer): void; + export function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; + export function clearInterval(intervalId: NodeJS.Timer): void; + export function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; + export function clearImmediate(immediateId: any): void; +} + +declare module "console" { + export = console; +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/typings/globals/node/typings.json b/Tasks/AzureRmWebAppDeploymentV3/typings/globals/node/typings.json new file mode 100644 index 000000000000..98c1869d1d0a --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/typings/globals/node/typings.json @@ -0,0 +1,8 @@ +{ + "resolution": "main", + "tree": { + "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/ab8d917787092fdfb16390f2bee6de8ab5c1783c/node/node.d.ts", + "raw": "registry:dt/node#6.0.0+20160920093002", + "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/ab8d917787092fdfb16390f2bee6de8ab5c1783c/node/node.d.ts" + } +} diff --git a/Tasks/AzureRmWebAppDeploymentV3/typings/globals/q/index.d.ts b/Tasks/AzureRmWebAppDeploymentV3/typings/globals/q/index.d.ts new file mode 100644 index 000000000000..4449c31841ff --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/typings/globals/q/index.d.ts @@ -0,0 +1,357 @@ +// Generated by typings +// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/623f30ab194a3486e014ca39bc7f2089897d6ce4/q/Q.d.ts +declare function Q(promise: Q.IPromise): Q.Promise; +/** + * If value is not a promise, returns a promise that is fulfilled with value. + */ +declare function Q(value: T): Q.Promise; + +declare namespace Q { + interface IPromise { + then(onFulfill?: (value: T) => U | IPromise, onReject?: (error: any) => U | IPromise): IPromise; + } + + interface Deferred { + promise: Promise; + resolve(value?: T): void; + resolve(value?: IPromise): void; + reject(reason: any): void; + notify(value: any): void; + makeNodeResolver(): (reason: any, value: T) => void; + } + + interface Promise { + /** + * Like a finally clause, allows you to observe either the fulfillment or rejection of a promise, but to do so without modifying the final value. This is useful for collecting resources regardless of whether a job succeeded, like closing a database connection, shutting a server down, or deleting an unneeded key from an object. + + * finally returns a promise, which will become resolved with the same fulfillment value or rejection reason as promise. However, if callback returns a promise, the resolution of the returned promise will be delayed until the promise returned from callback is finished. + */ + fin(finallyCallback: () => any): Promise; + /** + * Like a finally clause, allows you to observe either the fulfillment or rejection of a promise, but to do so without modifying the final value. This is useful for collecting resources regardless of whether a job succeeded, like closing a database connection, shutting a server down, or deleting an unneeded key from an object. + + * finally returns a promise, which will become resolved with the same fulfillment value or rejection reason as promise. However, if callback returns a promise, the resolution of the returned promise will be delayed until the promise returned from callback is finished. + */ + finally(finallyCallback: () => any): Promise; + + /** + * The then method from the Promises/A+ specification, with an additional progress handler. + */ + then(onFulfill?: (value: T) => U | IPromise, onReject?: (error: any) => U | IPromise, onProgress?: Function): Promise; + + /** + * Like then, but "spreads" the array into a variadic fulfillment handler. If any of the promises in the array are rejected, instead calls onRejected with the first rejected promise's rejection reason. + * + * This is especially useful in conjunction with all + */ + spread(onFulfill: (...args: any[]) => IPromise | U, onReject?: (reason: any) => IPromise | U): Promise; + + fail(onRejected: (reason: any) => U | IPromise): Promise; + + /** + * A sugar method, equivalent to promise.then(undefined, onRejected). + */ + catch(onRejected: (reason: any) => U | IPromise): Promise; + + /** + * A sugar method, equivalent to promise.then(undefined, undefined, onProgress). + */ + progress(onProgress: (progress: any) => any): Promise; + + /** + * Much like then, but with different behavior around unhandled rejection. If there is an unhandled rejection, either because promise is rejected and no onRejected callback was provided, or because onFulfilled or onRejected threw an error or returned a rejected promise, the resulting rejection reason is thrown as an exception in a future turn of the event loop. + * + * This method should be used to terminate chains of promises that will not be passed elsewhere. Since exceptions thrown in then callbacks are consumed and transformed into rejections, exceptions at the end of the chain are easy to accidentally, silently ignore. By arranging for the exception to be thrown in a future turn of the event loop, so that it won't be caught, it causes an onerror event on the browser window, or an uncaughtException event on Node.js's process object. + * + * Exceptions thrown by done will have long stack traces, if Q.longStackSupport is set to true. If Q.onerror is set, exceptions will be delivered there instead of thrown in a future turn. + * + * The Golden Rule of done vs. then usage is: either return your promise to someone else, or if the chain ends with you, call done to terminate it. + */ + done(onFulfilled?: (value: T) => any, onRejected?: (reason: any) => any, onProgress?: (progress: any) => any): void; + + /** + * If callback is a function, assumes it's a Node.js-style callback, and calls it as either callback(rejectionReason) when/if promise becomes rejected, or as callback(null, fulfillmentValue) when/if promise becomes fulfilled. If callback is not a function, simply returns promise. + */ + nodeify(callback: (reason: any, value: any) => void): Promise; + + /** + * Returns a promise to get the named property of an object. Essentially equivalent to + * + * promise.then(function (o) { + * return o[propertyName]; + * }); + */ + get(propertyName: String): Promise; + set(propertyName: String, value: any): Promise; + delete(propertyName: String): Promise; + /** + * Returns a promise for the result of calling the named method of an object with the given array of arguments. The object itself is this in the function, just like a synchronous method call. Essentially equivalent to + * + * promise.then(function (o) { + * return o[methodName].apply(o, args); + * }); + */ + post(methodName: String, args: any[]): Promise; + /** + * Returns a promise for the result of calling the named method of an object with the given variadic arguments. The object itself is this in the function, just like a synchronous method call. + */ + invoke(methodName: String, ...args: any[]): Promise; + fapply(args: any[]): Promise; + fcall(...args: any[]): Promise; + + /** + * Returns a promise for an array of the property names of an object. Essentially equivalent to + * + * promise.then(function (o) { + * return Object.keys(o); + * }); + */ + keys(): Promise; + + /** + * A sugar method, equivalent to promise.then(function () { return value; }). + */ + thenResolve(value: U): Promise; + /** + * A sugar method, equivalent to promise.then(function () { throw reason; }). + */ + thenReject(reason: any): Promise; + + /** + * Attaches a handler that will observe the value of the promise when it becomes fulfilled, returning a promise for that same value, perhaps deferred but not replaced by the promise returned by the onFulfilled handler. + */ + tap(onFulfilled: (value: T) => any): Promise; + + timeout(ms: number, message?: string): Promise; + /** + * Returns a promise that will have the same result as promise, but will only be fulfilled or rejected after at least ms milliseconds have passed. + */ + delay(ms: number): Promise; + + /** + * Returns whether a given promise is in the fulfilled state. When the static version is used on non-promises, the result is always true. + */ + isFulfilled(): boolean; + /** + * Returns whether a given promise is in the rejected state. When the static version is used on non-promises, the result is always false. + */ + isRejected(): boolean; + /** + * Returns whether a given promise is in the pending state. When the static version is used on non-promises, the result is always false. + */ + isPending(): boolean; + + valueOf(): any; + + /** + * Returns a "state snapshot" object, which will be in one of three forms: + * + * - { state: "pending" } + * - { state: "fulfilled", value: } + * - { state: "rejected", reason: } + */ + inspect(): PromiseState; + } + + interface PromiseState { + /** + * "fulfilled", "rejected", "pending" + */ + state: string; + value?: T; + reason?: any; + } + + // If no value provided, returned promise will be of void type + export function when(): Promise; + + // if no fulfill, reject, or progress provided, returned promise will be of same type + export function when(value: T | IPromise): Promise; + + // If a non-promise value is provided, it will not reject or progress + export function when(value: T | IPromise, onFulfilled: (val: T) => U | IPromise, onRejected?: (reason: any) => U | IPromise, onProgress?: (progress: any) => any): Promise; + + /** + * Currently "impossible" (and I use the term loosely) to implement due to TypeScript limitations as it is now. + * See: https://github.com/Microsoft/TypeScript/issues/1784 for discussion on it. + */ + // export function try(method: Function, ...args: any[]): Promise; + + export function fbind(method: (...args: any[]) => T | IPromise, ...args: any[]): (...args: any[]) => Promise; + + export function fcall(method: (...args: any[]) => T, ...args: any[]): Promise; + + export function send(obj: any, functionName: string, ...args: any[]): Promise; + export function invoke(obj: any, functionName: string, ...args: any[]): Promise; + export function mcall(obj: any, functionName: string, ...args: any[]): Promise; + + export function denodeify(nodeFunction: Function, ...args: any[]): (...args: any[]) => Promise; + export function nbind(nodeFunction: Function, thisArg: any, ...args: any[]): (...args: any[]) => Promise; + export function nfbind(nodeFunction: Function, ...args: any[]): (...args: any[]) => Promise; + export function nfcall(nodeFunction: Function, ...args: any[]): Promise; + export function nfapply(nodeFunction: Function, args: any[]): Promise; + + export function ninvoke(nodeModule: any, functionName: string, ...args: any[]): Promise; + export function npost(nodeModule: any, functionName: string, args: any[]): Promise; + export function nsend(nodeModule: any, functionName: string, ...args: any[]): Promise; + export function nmcall(nodeModule: any, functionName: string, ...args: any[]): Promise; + + /** + * Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected. + */ + export function all(promises: [IPromise, IPromise, IPromise, IPromise, IPromise, IPromise]): Promise<[A, B, C, D, E, F]>; + /** + * Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected. + */ + export function all(promises: [IPromise, IPromise, IPromise, IPromise, IPromise]): Promise<[A, B, C, D, E]>; + /** + * Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected. + */ + export function all(promises: [IPromise, IPromise, IPromise, IPromise]): Promise<[A, B, C, D]>; + /** + * Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected. + */ + export function all(promises: [IPromise, IPromise, IPromise]): Promise<[A, B, C]>; + /** + * Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected. + */ + export function all(promises: [IPromise, IPromise]): Promise<[A, B]>; + /** + * Returns a promise that is fulfilled with an array containing the fulfillment value of each promise, or is rejected with the same rejection reason as the first promise to be rejected. + */ + export function all(promises: IPromise[]): Promise; + + /** + * Returns a promise for the first of an array of promises to become settled. + */ + export function race(promises: IPromise[]): Promise; + + /** + * Returns a promise that is fulfilled with an array of promise state snapshots, but only after all the original promises have settled, i.e. become either fulfilled or rejected. + */ + export function allSettled(promises: IPromise[]): Promise[]>; + + export function allResolved(promises: IPromise[]): Promise[]>; + + /** + * Like then, but "spreads" the array into a variadic fulfillment handler. If any of the promises in the array are rejected, instead calls onRejected with the first rejected promise's rejection reason. + * This is especially useful in conjunction with all. + */ + export function spread(promises: IPromise[], onFulfilled: (...args: T[]) => U | IPromise, onRejected?: (reason: any) => U | IPromise): Promise; + + /** + * Returns a promise that will have the same result as promise, except that if promise is not fulfilled or rejected before ms milliseconds, the returned promise will be rejected with an Error with the given message. If message is not supplied, the message will be "Timed out after " + ms + " ms". + */ + export function timeout(promise: Promise, ms: number, message?: string): Promise; + + /** + * Returns a promise that will have the same result as promise, but will only be fulfilled or rejected after at least ms milliseconds have passed. + */ + export function delay(promise: Promise, ms: number): Promise; + /** + * Returns a promise that will have the same result as promise, but will only be fulfilled or rejected after at least ms milliseconds have passed. + */ + export function delay(value: T, ms: number): Promise; + /** + * Returns a promise that will be fulfilled with undefined after at least ms milliseconds have passed. + */ + export function delay(ms: number): Promise ; + /** + * Returns whether a given promise is in the fulfilled state. When the static version is used on non-promises, the result is always true. + */ + export function isFulfilled(promise: Promise): boolean; + /** + * Returns whether a given promise is in the rejected state. When the static version is used on non-promises, the result is always false. + */ + export function isRejected(promise: Promise): boolean; + /** + * Returns whether a given promise is in the pending state. When the static version is used on non-promises, the result is always false. + */ + export function isPending(promise: Promise): boolean; + + /** + * Returns a "deferred" object with a: + * promise property + * resolve(value) method + * reject(reason) method + * notify(value) method + * makeNodeResolver() method + */ + export function defer(): Deferred; + + /** + * Returns a promise that is rejected with reason. + */ + export function reject(reason?: any): Promise; + + export function Promise(resolver: (resolve: (val: T | IPromise) => void , reject: (reason: any) => void , notify: (progress: any) => void ) => void ): Promise; + + /** + * Creates a new version of func that accepts any combination of promise and non-promise values, converting them to their fulfillment values before calling the original func. The returned version also always returns a promise: if func does a return or throw, then Q.promised(func) will return fulfilled or rejected promise, respectively. + * + * This can be useful for creating functions that accept either promises or non-promise values, and for ensuring that the function always returns a promise even in the face of unintentional thrown exceptions. + */ + export function promised(callback: (...args: any[]) => T): (...args: any[]) => Promise; + + /** + * Returns whether the given value is a Q promise. + */ + export function isPromise(object: any): boolean; + /** + * Returns whether the given value is a promise (i.e. it's an object with a then function). + */ + export function isPromiseAlike(object: any): boolean; + /** + * Returns whether a given promise is in the pending state. When the static version is used on non-promises, the result is always false. + */ + export function isPending(object: any): boolean; + /** + * If an object is not a promise, it is as "near" as possible. + * If a promise is rejected, it is as "near" as possible too. + * If it’s a fulfilled promise, the fulfillment value is nearer. + * If it’s a deferred promise and the deferred has been resolved, the + * resolution is "nearer". + */ + export function nearer(promise: Promise): T; + + /** + * This is an experimental tool for converting a generator function into a deferred function. This has the potential of reducing nested callbacks in engines that support yield. + */ + export function async(generatorFunction: any): (...args: any[]) => Promise; + export function nextTick(callback: Function): void; + + /** + * A settable property that will intercept any uncaught errors that would otherwise be thrown in the next tick of the event loop, usually as a result of done. Can be useful for getting the full stack trace of an error in browsers, which is not usually possible with window.onerror. + */ + export var onerror: (reason: any) => void; + /** + * A settable property that lets you turn on long stack trace support. If turned on, "stack jumps" will be tracked across asynchronous promise operations, so that if an uncaught error is thrown by done or a rejection reason's stack property is inspected in a rejection callback, a long stack trace is produced. + */ + export var longStackSupport: boolean; + + /** + * Calling resolve with a pending promise causes promise to wait on the passed promise, becoming fulfilled with its fulfillment value or rejected with its rejection reason (or staying pending forever, if the passed promise does). + * Calling resolve with a rejected promise causes promise to be rejected with the passed promise's rejection reason. + * Calling resolve with a fulfilled promise causes promise to be fulfilled with the passed promise's fulfillment value. + * Calling resolve with a non-promise value causes promise to be fulfilled with that value. + */ + export function resolve(object: IPromise): Promise; + /** + * Calling resolve with a pending promise causes promise to wait on the passed promise, becoming fulfilled with its fulfillment value or rejected with its rejection reason (or staying pending forever, if the passed promise does). + * Calling resolve with a rejected promise causes promise to be rejected with the passed promise's rejection reason. + * Calling resolve with a fulfilled promise causes promise to be fulfilled with the passed promise's fulfillment value. + * Calling resolve with a non-promise value causes promise to be fulfilled with that value. + */ + export function resolve(object: T): Promise; + + /** + * Resets the global "Q" variable to the value it has before Q was loaded. + * This will either be undefined if there was no version or the version of Q which was already loaded before. + * @returns { The last version of Q. } + */ + export function noConflict(): typeof Q; +} + +declare module "q" { + export = Q; +} \ No newline at end of file diff --git a/Tasks/AzureRmWebAppDeploymentV3/typings/globals/q/typings.json b/Tasks/AzureRmWebAppDeploymentV3/typings/globals/q/typings.json new file mode 100644 index 000000000000..3d59355a87e8 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/typings/globals/q/typings.json @@ -0,0 +1,8 @@ +{ + "resolution": "main", + "tree": { + "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/623f30ab194a3486e014ca39bc7f2089897d6ce4/q/Q.d.ts", + "raw": "registry:dt/q#0.0.0+20160613154756", + "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/623f30ab194a3486e014ca39bc7f2089897d6ce4/q/Q.d.ts" + } +} diff --git a/Tasks/AzureRmWebAppDeploymentV3/typings/index.d.ts b/Tasks/AzureRmWebAppDeploymentV3/typings/index.d.ts new file mode 100644 index 000000000000..bbb3a42c2b21 --- /dev/null +++ b/Tasks/AzureRmWebAppDeploymentV3/typings/index.d.ts @@ -0,0 +1,3 @@ +/// +/// +/// diff --git a/Tasks/AzureRmWebAppDeploymentV4/task.json b/Tasks/AzureRmWebAppDeploymentV4/task.json index f6aae69da727..886d28ee56d6 100644 --- a/Tasks/AzureRmWebAppDeploymentV4/task.json +++ b/Tasks/AzureRmWebAppDeploymentV4/task.json @@ -599,6 +599,7 @@ "ASE_SSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to set a variable named VSTS_ARM_REST_IGNORE_SSL_ERRORS to the value true in the build or release pipeline", "ZipDeployLogsURL": "Zip Deploy logs can be viewed at %s", "AppServiceApplicationURL": "App Service Application URL: %s", - "ASE_WebDeploySSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to pass -allowUntrusted in additional arguments of web deploy option." + "ASE_WebDeploySSLIssueRecommendation": "To use a certificate in App Service, the certificate must be signed by a trusted certificate authority. If your web app gives you certificate validation errors, you're probably using a self-signed certificate and to resolve them you need to pass -allowUntrusted in additional arguments of web deploy option.", + "FailedToGetResourceID": "Failed to get resource ID for resource type '%s' and resource name '%s'. Error: %s" } } diff --git a/make-options.json b/make-options.json index a8f23cb32c97..459bd15f5291 100644 --- a/make-options.json +++ b/make-options.json @@ -19,6 +19,7 @@ "AzureNLBManagementV1", "AzurePowerShellV3", "AzureResourceGroupDeploymentV2", + "AzureRmWebAppDeploymentV3", "AzureRmWebAppDeploymentV4", "AzureVmssDeploymentV0", "BashV3",