From 1d16dfff7c6b85330a933974ad13f1115374347a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rog=C3=A9rio=20Rodrigues?= Date: Thu, 17 Jul 2025 14:34:58 -0300 Subject: [PATCH 1/4] Add ASP.NET Core web project --- README.md | 15 ++++++ src/ADOGenerator.Web/ADOGenerator.Web.csproj | 10 ++++ src/ADOGenerator.Web/Program.cs | 56 ++++++++++++++++++++ src/ADOGenerator.Web/appsettings.json | 46 ++++++++++++++++ 4 files changed, 127 insertions(+) create mode 100644 src/ADOGenerator.Web/ADOGenerator.Web.csproj create mode 100644 src/ADOGenerator.Web/Program.cs create mode 100644 src/ADOGenerator.Web/appsettings.json diff --git a/README.md b/README.md index 59a03be..0f16e1d 100644 --- a/README.md +++ b/README.md @@ -18,3 +18,18 @@ For more information on contributing, please visit the [contributor guide](./CON ## Contributors: - [Akshay Hosur](https://github.com/akshay-online) + +## Web Application + +A new ASP.NET Core project (`ADOGenerator.Web`) exposes minimal API endpoints that leverage the existing services to create projects or generate template artifacts. This application can be deployed to Azure App Service. + +### Running locally + +```bash +cd src/ADOGenerator.Web +dotnet run +``` + +### Deploying to Azure + +Publish the project and deploy the generated output to an Azure App Service instance using the Azure portal or the `az webapp` CLI commands. diff --git a/src/ADOGenerator.Web/ADOGenerator.Web.csproj b/src/ADOGenerator.Web/ADOGenerator.Web.csproj new file mode 100644 index 0000000..2194f47 --- /dev/null +++ b/src/ADOGenerator.Web/ADOGenerator.Web.csproj @@ -0,0 +1,10 @@ + + + net8.0 + disable + enable + + + + + diff --git a/src/ADOGenerator.Web/Program.cs b/src/ADOGenerator.Web/Program.cs new file mode 100644 index 0000000..bb0f21e --- /dev/null +++ b/src/ADOGenerator.Web/Program.cs @@ -0,0 +1,56 @@ +using ADOGenerator.IServices; +using ADOGenerator.Models; +using ADOGenerator.Services; + +var builder = WebApplication.CreateBuilder(args); + +// Add configuration and services +builder.Configuration.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); + +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); + +var app = builder.Build(); + +app.MapPost("/api/projects/create", (ProjectRequest request, IProjectService svc) => +{ + var model = new Project + { + id = Guid.NewGuid().ToString(), + accountName = request.Organization, + accessToken = request.AccessToken, + adoAuthScheme = request.AuthScheme, + ProjectName = request.ProjectName, + selectedTemplateFolder = request.TemplateFolder, + TemplateName = request.TemplateName, + isExtensionNeeded = request.InstallExtensions, + isAgreeTerms = request.InstallExtensions + }; + bool created = svc.CreateProjectEnvironment(model); + return Results.Ok(new { Success = created }); +}); + +app.MapPost("/api/projects/artifacts", (ArtifactRequest request, ITemplateService templateSvc) => +{ + var model = new Project + { + id = Guid.NewGuid().ToString(), + accountName = request.Organization, + ProjectName = request.ProjectName, + ProjectId = request.ProjectId, + accessToken = request.AccessToken, + adoAuthScheme = request.AuthScheme + }; + var result = templateSvc.GenerateTemplateArtifacts(model); + if (result.Item1) + { + return Results.Ok(new { Template = result.Item2, Location = result.Item3 }); + } + return Results.BadRequest(new { Message = "Artifact generation failed" }); +}); + +app.Run(); + +public record ProjectRequest(string Organization, string ProjectName, string TemplateName, string TemplateFolder, string AccessToken, string AuthScheme, bool InstallExtensions); +public record ArtifactRequest(string Organization, string ProjectName, string ProjectId, string AccessToken, string AuthScheme); diff --git a/src/ADOGenerator.Web/appsettings.json b/src/ADOGenerator.Web/appsettings.json new file mode 100644 index 0000000..ec5d773 --- /dev/null +++ b/src/ADOGenerator.Web/appsettings.json @@ -0,0 +1,46 @@ +{ + "AppSettings": { + "webpages:Version": "2.0.0.0", + "webpages:Enabled": "false", + "PreserveLoginUrl": "true", + "ClientValidationEnabled": "true", + "UnobtrusiveJavaScriptEnabled": "true", + "ProjectCreationVersion": "4.1", + "ProjectPropertyVersion": "4.1-preview", + "RepoVersion": "4.1", + "BuildVersion": "4.1", + "ReleaseVersion": "4.1", + "WikiVersion": "4.1", + "BoardVersion": "4.1", + "WorkItemsVersion": "4.1", + "QueriesVersion": "4.1", + "EndPointVersion": "4.1-preview.1", + "ExtensionVersion": "4.1", + "DashboardVersion": "4.1-preview.2", + "AgentQueueVersion": "4.1-preview", + "GetSourceCodeVersion": "4.1-preview", + "TestPlanVersion": "5.0", + "DefaultHost": "https://dev.azure.com/", + "ReleaseHost": "https://vsrm.dev.azure.com/", + "ExtensionHost": "https://extmgmt.dev.azure.com/", + "GetRelease": "4.1-preview.3", + "BaseAddress": "https://app.vssps.visualstudio.com/", + "GraphAPIHost": "https://vssps.dev.azure.com/", + "ProjectProperties": "4.1-preview.1", + "DefaultTemplate": "SmartHotel360", + "DeloymentGroup": "4.1-preview.1", + "GraphApiVersion": "4.1-preview.1", + "VariableGroupsApiVersion": "5.0-preview.1", + "AnalyticsKey": "", + "clientId": "", + "tenantId": "", + "scopes": "" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "System": "Warning", + "Microsoft": "Warning" + } + } +} From 0246bbfc97824dbd696663a5261f0739c4e9bb5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rog=C3=A9rio=20Rodrigues?= Date: Thu, 17 Jul 2025 15:29:48 -0300 Subject: [PATCH 2/4] Add simple web UI --- README.md | 2 + src/ADOGenerator.Web/ADOGenerator.Web.csproj | 8 +++ src/ADOGenerator.Web/Program.cs | 20 ++++++ src/ADOGenerator.Web/wwwroot/index.html | 70 +++++++++++++++++++ .../IServices/ITemplateService.cs | 1 + src/ADOGenerator/Services/TemplateService.cs | 21 ++++++ 6 files changed, 122 insertions(+) create mode 100644 src/ADOGenerator.Web/wwwroot/index.html diff --git a/README.md b/README.md index 0f16e1d..43f059f 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ For more information on contributing, please visit the [contributor guide](./CON A new ASP.NET Core project (`ADOGenerator.Web`) exposes minimal API endpoints that leverage the existing services to create projects or generate template artifacts. This application can be deployed to Azure App Service. +The web app also serves a simple UI that lets you choose a template and create projects. + ### Running locally ```bash diff --git a/src/ADOGenerator.Web/ADOGenerator.Web.csproj b/src/ADOGenerator.Web/ADOGenerator.Web.csproj index 2194f47..479819a 100644 --- a/src/ADOGenerator.Web/ADOGenerator.Web.csproj +++ b/src/ADOGenerator.Web/ADOGenerator.Web.csproj @@ -6,5 +6,13 @@ + + + + + + Templates\%(RecursiveDir)%(Filename)%(Extension) + PreserveNewest + diff --git a/src/ADOGenerator.Web/Program.cs b/src/ADOGenerator.Web/Program.cs index bb0f21e..3c15136 100644 --- a/src/ADOGenerator.Web/Program.cs +++ b/src/ADOGenerator.Web/Program.cs @@ -1,6 +1,7 @@ using ADOGenerator.IServices; using ADOGenerator.Models; using ADOGenerator.Services; +using System.Linq; var builder = WebApplication.CreateBuilder(args); @@ -11,8 +12,27 @@ builder.Services.AddSingleton(); builder.Services.AddSingleton(); +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + var app = builder.Build(); +app.UseDefaultFiles(); +app.UseStaticFiles(); + +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.MapGet("/api/templates", (ITemplateService svc) => +{ + var list = svc.GetAvailableTemplates() + .Select(t => new { t.Name, t.TemplateFolder, t.Description }); + return Results.Ok(list); +}); + app.MapPost("/api/projects/create", (ProjectRequest request, IProjectService svc) => { var model = new Project diff --git a/src/ADOGenerator.Web/wwwroot/index.html b/src/ADOGenerator.Web/wwwroot/index.html new file mode 100644 index 0000000..721a674 --- /dev/null +++ b/src/ADOGenerator.Web/wwwroot/index.html @@ -0,0 +1,70 @@ + + + + + ADO Generator + + + +

Create Azure DevOps Project

+
+ + + + + + +
+

+
+
+
diff --git a/src/ADOGenerator/IServices/ITemplateService.cs b/src/ADOGenerator/IServices/ITemplateService.cs
index 4e497d7..59c822f 100644
--- a/src/ADOGenerator/IServices/ITemplateService.cs
+++ b/src/ADOGenerator/IServices/ITemplateService.cs
@@ -7,5 +7,6 @@ public interface ITemplateService
         bool AnalyzeProject(Project model);
         bool CheckTemplateExists(Project model);
         (bool,string,string) GenerateTemplateArtifacts(Project model);
+        IEnumerable GetAvailableTemplates();
     }
 }
diff --git a/src/ADOGenerator/Services/TemplateService.cs b/src/ADOGenerator/Services/TemplateService.cs
index 608c8b3..113664b 100644
--- a/src/ADOGenerator/Services/TemplateService.cs
+++ b/src/ADOGenerator/Services/TemplateService.cs
@@ -2,10 +2,13 @@
 using ADOGenerator.Models;
 using ADOGenerator.Services;
 using Microsoft.Extensions.Configuration;
+using Newtonsoft.Json;
 using RestAPI.Extractor;
 using RestAPI.ProjectsAndTeams;
 using RestAPI;
 using ADOGenerator;
+using System.IO;
+using System.Linq;
 
 public class TemplateService : ITemplateService
 {
@@ -101,6 +104,24 @@ public bool CheckTemplateExists(Project model)
         }
     }
 
+    public IEnumerable GetAvailableTemplates()
+    {
+        var templatesPath = Path.Combine(Directory.GetCurrentDirectory(), "Templates", "TemplateSetting.json");
+        if (!File.Exists(templatesPath))
+        {
+            return Enumerable.Empty();
+        }
+
+        var json = File.ReadAllText(templatesPath);
+        var parsed = JsonConvert.DeserializeObject(json);
+        if (parsed?.GroupwiseTemplates == null)
+        {
+            return Enumerable.Empty();
+        }
+
+        return parsed.GroupwiseTemplates.SelectMany(g => g.Template);
+    }
+
     private void LogAnalysisResults(Project model, ExtractorAnalysis analysis)
     {
         model.id.AddMessage(Environment.NewLine + "-------------------------------------------------------------------");

From b4ad022f5aa3f1c3634dae2da60bdd634628303f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rog=C3=A9rio=20Rodrigues?= 
Date: Thu, 17 Jul 2025 17:23:52 -0300
Subject: [PATCH 3/4] Use AppContext.BaseDirectory for template path

---
 src/ADOGenerator/Services/TemplateService.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/ADOGenerator/Services/TemplateService.cs b/src/ADOGenerator/Services/TemplateService.cs
index 113664b..36eaeb7 100644
--- a/src/ADOGenerator/Services/TemplateService.cs
+++ b/src/ADOGenerator/Services/TemplateService.cs
@@ -106,7 +106,7 @@ public bool CheckTemplateExists(Project model)
 
     public IEnumerable GetAvailableTemplates()
     {
-        var templatesPath = Path.Combine(Directory.GetCurrentDirectory(), "Templates", "TemplateSetting.json");
+        var templatesPath = Path.Combine(AppContext.BaseDirectory, "Templates", "TemplateSetting.json");
         if (!File.Exists(templatesPath))
         {
             return Enumerable.Empty();

From b85f5dce9e8e79dac62ff28adfee3582ecbcf62a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rog=C3=A9rio=20Rodrigues?= 
Date: Thu, 17 Jul 2025 22:01:02 -0300
Subject: [PATCH 4/4] Convert web project to MVC structure

---
 .../Controllers/HomeController.cs             | 26 +++++++
 .../Controllers/ProjectsController.cs         | 62 ++++++++++++++++
 .../Controllers/TemplatesController.cs        | 25 +++++++
 src/ADOGenerator.Web/Program.cs               | 53 ++------------
 .../ViewModels/ProjectViewModel.cs            | 18 +++++
 src/ADOGenerator.Web/Views/Home/Index.cshtml  | 42 +++++++++++
 .../Views/_ViewImports.cshtml                 |  1 +
 src/ADOGenerator.Web/Views/_ViewStart.cshtml  |  3 +
 src/ADOGenerator.Web/wwwroot/index.html       | 70 -------------------
 src/ADOGenerator/Services/ProjectService.cs   | 10 +--
 10 files changed, 188 insertions(+), 122 deletions(-)
 create mode 100644 src/ADOGenerator.Web/Controllers/HomeController.cs
 create mode 100644 src/ADOGenerator.Web/Controllers/ProjectsController.cs
 create mode 100644 src/ADOGenerator.Web/Controllers/TemplatesController.cs
 create mode 100644 src/ADOGenerator.Web/ViewModels/ProjectViewModel.cs
 create mode 100644 src/ADOGenerator.Web/Views/Home/Index.cshtml
 create mode 100644 src/ADOGenerator.Web/Views/_ViewImports.cshtml
 create mode 100644 src/ADOGenerator.Web/Views/_ViewStart.cshtml
 delete mode 100644 src/ADOGenerator.Web/wwwroot/index.html

diff --git a/src/ADOGenerator.Web/Controllers/HomeController.cs b/src/ADOGenerator.Web/Controllers/HomeController.cs
new file mode 100644
index 0000000..0b1e418
--- /dev/null
+++ b/src/ADOGenerator.Web/Controllers/HomeController.cs
@@ -0,0 +1,26 @@
+using ADOGenerator.IServices;
+using ADOGenerator.Web.ViewModels;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Rendering;
+using System.Linq;
+
+namespace ADOGenerator.Web.Controllers
+{
+    public class HomeController : Controller
+    {
+        private readonly ITemplateService _templateService;
+
+        public HomeController(ITemplateService templateService)
+        {
+            _templateService = templateService;
+        }
+
+        public IActionResult Index()
+        {
+            var vm = new ProjectViewModel();
+            vm.TemplateOptions = _templateService.GetAvailableTemplates()
+                .Select(t => new SelectListItem { Text = t.Name, Value = t.TemplateFolder });
+            return View(vm);
+        }
+    }
+}
diff --git a/src/ADOGenerator.Web/Controllers/ProjectsController.cs b/src/ADOGenerator.Web/Controllers/ProjectsController.cs
new file mode 100644
index 0000000..608e7cd
--- /dev/null
+++ b/src/ADOGenerator.Web/Controllers/ProjectsController.cs
@@ -0,0 +1,62 @@
+using ADOGenerator.IServices;
+using ADOGenerator.Models;
+using ADOGenerator.Web.ViewModels;
+using Microsoft.AspNetCore.Mvc;
+
+namespace ADOGenerator.Web.Controllers
+{
+    [Route("api/[controller]")]
+    [ApiController]
+    public class ProjectsController : Controller
+    {
+        private readonly IProjectService _projectService;
+        private readonly ITemplateService _templateService;
+
+        public ProjectsController(IProjectService projectService, ITemplateService templateService)
+        {
+            _projectService = projectService;
+            _templateService = templateService;
+        }
+
+        [HttpPost("create")]
+        public IActionResult Create([FromBody] ProjectViewModel request)
+        {
+            var model = new Project
+            {
+                id = Guid.NewGuid().ToString(),
+                accountName = request.Organization,
+                accessToken = request.AccessToken,
+                adoAuthScheme = request.AuthScheme,
+                ProjectName = request.ProjectName,
+                selectedTemplateFolder = request.TemplateFolder,
+                TemplateName = request.TemplateName,
+                isExtensionNeeded = request.InstallExtensions,
+                isAgreeTerms = request.InstallExtensions
+            };
+            bool created = _projectService.CreateProjectEnvironment(model);
+            return Ok(new { Success = created });
+        }
+
+        [HttpPost("artifacts")]
+        public IActionResult Artifacts([FromBody] ArtifactRequest request)
+        {
+            var model = new Project
+            {
+                id = Guid.NewGuid().ToString(),
+                accountName = request.Organization,
+                ProjectName = request.ProjectName,
+                ProjectId = request.ProjectId,
+                accessToken = request.AccessToken,
+                adoAuthScheme = request.AuthScheme
+            };
+            var result = _templateService.GenerateTemplateArtifacts(model);
+            if (result.Item1)
+            {
+                return Ok(new { Template = result.Item2, Location = result.Item3 });
+            }
+            return BadRequest(new { Message = "Artifact generation failed" });
+        }
+    }
+
+    public record ArtifactRequest(string Organization, string ProjectName, string ProjectId, string AccessToken, string AuthScheme);
+}
diff --git a/src/ADOGenerator.Web/Controllers/TemplatesController.cs b/src/ADOGenerator.Web/Controllers/TemplatesController.cs
new file mode 100644
index 0000000..aa5acf9
--- /dev/null
+++ b/src/ADOGenerator.Web/Controllers/TemplatesController.cs
@@ -0,0 +1,25 @@
+using ADOGenerator.IServices;
+using Microsoft.AspNetCore.Mvc;
+using System.Linq;
+
+namespace ADOGenerator.Web.Controllers
+{
+    [Route("api/[controller]")]
+    [ApiController]
+    public class TemplatesController : Controller
+    {
+        private readonly ITemplateService _templateService;
+        public TemplatesController(ITemplateService templateService)
+        {
+            _templateService = templateService;
+        }
+
+        [HttpGet]
+        public IActionResult Get()
+        {
+            var list = _templateService.GetAvailableTemplates()
+                .Select(t => new { t.Name, t.TemplateFolder, t.Description });
+            return Ok(list);
+        }
+    }
+}
diff --git a/src/ADOGenerator.Web/Program.cs b/src/ADOGenerator.Web/Program.cs
index 3c15136..9216645 100644
--- a/src/ADOGenerator.Web/Program.cs
+++ b/src/ADOGenerator.Web/Program.cs
@@ -1,7 +1,6 @@
 using ADOGenerator.IServices;
 using ADOGenerator.Models;
 using ADOGenerator.Services;
-using System.Linq;
 
 var builder = WebApplication.CreateBuilder(args);
 
@@ -12,13 +11,14 @@
 builder.Services.AddSingleton();
 builder.Services.AddSingleton();
 
+builder.Services.AddControllersWithViews();
 builder.Services.AddEndpointsApiExplorer();
 builder.Services.AddSwaggerGen();
 
 var app = builder.Build();
 
-app.UseDefaultFiles();
 app.UseStaticFiles();
+app.UseRouting();
 
 if (app.Environment.IsDevelopment())
 {
@@ -26,51 +26,10 @@
     app.UseSwaggerUI();
 }
 
-app.MapGet("/api/templates", (ITemplateService svc) =>
-{
-    var list = svc.GetAvailableTemplates()
-        .Select(t => new { t.Name, t.TemplateFolder, t.Description });
-    return Results.Ok(list);
-});
+app.UseAuthorization();
 
-app.MapPost("/api/projects/create", (ProjectRequest request, IProjectService svc) =>
-{
-    var model = new Project
-    {
-        id = Guid.NewGuid().ToString(),
-        accountName = request.Organization,
-        accessToken = request.AccessToken,
-        adoAuthScheme = request.AuthScheme,
-        ProjectName = request.ProjectName,
-        selectedTemplateFolder = request.TemplateFolder,
-        TemplateName = request.TemplateName,
-        isExtensionNeeded = request.InstallExtensions,
-        isAgreeTerms = request.InstallExtensions
-    };
-    bool created = svc.CreateProjectEnvironment(model);
-    return Results.Ok(new { Success = created });
-});
-
-app.MapPost("/api/projects/artifacts", (ArtifactRequest request, ITemplateService templateSvc) =>
-{
-    var model = new Project
-    {
-        id = Guid.NewGuid().ToString(),
-        accountName = request.Organization,
-        ProjectName = request.ProjectName,
-        ProjectId = request.ProjectId,
-        accessToken = request.AccessToken,
-        adoAuthScheme = request.AuthScheme
-    };
-    var result = templateSvc.GenerateTemplateArtifacts(model);
-    if (result.Item1)
-    {
-        return Results.Ok(new { Template = result.Item2, Location = result.Item3 });
-    }
-    return Results.BadRequest(new { Message = "Artifact generation failed" });
-});
+app.MapControllerRoute(
+    name: "default",
+    pattern: "{controller=Home}/{action=Index}/{id?}");
 
 app.Run();
-
-public record ProjectRequest(string Organization, string ProjectName, string TemplateName, string TemplateFolder, string AccessToken, string AuthScheme, bool InstallExtensions);
-public record ArtifactRequest(string Organization, string ProjectName, string ProjectId, string AccessToken, string AuthScheme);
diff --git a/src/ADOGenerator.Web/ViewModels/ProjectViewModel.cs b/src/ADOGenerator.Web/ViewModels/ProjectViewModel.cs
new file mode 100644
index 0000000..e0b28e0
--- /dev/null
+++ b/src/ADOGenerator.Web/ViewModels/ProjectViewModel.cs
@@ -0,0 +1,18 @@
+using Microsoft.AspNetCore.Mvc.Rendering;
+using System.Collections.Generic;
+
+namespace ADOGenerator.Web.ViewModels
+{
+    public class ProjectViewModel
+    {
+        public string Organization { get; set; }
+        public string ProjectName { get; set; }
+        public string TemplateName { get; set; }
+        public string TemplateFolder { get; set; }
+        public string AccessToken { get; set; }
+        public string AuthScheme { get; set; } = "pat";
+        public bool InstallExtensions { get; set; } = true;
+        public IEnumerable TemplateOptions { get; set; } = new List();
+        public string ResultMessage { get; set; }
+    }
+}
diff --git a/src/ADOGenerator.Web/Views/Home/Index.cshtml b/src/ADOGenerator.Web/Views/Home/Index.cshtml
new file mode 100644
index 0000000..8d4462e
--- /dev/null
+++ b/src/ADOGenerator.Web/Views/Home/Index.cshtml
@@ -0,0 +1,42 @@
+@model ADOGenerator.Web.ViewModels.ProjectViewModel
+
+
+
+    
+    ADO Generator
+    
+
+
+

Create Azure DevOps Project

+
+ + + + + + + +
+@if (Model.ResultMessage != null) +{ +
@Model.ResultMessage
+} + + diff --git a/src/ADOGenerator.Web/Views/_ViewImports.cshtml b/src/ADOGenerator.Web/Views/_ViewImports.cshtml new file mode 100644 index 0000000..a757b41 --- /dev/null +++ b/src/ADOGenerator.Web/Views/_ViewImports.cshtml @@ -0,0 +1 @@ +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/src/ADOGenerator.Web/Views/_ViewStart.cshtml b/src/ADOGenerator.Web/Views/_ViewStart.cshtml new file mode 100644 index 0000000..9d06493 --- /dev/null +++ b/src/ADOGenerator.Web/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = null; +} diff --git a/src/ADOGenerator.Web/wwwroot/index.html b/src/ADOGenerator.Web/wwwroot/index.html deleted file mode 100644 index 721a674..0000000 --- a/src/ADOGenerator.Web/wwwroot/index.html +++ /dev/null @@ -1,70 +0,0 @@ - - - - - ADO Generator - - - -

Create Azure DevOps Project

-
- - - - - - -
-

-
-
-
diff --git a/src/ADOGenerator/Services/ProjectService.cs b/src/ADOGenerator/Services/ProjectService.cs
index dab8f5a..c14ecdb 100644
--- a/src/ADOGenerator/Services/ProjectService.cs
+++ b/src/ADOGenerator/Services/ProjectService.cs
@@ -183,7 +183,7 @@ public async Task> SelectProject(string accessToken, HttpResponseMe
         public string GetJsonFilePath(bool IsPrivate, string TemplateFolder, string TemplateName, string FileName = "")
         {
             string filePath = string.Empty;
-            filePath = string.Format(Path.Combine(Directory.GetCurrentDirectory(), "Templates", TemplateName, FileName));
+            filePath = Path.Combine(AppContext.BaseDirectory, "Templates", TemplateName, FileName);
             return filePath;
         }
 
@@ -366,7 +366,7 @@ public bool CreateProjectEnvironment(Project model)
                 Console.WriteLine("Error in reading project template file:" + ex.Message);
             }
             //create team project
-            string jsonProject = model.ReadJsonFile(Path.Combine(Directory.GetCurrentDirectory(), "Templates", "CreateProject.json"));
+            string jsonProject = model.ReadJsonFile(Path.Combine(AppContext.BaseDirectory, "Templates", "CreateProject.json"));
             jsonProject = jsonProject.Replace("$projectName$", model.ProjectName).Replace("$processTemplateId$", processTemplateId);
 
             Projects proj = new Projects(_projectCreationVersion);
@@ -2260,7 +2260,7 @@ void CreateQueryAndWidgets(Project model, List listQueries, ADOConfigura
                 bool isFolderCreated = false;
                 if (!string.IsNullOrEmpty(teamName))
                 {
-                    string createQueryFolderJson = File.ReadAllText(Path.Combine(Directory.GetCurrentDirectory(), "PreSetting", "CreateQueryFolder.json"));
+                    string createQueryFolderJson = File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "PreSetting", "CreateQueryFolder.json"));
                     createQueryFolderJson = createQueryFolderJson.Replace("$TeamName$", teamName);
                     QueryResponse createFolderResponse = _newobjQuery.CreateQuery(model.ProjectName, createQueryFolderJson);
                     isFolderCreated = createFolderResponse.id != null ? true : false;
@@ -2787,7 +2787,7 @@ string GetTemplateMessage(string TemplateName)
             {
                 string groupDetails = "";
                 TemplateSelection.Templates templates = new TemplateSelection.Templates();
-                string templatesPath = ""; templatesPath = Path.Combine(Directory.GetCurrentDirectory(), "Templates");
+                string templatesPath = Path.Combine(AppContext.BaseDirectory, "Templates");
                 if (File.Exists(templatesPath + "TemplateSetting.json"))
                 {
                     groupDetails = File.ReadAllText(templatesPath + "\\TemplateSetting.json");
@@ -2889,7 +2889,7 @@ void CreateVaribaleGroups(Project model, ADOConfiguration _variableGroups)
         public bool WhereDoseTemplateBelongTo(string templatName)
         {
 
-            string privatePath = Path.Combine(Directory.GetCurrentDirectory(), "PrivateTemplates");
+            string privatePath = Path.Combine(AppContext.BaseDirectory, "PrivateTemplates");
             string privateTemplate = Path.Combine(privatePath, templatName);
 
             if (!Directory.Exists(privatePath))