implemented uploading template from URL - home page (#196)
* implemented uploading template from URL - home page * added comments * setting the default template once the process completes * setting default template after the process completes * validating extension for private tempalte * Handled pull request error * changed querystring parameter showing template name without GUID * hiding choose template button when template is submitted in URL * adding note about private template * updated the document * updated doc
This commit is contained in:
Родитель
bb050c75bd
Коммит
00ea7b2fe2
|
@ -148,3 +148,4 @@ UpgradeLog.htm
|
|||
.cr/
|
||||
/src/VstsDemoBuilder/Logs
|
||||
/src/VstsDemoBuilder/ExtractedTemplate/adqw
|
||||
/src/AzureDevOpsDemoBuilder/log
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
# Using Private template URL
|
||||
|
||||
Once you generate the custom tempalte using [Azure DevOps Demo Generator - Tempalte Builder](https://azuredevopsdemogenerator.azurewebsites.net/), you can use the same template as a master copy to provision the sample projects.
|
||||
|
||||
## Provisioning your project from your custom template using public URL
|
||||
|
||||
Using private template URL you can provisoin the project. You have multiple options here
|
||||
|
||||
|
||||
1. Using the template URL from public GitHub repository, refer [Provisioning the project from your custom template](./Using-The-Template-Extractor.md)
|
||||
|
||||
1. Use the template URL in the home page of [Azure DevOps Demo Generator](https://azuredevopsdemogenerator.azurewebsites.net/) with querystring parameter **?templateurl**. This supports only the public URL
|
||||
|
||||
>```Ex: https://azuredevopsdemogenerator.azurewebsites.net/?templateurl=public_url ```
|
||||
|
||||
Once you format the URL, press enter to reload the page.
|
||||
1. Click on **Sign In** button
|
||||
|
||||
1. Once you navigate to **Create Project** page, you should see the private tempalte selected by default
|
||||
|
||||
1. Select the **Organization**. Provide the **Project Name**. Choose **Create Project** to start provisioning a project
|
||||
|
||||
> **Note**: Once the process completes, the template will be discarded by the system. If you want to reuse the tempalte, you can use the **Private** option in the **Choose Template** dialog box
|
||||
|
||||
You can refer the document [Provisioning your project from your custom template](./Using-The-Template-Extractor.md)
|
||||
|
||||
Previous: [Using the Extractor](./Using-The-Template-Extractor.md)
|
|
@ -44,10 +44,20 @@ Setup an Azure DevOps project and make sure it is ready to be extracted. The ext
|
|||
|
||||
1. You will see a new tab labelled **Private**. Select the tab.
|
||||
|
||||
1. Select **Browse** and select the zip file you downloaded zip file.
|
||||
Here you have three option
|
||||
|
||||
1. Click **OK** to close the dialog. Choose **Create Project** to start provisioning a project
|
||||
1. Select **Browse** and select the zip file you downloaded zip file.
|
||||
|
||||
1. Use the radio button **GitHub** to consume the private template from a github raw URL
|
||||
|
||||
1. Use the radio button **URL** to consume the private template from other sources
|
||||
|
||||
1. Once you point the right template, click **Submit** to validate and pick the template for provisoning the project
|
||||
|
||||
1. Choose **Create Project** to start provisioning a project
|
||||
|
||||
-------------
|
||||
|
||||
Previous: [Using the Generator](./Using-The-Generator.md)
|
||||
|
||||
Next: [Using Private template URL](./Using-Private-template-URL.md)
|
|
@ -2,6 +2,8 @@
|
|||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Web.Hosting;
|
||||
using System.Web.Mvc;
|
||||
using VstsDemoBuilder.Models;
|
||||
using VstsDemoBuilder.ServiceInterfaces;
|
||||
|
@ -16,10 +18,12 @@ namespace VstsDemoBuilder.Controllers
|
|||
private TemplateSelection.Templates templates = new TemplateSelection.Templates();
|
||||
private ILog logger = LogManager.GetLogger("ErrorLog");
|
||||
private IProjectService projectService;
|
||||
private ITemplateService templateService;
|
||||
|
||||
public AccountController(IProjectService _projectService)
|
||||
public AccountController(IProjectService _projectService, ITemplateService _templateService)
|
||||
{
|
||||
projectService = _projectService;
|
||||
templateService = _templateService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
|
@ -49,6 +53,7 @@ namespace VstsDemoBuilder.Controllers
|
|||
{
|
||||
Session["EnableExtractor"] = model.EnableExtractor;
|
||||
}
|
||||
|
||||
var browser = Request.Browser.Type;
|
||||
if (browser.Contains("InternetExplorer"))
|
||||
{
|
||||
|
@ -101,6 +106,25 @@ namespace VstsDemoBuilder.Controllers
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(model.TemplateURL))
|
||||
{
|
||||
if (model.TemplateURL.EndsWith(".zip"))
|
||||
{
|
||||
PrivateTemplate _privateTemplate = UploadPrivateTempalteFromHome(model.TemplateURL);
|
||||
if (_privateTemplate.IsTemplateValid)
|
||||
{
|
||||
Session["PrivateTemplateURL"] = _privateTemplate.privateTemplatePath;
|
||||
Session["PrivateTemplateName"] = _privateTemplate.privateTemplateName;
|
||||
Session["PrivateTemplateOriginalName"] = _privateTemplate.privateTemplateOriginalName;
|
||||
}
|
||||
else
|
||||
{
|
||||
ViewBag.resMessage = _privateTemplate.responseMessage;
|
||||
return View(new LoginModel());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -172,5 +196,48 @@ namespace VstsDemoBuilder.Controllers
|
|||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
public PrivateTemplate UploadPrivateTempalteFromHome(string TemplateURL)
|
||||
{
|
||||
PrivateTemplate privateTemplate = new PrivateTemplate();
|
||||
string templatePath = string.Empty;
|
||||
try
|
||||
{
|
||||
privateTemplate.IsTemplateValid = false;
|
||||
string templateName = "";
|
||||
string fileName = Path.GetFileName(TemplateURL);
|
||||
string extension = Path.GetExtension(TemplateURL);
|
||||
privateTemplate.privateTemplateOriginalName = fileName.ToLower().Replace(".zip", "").Trim();
|
||||
templateName = fileName.ToLower().Replace(".zip", "").Trim() + "-" + Guid.NewGuid().ToString().Substring(0, 6) + extension.ToLower();
|
||||
privateTemplate.privateTemplateName = templateName.ToLower().Replace(".zip", "").Trim();
|
||||
privateTemplate.privateTemplatePath = templateService.GetTemplateFromPath(TemplateURL, templateName, "", "", "");
|
||||
|
||||
if (privateTemplate.privateTemplatePath != "")
|
||||
{
|
||||
privateTemplate.responseMessage = templateService.checkSelectedTemplateIsPrivate(privateTemplate.privateTemplatePath);
|
||||
if (privateTemplate.responseMessage != "SUCCESS")
|
||||
{
|
||||
var templatepath = HostingEnvironment.MapPath("~") + @"\PrivateTemplates\" + templateName.ToLower().Replace(".zip", "").Trim();
|
||||
if (Directory.Exists(templatepath))
|
||||
Directory.Delete(templatepath, true);
|
||||
}
|
||||
if (privateTemplate.responseMessage == "SUCCESS")
|
||||
{
|
||||
privateTemplate.IsTemplateValid = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
privateTemplate.responseMessage = "Unable to download file, please check the provided URL";
|
||||
privateTemplate.IsTemplateValid = false;
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ProjectService.logger.Info(DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss") + "\t" + "\t" + ex.Message + "\t" + "\n" + ex.StackTrace + "\n");
|
||||
}
|
||||
return privateTemplate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,11 +168,16 @@ namespace VstsDemoBuilder.Controllers
|
|||
model.TemplateName = Session["templateName"].ToString();
|
||||
TemplateSelected = model.TemplateName;
|
||||
}
|
||||
else if (Session["PrivateTemplateName"] != null)
|
||||
{
|
||||
model.TemplateName = Session["PrivateTemplateName"].ToString();
|
||||
TemplateSelected = model.TemplateName;
|
||||
}
|
||||
else
|
||||
{
|
||||
TemplateSelected = System.Configuration.ConfigurationManager.AppSettings["DefaultTemplate"];
|
||||
model.TemplateName = TemplateSelected;
|
||||
}
|
||||
|
||||
if (Session["PAT"] != null)
|
||||
{
|
||||
_accessDetails.access_token = Session["PAT"].ToString();
|
||||
|
@ -229,25 +234,37 @@ namespace VstsDemoBuilder.Controllers
|
|||
//if exist, will append the template name to Selected template textbox, else will append the SmartHotel360 template
|
||||
if (!string.IsNullOrEmpty(TemplateSelected))
|
||||
{
|
||||
foreach (var grpTemplate in templates.GroupwiseTemplates)
|
||||
if (Session["PrivateTemplateName"] == null)
|
||||
{
|
||||
foreach (var template in grpTemplate.Template)
|
||||
foreach (var grpTemplate in templates.GroupwiseTemplates)
|
||||
{
|
||||
if (template.Name != null)
|
||||
foreach (var template in grpTemplate.Template)
|
||||
{
|
||||
if (template.Name.ToLower() == TemplateSelected.ToLower())
|
||||
if (template.Name != null)
|
||||
{
|
||||
model.SelectedTemplate = template.Name;
|
||||
model.Templates.Add(template.Name);
|
||||
model.selectedTemplateDescription = template.Description == null ? string.Empty : template.Description;
|
||||
model.selectedTemplateFolder = template.TemplateFolder == null ? string.Empty : template.TemplateFolder;
|
||||
model.Message = template.Message == null ? string.Empty : template.Message;
|
||||
model.ForkGitHubRepo = template.ForkGitHubRepo.ToString();
|
||||
model.templateImage = template.Image ?? "/Templates/TemplateImages/CodeFile.png";
|
||||
if (template.Name.ToLower() == TemplateSelected.ToLower())
|
||||
{
|
||||
model.SelectedTemplate = template.Name;
|
||||
model.Templates.Add(template.Name);
|
||||
model.selectedTemplateDescription = template.Description == null ? string.Empty : template.Description;
|
||||
model.selectedTemplateFolder = template.TemplateFolder == null ? string.Empty : template.TemplateFolder;
|
||||
model.Message = template.Message == null ? string.Empty : template.Message;
|
||||
model.ForkGitHubRepo = template.ForkGitHubRepo.ToString();
|
||||
model.templateImage = template.Image ?? "/Templates/TemplateImages/CodeFile.png";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
model.SelectedTemplate = Session["PrivateTemplateOriginalName"].ToString();
|
||||
model.Templates.Add(model.SelectedTemplate);
|
||||
model.selectedTemplateDescription = "<p style='color:red;fontsize:10px'><b>Note</b>: Template will be discarded once the process completes. Please refersh the page to select other templates </p>";
|
||||
model.selectedTemplateFolder = Session["PrivateTemplateName"].ToString();
|
||||
model.ForkGitHubRepo = "false";
|
||||
model.templateImage = "/Templates/TemplateImages/CodeFile.png";
|
||||
}
|
||||
}
|
||||
return View(model);
|
||||
}
|
||||
|
@ -518,9 +535,18 @@ namespace VstsDemoBuilder.Controllers
|
|||
{
|
||||
model.GitHubToken = Session["GitHubToken"].ToString();
|
||||
}
|
||||
if (Session["PrivateTemplateURL"] != null && Session["PrivateTemplateName"] != null)
|
||||
{
|
||||
model.PrivateTemplatePath = Session["PrivateTemplateURL"].ToString();
|
||||
Session["PrivateTemplateURL"] = null;
|
||||
Session["PrivateTemplateName"] = null;
|
||||
Session["PrivateTemplateOriginalName"] = null;
|
||||
Session["templateName"] = System.Configuration.ConfigurationManager.AppSettings["DefaultTemplate"];
|
||||
}
|
||||
projectService.AddMessage(model.id, string.Empty);
|
||||
projectService.AddMessage(model.id.ErrorId(), string.Empty);
|
||||
if (!string.IsNullOrEmpty(model.PrivateTemplatePath))
|
||||
bool whereIsTemplate = projectService.WhereDoseTemplateBelongTo(model.SelectedTemplate); // checking for private template existance
|
||||
if (!string.IsNullOrEmpty(model.PrivateTemplatePath) && whereIsTemplate) // if the template path exist and tempalte is present in private fodler
|
||||
{
|
||||
model.IsPrivatePath = true;
|
||||
}
|
||||
|
@ -620,6 +646,7 @@ namespace VstsDemoBuilder.Controllers
|
|||
{
|
||||
try
|
||||
{
|
||||
bool isTemplateBelongToPrivateFolder = projectService.WhereDoseTemplateBelongTo(selectedTemplate);
|
||||
if (!string.IsNullOrEmpty(selectedTemplate) && !string.IsNullOrEmpty(account) && !string.IsNullOrEmpty(token))
|
||||
{
|
||||
string accountName = string.Empty;
|
||||
|
@ -629,7 +656,12 @@ namespace VstsDemoBuilder.Controllers
|
|||
pat = token;
|
||||
string templatesFolder = string.Empty;
|
||||
string extensionJsonFile = string.Empty;
|
||||
if (string.IsNullOrEmpty(PrivatePath))
|
||||
if (isTemplateBelongToPrivateFolder)
|
||||
{
|
||||
templatesFolder = Session["PrivateTemplateURL"].ToString();
|
||||
extensionJsonFile = string.Format(templatesFolder + @"\Extensions.json");
|
||||
}
|
||||
else if (string.IsNullOrEmpty(PrivatePath))
|
||||
{
|
||||
templatesFolder = Server.MapPath("~") + @"\Templates\";
|
||||
extensionJsonFile = string.Format(templatesFolder + @"\{0}\Extensions.json", selectedTemplate);
|
||||
|
@ -640,8 +672,6 @@ namespace VstsDemoBuilder.Controllers
|
|||
extensionJsonFile = string.Format(templatesFolder + @"\Extensions.json");
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!(System.IO.File.Exists(extensionJsonFile)))
|
||||
{
|
||||
return Json(new { message = "Template not found", status = "false" }, JsonRequestBehavior.AllowGet);
|
||||
|
|
|
@ -13,5 +13,6 @@
|
|||
public string name { get; set; }
|
||||
|
||||
public string EnableExtractor { get; set; }
|
||||
public string TemplateURL { get; set; }
|
||||
}
|
||||
}
|
|
@ -223,8 +223,10 @@ namespace VstsDemoBuilder.Models
|
|||
public class PrivateTemplate
|
||||
{
|
||||
public string privateTemplateName { get; set; }
|
||||
public string privateTemplateOriginalName { get; set; }
|
||||
public string privateTemplatePath { get; set; }
|
||||
public string responseMessage { get; set; }
|
||||
public bool IsTemplateValid { get; set; }
|
||||
}
|
||||
|
||||
}
|
|
@ -21,5 +21,8 @@ namespace VstsDemoBuilder.ServiceInterfaces
|
|||
bool CheckForInstalledExtensions(string extensionJsonFile, string token, string account);
|
||||
|
||||
bool InstallExtensions(Project model, string accountName, string PAT);
|
||||
|
||||
bool WhereDoseTemplateBelongTo(string templatName);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1576,7 +1576,7 @@ namespace VstsDemoBuilder.Services
|
|||
string repositoryId = string.Empty;
|
||||
if (model.SelectedTemplate == "MyHealthClinic") { repositoryId = model.Environment.repositoryIdList["MyHealthClinic"]; }
|
||||
if (model.SelectedTemplate == "SmartHotel360") { repositoryId = model.Environment.repositoryIdList["PublicWeb"]; }
|
||||
else { repositoryId = model.Environment.repositoryIdList[model.SelectedTemplate]; }
|
||||
else { repositoryId = model.Environment.repositoryIdList.ContainsKey(model.SelectedTemplate) ? model.Environment.repositoryIdList[model.SelectedTemplate] : ""; }
|
||||
|
||||
pullRequestJsonPath = model.ReadJsonFile(pullRequestJsonPath);
|
||||
pullRequestJsonPath = pullRequestJsonPath.Replace("$reviewer$", model.Environment.UserUniqueId);
|
||||
|
@ -2764,5 +2764,24 @@ namespace VstsDemoBuilder.Services
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checkign for template existance - if template is present in private path, return true else return false
|
||||
/// </summary>
|
||||
/// <param name="templatName"></param>
|
||||
/// <returns></returns>
|
||||
public bool WhereDoseTemplateBelongTo(string templatName)
|
||||
{
|
||||
string privatePath = HostingEnvironment.MapPath("~") + @"\PrivateTemplates\";
|
||||
string privateTemplate = HostingEnvironment.MapPath("~") + @"\PrivateTemplates\" + templatName;
|
||||
//string publicPath = HostingEnvironment.MapPath("~") + @"\Templates\";
|
||||
string[] privatedirs = Directory.GetDirectories(privatePath);
|
||||
//string[] publicdirs = Directory.GetDirectories(privatePath);
|
||||
if (privatedirs.Contains(privateTemplate))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -187,7 +187,6 @@ namespace VstsDemoBuilder.Services
|
|||
webClient.DownloadFile(TemplateUrl, path);
|
||||
webClient.Dispose();
|
||||
}
|
||||
|
||||
templatePath = ExtractZipFile(path, templateName);
|
||||
|
||||
}
|
||||
|
|
|
@ -48,6 +48,10 @@
|
|||
<img src="~/Images/next.png" style="width:10px" />
|
||||
</a>
|
||||
</div>
|
||||
@if (!string.IsNullOrEmpty(ViewBag.resMessage))
|
||||
{
|
||||
<p style="text-align:center; color:red;">@ViewBag.resMessage</p>
|
||||
}
|
||||
<!--div class="demo-generator-feedback mt-auto text-center text-sm-left">
|
||||
<p>
|
||||
<ul>
|
||||
|
|
|
@ -215,13 +215,15 @@
|
|||
<input type="hidden" id="PrivateTemplateName" />
|
||||
<input type="hidden" id="PrivateTemplatePath" />
|
||||
<div class="alert alert-danger d-none" role="alert" id="ddlTemplates_Error">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="template-invoke mb-3 mt-1 col-lg-3">
|
||||
<button type="button" class="btn btn-primary" id="templateselection" style="padding-left:5px; padding-right:5px; width: 100%">
|
||||
Choose template
|
||||
</button>
|
||||
@if (Session["PrivateTemplateOriginalName"] == null)
|
||||
{
|
||||
<button type="button" class="btn btn-primary" id="templateselection" style="padding-left:5px; padding-right:5px; width: 100%">
|
||||
Choose template
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -240,30 +240,33 @@ namespace VstsRestAPI.Git
|
|||
{
|
||||
try
|
||||
{
|
||||
string[] pullRequest = new string[2];
|
||||
|
||||
using (var client = GetHttpClient())
|
||||
if (!string.IsNullOrEmpty(repositoryId))
|
||||
{
|
||||
var jsonContent = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
var method = new HttpMethod("POST");
|
||||
string[] pullRequest = new string[2];
|
||||
|
||||
var request = new HttpRequestMessage(method, Project + "/_apis/git/repositories/" + repositoryId + "/pullRequests?api-version=" + _configuration.VersionNumber) { Content = jsonContent };
|
||||
var response = client.SendAsync(request).Result;
|
||||
using (var client = GetHttpClient())
|
||||
{
|
||||
var jsonContent = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
var method = new HttpMethod("POST");
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var responseDetails = response.Content.ReadAsStringAsync().Result;
|
||||
JObject objResponse = JObject.Parse(responseDetails);
|
||||
pullRequest[0] = objResponse["pullRequestId"].ToString();
|
||||
pullRequest[1] = objResponse["title"].ToString();
|
||||
return pullRequest;
|
||||
}
|
||||
else
|
||||
{
|
||||
var errorMessage = response.Content.ReadAsStringAsync();
|
||||
string error = Utility.GeterroMessage(errorMessage.Result.ToString());
|
||||
this.LastFailureMessage = error;
|
||||
return pullRequest;
|
||||
var request = new HttpRequestMessage(method, Project + "/_apis/git/repositories/" + repositoryId + "/pullRequests?api-version=" + _configuration.VersionNumber) { Content = jsonContent };
|
||||
var response = client.SendAsync(request).Result;
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var responseDetails = response.Content.ReadAsStringAsync().Result;
|
||||
JObject objResponse = JObject.Parse(responseDetails);
|
||||
pullRequest[0] = objResponse["pullRequestId"].ToString();
|
||||
pullRequest[1] = objResponse["title"].ToString();
|
||||
return pullRequest;
|
||||
}
|
||||
else
|
||||
{
|
||||
var errorMessage = response.Content.ReadAsStringAsync();
|
||||
string error = Utility.GeterroMessage(errorMessage.Result.ToString());
|
||||
this.LastFailureMessage = error;
|
||||
return pullRequest;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче