From 7a64ae639402f53a8078f42b98d7b4d47246836b Mon Sep 17 00:00:00 2001 From: Coen van den Munckhof Date: Mon, 1 Apr 2024 22:41:06 +0200 Subject: [PATCH 1/7] WIP --- src/RepoM.Api/EnsureStartup.cs | 46 ++++++++++++++++++++++++++++++++++ src/RepoM.App/App.xaml.cs | 4 +++ src/RepoM.App/Bootstrapper.cs | 2 ++ 3 files changed, 52 insertions(+) create mode 100644 src/RepoM.Api/EnsureStartup.cs diff --git a/src/RepoM.Api/EnsureStartup.cs b/src/RepoM.Api/EnsureStartup.cs new file mode 100644 index 00000000..a31d0177 --- /dev/null +++ b/src/RepoM.Api/EnsureStartup.cs @@ -0,0 +1,46 @@ +namespace RepoM.Api; + +using System; +using System.Collections; +using System.Configuration; +using System.IO; +using System.IO.Abstractions; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using RepoM.Core.Plugin.Common; + +public class EnsureStartup +{ + private readonly IFileSystem _fileSystem; + private readonly IAppDataPathProvider _appDataProvider; + private readonly ILogger _logger; + + public EnsureStartup(IFileSystem fileSystem, IAppDataPathProvider appDataProvider, ILogger logger) + { + _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); + _appDataProvider = appDataProvider ?? throw new ArgumentNullException(nameof(appDataProvider)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + + public async Task EnsureFilesAsync() + { + var filename = Path.Combine(_appDataProvider.AppDataPath, "RepositoryActionsV2.yaml"); + + if (!_fileSystem.File.Exists(filename)) + { + await TryCreateAsync(filename, new MemoryStream()).ConfigureAwait(false); + } + + if (!_fileSystem.File.Exists(filename)) + { + throw new FileNotFoundException(filename); + } + } + + private async Task TryCreateAsync(string filename, Stream content) + { + using var ms = new MemoryStream(); + await content.CopyToAsync(ms).ConfigureAwait(false); + await _fileSystem.File.WriteAllBytesAsync(filename, ms.ToArray()).ConfigureAwait(false); + } +} \ No newline at end of file diff --git a/src/RepoM.App/App.xaml.cs b/src/RepoM.App/App.xaml.cs index def68214..2e6b515b 100644 --- a/src/RepoM.App/App.xaml.cs +++ b/src/RepoM.App/App.xaml.cs @@ -22,6 +22,7 @@ namespace RepoM.App; using Container = SimpleInjector.Container; using RepoM.App.Services.HotKey; using Serilog.Enrichers; +using RepoM.Api; /// /// Interaction logic for App.xaml @@ -75,6 +76,9 @@ protected override async void OnStartup(StartupEventArgs e) Bootstrapper.Container.Verify(SimpleInjector.VerificationOption.VerifyAndDiagnose); #endif + EnsureStartup ensureStartup = Bootstrapper.Container.GetInstance(); + await ensureStartup.EnsureFilesAsync().ConfigureAwait(true); + UseRepositoryMonitor(Bootstrapper.Container); _ = Bootstrapper.Container.GetInstance(); // not sure if this is required. diff --git a/src/RepoM.App/Bootstrapper.cs b/src/RepoM.App/Bootstrapper.cs index a5b72a37..49b91d09 100644 --- a/src/RepoM.App/Bootstrapper.cs +++ b/src/RepoM.App/Bootstrapper.cs @@ -109,6 +109,8 @@ public static void RegisterServices(IFileSystem fileSystem) Container.RegisterSingleton(); Container.RegisterSingleton(); + + Container.RegisterSingleton(); } public static async Task RegisterPlugins( From 5dcbca9df942576b8fc89846b67b30b386433a8f Mon Sep 17 00:00:00 2001 From: Coen van den Munckhof Date: Mon, 1 Apr 2024 23:39:58 +0200 Subject: [PATCH 2/7] wip --- src/RepoM.Api/EnsureStartup.cs | 24 +- src/RepoM.Api/RepoM.Api.csproj | 7 + src/RepoM.Api/Resources/EmbeddedResources.cs | 23 + src/RepoM.Api/Resources/RepoM.Filtering.yaml | 18 + src/RepoM.Api/Resources/RepoM.Sorting.yaml | 93 +++ .../Resources/RepositoryActions.yaml | 46 ++ .../Resources/RepositoryActionsV2.yaml | 612 ++++++++++++++++++ 7 files changed, 812 insertions(+), 11 deletions(-) create mode 100644 src/RepoM.Api/Resources/EmbeddedResources.cs create mode 100644 src/RepoM.Api/Resources/RepoM.Filtering.yaml create mode 100644 src/RepoM.Api/Resources/RepoM.Sorting.yaml create mode 100644 src/RepoM.Api/Resources/RepositoryActions.yaml create mode 100644 src/RepoM.Api/Resources/RepositoryActionsV2.yaml diff --git a/src/RepoM.Api/EnsureStartup.cs b/src/RepoM.Api/EnsureStartup.cs index a31d0177..6b73a05b 100644 --- a/src/RepoM.Api/EnsureStartup.cs +++ b/src/RepoM.Api/EnsureStartup.cs @@ -1,39 +1,41 @@ namespace RepoM.Api; using System; -using System.Collections; -using System.Configuration; using System.IO; using System.IO.Abstractions; using System.Threading.Tasks; -using Microsoft.Extensions.Logging; +using RepoM.Api.Resources; using RepoM.Core.Plugin.Common; public class EnsureStartup { private readonly IFileSystem _fileSystem; private readonly IAppDataPathProvider _appDataProvider; - private readonly ILogger _logger; - public EnsureStartup(IFileSystem fileSystem, IAppDataPathProvider appDataProvider, ILogger logger) + public EnsureStartup(IFileSystem fileSystem, IAppDataPathProvider appDataProvider) { _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); _appDataProvider = appDataProvider ?? throw new ArgumentNullException(nameof(appDataProvider)); - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } public async Task EnsureFilesAsync() { - var filename = Path.Combine(_appDataProvider.AppDataPath, "RepositoryActionsV2.yaml"); + await CheckOrCreateAsync("RepositoryActionsV2.yaml", () => EmbeddedResources.GetRepositoryActionsV2Yaml()); + } + + private async Task CheckOrCreateAsync(string filename, Func func) + { + var fullFilename = Path.Combine(_appDataProvider.AppDataPath, filename); - if (!_fileSystem.File.Exists(filename)) + if (!_fileSystem.File.Exists(fullFilename)) { - await TryCreateAsync(filename, new MemoryStream()).ConfigureAwait(false); + await using Stream stream = func.Invoke(); + await TryCreateAsync(fullFilename, stream).ConfigureAwait(false); } - if (!_fileSystem.File.Exists(filename)) + if (!_fileSystem.File.Exists(fullFilename)) { - throw new FileNotFoundException(filename); + throw new FileNotFoundException(fullFilename); } } diff --git a/src/RepoM.Api/RepoM.Api.csproj b/src/RepoM.Api/RepoM.Api.csproj index 2575862a..982ccd84 100644 --- a/src/RepoM.Api/RepoM.Api.csproj +++ b/src/RepoM.Api/RepoM.Api.csproj @@ -20,4 +20,11 @@ + + + + + + + diff --git a/src/RepoM.Api/Resources/EmbeddedResources.cs b/src/RepoM.Api/Resources/EmbeddedResources.cs new file mode 100644 index 00000000..9f5ef2c9 --- /dev/null +++ b/src/RepoM.Api/Resources/EmbeddedResources.cs @@ -0,0 +1,23 @@ +namespace RepoM.Api.Resources; + +using System.IO; +using System.Linq; +using System.Reflection; +using LibGit2Sharp; + +internal static class EmbeddedResources +{ + private static readonly Assembly _assembly = typeof(EmbeddedResources).Assembly; + private static readonly string _namespace = typeof(EmbeddedResources).Namespace!; + + public static Stream GetRepositoryActionsV2Yaml() + { + return ResolveFromAssembly("RepositoryActionsV2.yaml") ?? throw new NotFoundException("File not found."); + } + + private static Stream? ResolveFromAssembly(string relativeFilename) + { + var embeddedFilename = $"{_namespace}.{relativeFilename}"; + return _assembly.GetManifestResourceStream(embeddedFilename); + } +} \ No newline at end of file diff --git a/src/RepoM.Api/Resources/RepoM.Filtering.yaml b/src/RepoM.Api/Resources/RepoM.Filtering.yaml new file mode 100644 index 00000000..62335d1e --- /dev/null +++ b/src/RepoM.Api/Resources/RepoM.Filtering.yaml @@ -0,0 +1,18 @@ +Work: + name: Work + description: Work filtering + always-visible: + kind: query@1 + query: is:pinned + filter: + kind: query@1 + query: tag:work +Private: + name: Private + description: Private repositories + always-visible: + kind: query@1 + query: RepoM OR is:pinned + filter: + kind: query@1 + query: (-tag:work OR tag:prive) \ No newline at end of file diff --git a/src/RepoM.Api/Resources/RepoM.Sorting.yaml b/src/RepoM.Api/Resources/RepoM.Sorting.yaml new file mode 100644 index 00000000..8985b78e --- /dev/null +++ b/src/RepoM.Api/Resources/RepoM.Sorting.yaml @@ -0,0 +1,93 @@ +Work: + type: composition-comparer@1 + comparers: + - type: score-comparer@1 + score-provider: + type: is-pinned-scorer@1 + weight: 1 + - type: score-comparer@1 + score-provider: + type: tag-scorer@1 + weight: 1 + tag: Team1 + - type: score-comparer@1 + score-provider: + type: tag-scorer@1 + weight: 1 + tag: Work + - type: az-comparer@1 + property: Name + weight: 1 +Work Dynamic: + type: composition-comparer@1 + comparers: + - type: score-comparer@1 + score-provider: + type: is-pinned-scorer@1 + weight: 1 + - type: score-comparer@1 + score-provider: + type: tag-scorer@1 + weight: 1 + tag: Team1 + - type: score-comparer@1 + score-provider: + type: usage-scorer@1 + max-score: 20 + windows: + - until: 00:15:00 + weight: 4 + max-items: 10 + - until: 01:00:00 + weight: 3 + max-items: 5 + - until: 24:00:00 + weight: 2 + max-items: 5 + - until: 168:00:00 + weight: 1 + max-items: 10 + - type: last-opened-comparer@1 + weight: 1 + - type: score-comparer@1 + score-provider: + type: tag-scorer@1 + weight: 1 + tag: Work + - type: az-comparer@1 + property: Name + weight: 1 +Prive: + type: composition-comparer@1 + comparers: + - type: score-comparer@1 + score-provider: + type: is-pinned-scorer@1 + weight: 1 + - type: score-comparer@1 + score-provider: + type: tag-scorer@1 + weight: 1 + tag: Prive + - type: score-comparer@1 + score-provider: + type: usage-scorer@1 + max-score: 20 + windows: + - until: 00:15:00 + weight: 4 + max-items: 10 + - until: 01:00:00 + weight: 3 + max-items: 5 + - until: 24:00:00 + weight: 2 + max-items: 5 + - until: 168:00:00 + weight: 1 + max-items: 10 + - type: last-opened-comparer@1 + weight: 1 + - type: az-comparer@1 + property: Name + weight: 1 \ No newline at end of file diff --git a/src/RepoM.Api/Resources/RepositoryActions.yaml b/src/RepoM.Api/Resources/RepositoryActions.yaml new file mode 100644 index 00000000..378b6d39 --- /dev/null +++ b/src/RepoM.Api/Resources/RepositoryActions.yaml @@ -0,0 +1,46 @@ +version: 1 + +variables: +- name: IsRepoM + value: '{empty}{StringContains({Repository.SafePath}, "RepoM")}' + +repository-specific-env-files: +- filename: '{Repository.SafePath}{slash}.git{slash}repom.env' + when: '{var.IsRepoM}' +- filename: '{Repository.SafePath}{slash}repom.env' + when: true + +repository-specific-config-files: +- filename: '{Repository.SafePath}{slash}.git{slash}RepositoryActions.json' +- filename: '{Repository.SafePath}{slash}RepositoryActions.json' + +repository-tags: +- tag: Work + when: '{StringContains({Repository.SafePath}, "Work")}' +- tag: Private + when: '{Not({StringContains({Repository.SafePath}, "Work")})}' + +repository-actions: + variables: + - name: key + value: abc + actions: + - type: command@1 + variables: + - name: Test2 + value: -- T3sT2 + enabled: true + name: '{OpenIn} Windows File Explorer' + command: '"{Repository.SafePath}"' + active: true + + - type: separator@1 + - type: browse-repository@1 + - type: separator@1 + - type: git-fetch@1 + - type: git-pull@1 + - type: git-push@1 + - type: git-checkout@1 + - type: separator@1 + - type: ignore-repositories@1 + - type: separator@1 \ No newline at end of file diff --git a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml new file mode 100644 index 00000000..6ab9f0e0 --- /dev/null +++ b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml @@ -0,0 +1,612 @@ +context: +- type: evaluate-script@1 + content: |- + func is_null(input) + ret input == null + end + + func translate(input) + ret input + end + + func get_filename(path) + ret path | string.split("\\") | array.last + end + + func remotes_contain_inner(remotes, url_part) + urls = remotes | array.map "url" + filtered = array.filter(urls, do + ret string.contains($0, url_part) + end) + ret array.size(filtered) > 0; + end + + func remotes_contain(url_part) + ret remotes_contain_inner(repository.remotes, url_part) + end + + func get_remote_origin() + remotes = repository.remotes; + filtered = array.filter(remotes, do + remote = $0; + ret remote.key == "origin" + end) + ret array.first(filtered); + end + + func get_remote_origin_name() + remote = get_remote_origin(); + ret remote?.name; + end + + func repository_path_contains(path) + ret repository.linux_path | string.contains path + end + + func is_feature_branch() + ret repository.branch | string.starts_with "feature/" + end + + func sanitize_feature_branch_name() + ret repository.branch | string.replace "feature/" "" | string.strip + end + + remote_name_origin = get_remote_origin_name(); + is_work_repository = remotes_contain("BDO-NL"); + is_bdo_tis_repository = is_work_repository && file.file_exists(repository.linux_path + "/.azuredevops/Pipelines/gated.yml") + is_github_repository = remotes_contain("github.com"); + is_integration_test_framework = remotes_contain("IntegrationServices.IntegrationTestFramework"); + is_end_to_end_api_test_framework = remotes_contain("EndToEndApiTestFramework"); + solution_files = file.find_files(repository.linux_path, "*.sln"); + solution_file = array.first(solution_files); + system_test_csproj_files = file.find_files(repository.linux_path, "*.SystemTests.csproj"); + smoke_tests_csproj_files = file.find_files(repository.linux_path, "*.SmokeTests.csproj"); + + exe_vs_code = env.LocalAppData + "/Programs/Microsoft VS Code/code.exe"; + exe_heidi_sql = "C:/StandAloneProgramFiles/HeidiSQL_12.3_64_Portable/heidisql.exe"; + exe_ssms = "C:/Program Files (x86)/Microsoft SQL Server Management Studio 18/Common7/IDE/Ssms.exe"; + exe_monitoring = "C:/Projects/Private/git/SimpleTestRunner/src/TestRunner.Application/bin/Release/net6.0-windows/TestRunner.Application.exe" + + path_repo_tis_wat = `C:\Users\Munckhof CJJ\OneDrive - BDO\BDO\TisWatConfig\` + remote_name_origin; + path_bdo_repo_root = `C:\Projects\Bdo\git\`; + + url_bdo_devops = "https://dev.azure.com/tfs-bdonl/BDO-NL/"; + +- root_path_repom: C:\\Users\\Munckhof CJJ\\OneDrive - BDO\\BDO\\RepoM\\ + +# Specific var files +- type: render-variable@1 + name: repo_docs_directory + value: 'G:\\My Drive\\RepoDocs\\github.com\\{{ remote_name_origin }}' + enabled: is_github_repository + +- type: render-variable@1 + name: repo_docs_directory + value: 'C:\\Users\\Munckhof CJJ\\OneDrive - BDO\\BDO\\RepoDocs\\{{ remote_name_origin }}' + +# Env files +- type: render-variable@1 + name: repo_environment_file_directory + value: '{{ env.REPOZ_CONFIG_PATH }}\\{{ remote_name_origin }}' + +- type: render-variable@1 + name: repo_environment_file + value: '{{ env.REPOZ_CONFIG_PATH }}\\{{ remote_name_origin }}\\RepoM.env' + +- type: render-variable@1 + name: repo_yaml_file + value: '{{ env.REPOZ_CONFIG_PATH }}\\{{ remote_name_origin }}\\RepoMV2.yaml' + +- type: render-variable@1 + name: repo_environment_template_file + value: '{{ env.REPOZ_CONFIG_PATH }}\\RepoM.Template.env' + +# Runsettings +- type: render-variable@1 + name: runsettings_file_directory + value: '{{ env.REPOZ_CONFIG_PATH }}\\{{ remote_name_origin }}' +- type: render-variable@1 + name: runsettings_file + value: '{{ env.REPOZ_CONFIG_PATH }}\\{{ remote_name_origin }}\\local.runsettings' +- type: render-variable@1 + name: runsettings_template_file + value: '{{ env.REPOZ_CONFIG_PATH }}\\Runsettings.Template.runsettings' + +- type: set-variable@1 + name: devops_environments + value: + - name: Develop + url: '-d.bdodt.nl' + - name: Test + url: '-t.bdodt.nl' + - name: Acceptation + url: '-a.bdo.nl' + - name: Production + url: '.bdo.nl' + +# - type: load-file@1 +# filename: '{{ repo_yaml_file }}' +# enabled: is_bdo_tis_repository + +- type: load-file@1 + filename: '{{ repo_environment_file }}' + enabled: is_work_repository + +- type: load-file@1 + filename: '{{ env.REPOZ_CONFIG_PATH }}\\BDO.env' + enabled: is_work_repository + +- type: load-file@1 + filename: '{{ repo_yaml_file }}' + enabled: is_work_repository + +tags: +- tag: TW + when: 'repository_path_contains "C:/Repositories/"' +- tag: DQE + when: 'repository_path_contains "Projects/Bdo/git/DataQualityEngine"' +- tag: DRC + when: 'repository_path_contains("Projects/Bdo/git/DRC") || repository_path_contains ("DataRotonde Core")' +- tag: APT + when: 'repository_path_contains "Projects/Bdo/git/APT"' +- tag: EA + when: 'repository_path_contains "Projects/Bdo/git/E-Accounting"' +- tag: EAS + when: 'repository_path_contains("Projects/Bdo/git/ExtAuthService") || repository_path_contains("Projects/Bdo/git/External Auth Service")' +- tag: PE + when: 'repository_path_contains "Projects/Bdo/git/PE"' +- tag: wiki + when: 'repository_path_contains("Projects/Bdo/git") && repository_path_contains("Wiki")' +- tag: BDO + when: is_work_repository +- tag: TIS + when: 'is_work_repository && file.file_exists(repository.linux_path + "/.azuredevops/Pipelines/gated.yml")' +- tag: wcf + when: 'is_work_repository && !string.empty(env.URL_SERVICE) && string.contains(env.URL_SERVICE, ".svc")' +- tag: Test + when: 'is_integration_test_framework || is_end_to_end_api_test_framework' +- tag: Compliance + when: 'is_work_repository && repository_path_contains("Projects/Bdo/git/Compliance")' +- tag: github + when: 'repository_path_contains "Projects/Github"' +- tag: Prive + when: '!is_work_repository && ( repository_path_contains("Projects/Private") || repository_path_contains("Projects/Bdo-prive") )' + +action-menu: + +- type: command@1 + name: Open in Windows File Explorer + command: '"{{ repository.path }}"' + +- type: command@1 + name: Open in Windows Terminal + command: wt + arguments: -d "{{ repository.linux_path }}" + +- type: executable@1 + name: 'Open in Windows PowerShell' + executable: '{{ env.WINDIR }}/System32/WindowsPowerShell/v1.0/powershell.exe' + arguments: -executionpolicy bypass -noexit -command "Set-Location '{{ repository.linux_path }}'" + +# Open in visual studio when exactly one '.sln' file was found: +- type: command@1 + name: Open in Visual Studio + command: '{{ solution_file }}' + active: array.size(solution_files) == 1 + +# Otherwise, Visual studio folder with all '.sln' files when multiple sln files were found: +- type: folder@1 + name: Open in Visual Studio + active: array.size(solution_files) > 1 + actions: + - type: foreach@1 + enumerable: solution_files + variable: sln + actions: + - type: command@1 + name: '{{ get_filename(sln) }}' + command: '{{ sln }}' + +- type: executable@1 + name: Open in Visual Studio Code + executable: '{{ exe_vs_code }}' + arguments: '"{{ repository.linux_path }}"' + +- type: executable@1 + name: Open in Sourcetree + executable: '{{ env.LocalAppData }}/SourceTree/SourceTree.exe' + arguments: -f "{{ repository.windows_path }}" + +- type: executable@1 + name: Open in Everything + executable: '{{ env.ProgramW6432 }}/Everything/Everything.exe' + arguments: -s """"{{ repository.path }}""" " + +- type: executable@1 + name: Open in TotalCommander + executable: '{{ env.ProgramW6432 }}/totalcmd/TOTALCMD64.EXE' + arguments: /O /T /L="{{ repository.linux_path }}" + +- type: separator@1 + +# Documentation per repository +- type: folder@1 + name: Docs + active: file.dir_exists(repo_docs_directory) + actions: + - type: executable@1 + name: Open in Visual Studio Code + executable: '{{ exe_vs_code }}' + arguments: '"{{ repo_docs_directory }}"' + - type: command@1 + name: Open in Windows File Explorer + command: '"{{ repo_docs_directory }}"' + +- type: folder@1 + name: DevOps + active: is_work_repository + actions: + - type: browse-repository@1 + + - type: browser@1 + name: Pipelines + # url: '{{ url_bdo_devops }}_build?definitionScope={{ web.url_encode(env.DEVOPS_PIPELINE_PATH_SUFFIX) }}' + url: '{{ url_bdo_devops }}_build?definitionScope={{ env.DEVOPS_PIPELINE_PATH_SUFFIX }}' + active: '!string.empty(env.DEVOPS_PIPELINE_PATH_SUFFIX)' + profile: BDO + + - type: folder@1 + name: Pull Request + active: '!string.empty(env.DEVOPS_GIT_REPO_NAME)' + context: + - type: evaluate-script@1 + content: |- + project_id = env.AZURE_DEVOPS_PROJECT_ID; + prs = azure_devops.get_pull_requests(env.AZURE_DEVOPS_PROJECT_ID); + now = date.now | date.to_string "%Y-%m-%d" + devops_guid_reviewer = "5d084100-0024-67e1-b736-8b669ca9397e"; + + actions: + + - type: command@1 + name: Create local release branch + command: cmd + arguments: /k cd "{{ repository.linux_path }}" & git pull & git checkout -b release/{{ date.now | date.to_string "%Y.%m.%d" }} & exit + active: repository.branch == "develop" + + - type: azure-devops-create-pr@1 + project-id: "{{ project_id }}" + name: Create release to master {{ now }} + pr-title: 'Release {{ now }}' + to-branch: master + reviewer-ids: + - "{{ devops_guid_reviewer }}" + draft-pr: true + include-work-items: true + open-in-browser: true + auto-complete: + merge-strategy: NoFastForward + delete-source-branch: true + transition-work-items: true + active: repository.branch | string.starts_with "release/" + + - type: azure-devops-create-pr@1 + context: + - type: evaluate-script@1 + content: |- + branch_name = sanitize_feature_branch_name(); + project-id: "{{ project_id }}" + name: Create hotfix to master ({{ branch_name | string.truncate 20 ".." }}) + pr-title: 'Hotfix {{ branch_name }}' + to-branch: master + reviewer-ids: + - "{{ devops_guid_reviewer }}" + draft-pr: true + include-work-items: true + open-in-browser: true + auto-complete: + merge-strategy: Squash + delete-source-branch: true + transition-work-items: true + active: repository.branch | string.starts_with "hotfix/" + + - type: azure-devops-create-pr@1 + project-id: "{{ project_id }}" + name: Create release to main {{ now }} + pr-title: 'Release {{ now }}' + to-branch: main + reviewer-ids: + - "{{ devops_guid_reviewer }}" + draft-pr: true + include-work-items: true + open-in-browser: true + auto-complete: + merge-strategy: NoFastForward + delete-source-branch: true + transition-work-items: true + active: repository.branch | string.starts_with "release/" + + - type: azure-devops-create-pr@1 + project-id: "{{ project_id }}" + name: Create master to develop + to-branch: develop + pr-title: Master to develop + reviewer-ids: + - "{{ devops_guid_reviewer }}" + draft-pr: true + include-work-items: false + open-in-browser: true + auto-complete: + merge-strategy: NoFastForward + delete-source-branch: true + transition-work-items: true + active: repository.branch == "master" || repository.branch == "main" + + - type: azure-devops-create-pr@1 + context: + - type: evaluate-script@1 + content: |- + branch_name = sanitize_feature_branch_name(); + project-id: "{{ project_id }}" + name: Create feature to develop ({{ branch_name | string.truncate 20 ".." }}) + pr-title: '{{ branch_name }}' + to-branch: develop + reviewer-ids: + - "{{ devops_guid_reviewer }}" + draft-pr: true + include-work-items: true + open-in-browser: true + auto-complete: + merge-strategy: Squash + delete-source-branch: true + transition-work-items: true + active: is_feature_branch() + + - type: azure-devops-create-pr@1 + context: + - type: evaluate-script@1 + content: |- + branch_name = sanitize_feature_branch_name(); + project-id: "{{ project_id }}" + name: Create feature to main ({{ branch_name | string.truncate 20 ".." }}) + pr-title: '{{ branch_name }}' + to-branch: main + reviewer-ids: + - "{{ devops_guid_reviewer }}" + draft-pr: true + include-work-items: true + open-in-browser: true + auto-complete: + merge-strategy: Squash + delete-source-branch: true + transition-work-items: true + active: is_feature_branch() + + - type: azure-devops-create-pr@1 + context: + - type: evaluate-script@1 + content: |- + branch_name = sanitize_feature_branch_name(); + project-id: "{{ project_id }}" + name: Create feature to master ({{ branch_name | string.truncate 20 ".." }}) + pr-title: '{{ branch_name }}' + to-branch: master + reviewer-ids: + - "{{ devops_guid_reviewer }}" + draft-pr: true + include-work-items: true + open-in-browser: true + auto-complete: + merge-strategy: Squash + delete-source-branch: true + transition-work-items: true + active: is_feature_branch() + + - type: separator@1 + + - type: browser@1 + active: array.size(prs) == 0 + name: Browse + url: '{{ url_bdo_devops }}_git/{{ env.DEVOPS_GIT_REPO_NAME }}/pullrequests?_a=active' + profile: BDO + + - type: foreach@1 + active: array.size(prs) > 0 + enumerable: prs + variable: pr + actions: + - type: browser@1 + name: '{{ pr.name | string.truncate 40 "..." }}' + url: '{{ pr.url }}' + profile: BDO + + - type: browser@1 + name: Wiki + url: '{{ url_bdo_devops }}_wiki/wikis/{{ env.WIKI_URL_SUFFIX }}' + active: '!string.empty(env.WIKI_URL_SUFFIX)' + profile: BDO + +- type: folder@1 + name: '{{ if string.contains(env.URL_SERVICE, ".svc") }}Wcf Service{{ else }}Swagger{{ end }}' + active: is_work_repository && !string.empty(env.URL_SERVICE) && !applications + actions: + - type: foreach@1 + enumerable: devops_environments + variable: environment + actions: + - type: browser@1 + name: '{{ environment.name }}' + url: '{{ string.replace(env.URL_SERVICE, ".bdo.nl", environment.url) }}' + profile: BDO + +- type: folder@1 + name: 'Swagger/Wcf' + active: is_work_repository && applications + actions: + - type: foreach@1 + enumerable: devops_environments + variable: 'environment' + actions: + - type: folder@1 + name: '{{ environment.name }}' + actions: + - type: foreach@1 + enumerable: applications + variable: application + actions: + - type: browser@1 + name: '{{ application.name }}' + url: '{{ string.replace(application.url, ".bdo.nl", environment.url) }}' + active: array.size(application.sub) == 0 + profile: BDO + - type: folder@1 + name: '{{ application.name }}' + active: array.size(application.sub) > 0 + actions: + - type: foreach@1 + enumerable: application.sub + variable: sub + actions: + - type: browser@1 + name: '{{ sub.name }}' + url: '{{ string.replace(application.url, ".bdo.nl", environment.url) }}{{ sub.url }}' + profile: BDO + +- type: folder@1 + name: Analysis + active: 'is_work_repository && (!string.empty(env.WHITESOURCE_PROJECT_ID) || !string.empty(env.SONARCLOUD_PROJECT_ID) )' + actions: + - type: browser@1 + name: SonarCloud + url: 'https://sonarcloud.io/project/overview?id={{ env.SONARCLOUD_PROJECT_ID }}' + profile: BDO + active: '!string.empty(env.SONARCLOUD_PROJECT_ID)' + - type: browser@1 + name: SonarCloud Settings + url: https://sonarcloud.io/project/settings?category=exclusions&id={{ env.SONARCLOUD_PROJECT_ID }} + profile: BDO + active: '!string.empty(env.SONARCLOUD_PROJECT_ID)' + - type: browser@1 + name: Whitesource + url: 'https://saas-eu.whitesourcesoftware.com/Wss/WSS.html#!project;id={{ env.WHITESOURCE_PROJECT_ID }}' + profile: BDO + active: '!string.empty(env.WHITESOURCE_PROJECT_ID)' + - type: browser@1 + name: LogicMonitor + url: https://bdonl.logicmonitor.com/santaba/uiv3/website/index.jsp#tree/{{ env.LOGICMONITOR_ID }} + profile: BDO + active: '!string.empty(env.LOGICMONITOR_ID)' + + - type: folder@1 + name: ApplicationInsights + active: 'is_work_repository && !string.empty(env.RESOURCE_GROUP) && !string.empty(env.APPLICATION_INSIGHTS)' + actions: + - type: foreach@1 + enumerable: azure_environments + variable: environment + actions: + - type: browser@1 + name: '{{ environment.name }}' + url: 'https://portal.azure.com/#@{{ environment.tentant }}/resource/subscriptions/{{ environment.subscription }}/resourceGroups/{{ string.replace(env.RESOURCE_GROUP, "BDONL", environment.resourcegroup_prefix) }}/providers/microsoft.insights/components/{{ string.replace(env.APPLICATION_INSIGHTS, "bdonl", environment.resourcegroup_prefix) }}/overview' + profile: '{{ environment.browser_profile }}' + +- type: folder@1 + name: Tests + context: + - type: render-variable@1 + name: runsettings_path + value: '{{ repo_environment_file_directory }}' + # SystemTests + - type: render-variable@1 + name: system_tests_filename + value: '{{ array.first(system_test_csproj_files) }}' + enabled: 'array.size(system_test_csproj_files) > 0' + - type: set-variable@1 + name: system_tests_filter + value: --filter "TestCategory=SystemTests&TestCategory!=PipelineIgnore" + - type: set-variable@1 + name: smoke_tests_filter + value: --filter "TestCategory!=SystemTests&TestCategory!=PipelineIgnore" + - type: evaluate-variable@1 + name: system_tests_filename_exists + value: 'array.size(system_test_csproj_files) > 0' + # SmokeTests + - type: render-variable@1 + name: smoke_tests_filename + value: '{{ array.first(smoke_tests_csproj_files) }}' + enabled: 'array.size(smoke_tests_csproj_files) > 0' + - type: evaluate-variable@1 + name: smoke_tests_filename_exists + value: 'array.size(smoke_tests_csproj_files) > 0' + actions: + + - type: folder@1 + name: dotnet test + actions: + - type: command@1 + name: Unittests sln + command: cmd + arguments: /k dotnet test -c release "{{ solution_file }}" --filter "FullyQualifiedName!=TestAutomation&TestCategory!=SystemTests" --verbosity q + + - type: foreach@1 + enumerable: 'runsettings_environments' + variable: environment + iteration-context: + - type: render-variable@1 + name: runsettings_file + value: '{{ repo_environment_file_directory }}\\{{ environment.filename }}' + - type: evaluate-variable@1 + name: runsettings_file_exists + value: 'file.file_exists(repo_environment_file_directory + "\\" + environment.filename)' + actions: + - type: command@1 + name: TA Systeem {{ environment.name }} + command: cmd + arguments: /k dotnet test -c release "{{ system_tests_filename }}" {{ system_tests_filter }} --settings:"{{ runsettings_file }}" + active: 'system_tests_filename_exists && runsettings_file_exists' + - type: command@1 + name: TA Smoke {{ environment.name }} + command: cmd + arguments: /k dotnet test -c release "{{ smoke_tests_filename }}" {{ smoke_tests_filter }} --settings:"{{ runsettings_file }}" + active: 'smoke_tests_filename_exists && runsettings_file_exists' + +- type: separator@1 + +- type: browse-repository@1 + +- type: folder@1 + name: Git + actions: + - type: git-fetch@1 + - type: git-pull@1 + - type: git-push@1 + - type: git-checkout@1 + +- type: separator@1 + +- type: ignore-repository@1 + +- type: separator@1 + active: is_work_repository + +- type: folder@1 + name: '-- Examples --' + actions: + - type: clipboard-copy@1 + name: Copy current branch name + text: '{{ repository.branch }}' + + - type: clipboard-copy@1 + name: Copy command 'git checkout -b {{ repository.branch | string.truncate 15 "..." }}' + text: '{{ repository.branch }}' + active: 'repository.branch | string.starts_with "feature/"' + + - type: command@1 + name: 'Create Directory {{ repo_docs_directory }}' + command: cmd + arguments: /k mkdir "{{ repo_docs_directory }}" + active: '!file.dir_exists(repo_docs_directory)' + + - type: just-text@1 + name: 'Usage counter: {{ statistics.count }}' + active: true \ No newline at end of file From 9dd6cc851d6fd7cb284281dbd14f2bb6d36f0895 Mon Sep 17 00:00:00 2001 From: Coen van den Munckhof Date: Tue, 2 Apr 2024 20:58:28 +0200 Subject: [PATCH 3/7] update --- RepoM.sln.DotSettings | 1 + _ref/RepoM.Filtering.yaml | 18 - _ref/RepoM.Sorting.yaml | 93 ---- _ref/RepositoryActions.yaml | 93 ---- _setup/RepoM.nsi | 1 - .../Common/FilesCompareSettingsService.cs | 18 +- .../Common/FilesFilterSettingsService.cs | 18 +- src/RepoM.Api/EnsureStartup.cs | 6 +- .../IO/DefaultAppDataPathProvider.cs | 22 - src/RepoM.Api/RepoM.Api.csproj | 4 +- src/RepoM.Api/Resources/EmbeddedResources.cs | 22 +- .../Resources/RepositoryActions.yaml | 46 -- .../Resources/RepositoryActionsV2.yaml | 419 +----------------- .../Resources/appsettings.serilog.json | 18 + src/RepoM.App/App.xaml.cs | 28 +- .../Common/IAppDataPathProvider.cs | 2 - 16 files changed, 59 insertions(+), 750 deletions(-) delete mode 100644 _ref/RepoM.Filtering.yaml delete mode 100644 _ref/RepoM.Sorting.yaml delete mode 100644 _ref/RepositoryActions.yaml delete mode 100644 src/RepoM.Api/Resources/RepositoryActions.yaml create mode 100644 src/RepoM.Api/Resources/appsettings.serilog.json diff --git a/RepoM.sln.DotSettings b/RepoM.sln.DotSettings index 24b37438..4ae60fb1 100644 --- a/RepoM.sln.DotSettings +++ b/RepoM.sln.DotSettings @@ -1,4 +1,5 @@  + True True True True diff --git a/_ref/RepoM.Filtering.yaml b/_ref/RepoM.Filtering.yaml deleted file mode 100644 index 62335d1e..00000000 --- a/_ref/RepoM.Filtering.yaml +++ /dev/null @@ -1,18 +0,0 @@ -Work: - name: Work - description: Work filtering - always-visible: - kind: query@1 - query: is:pinned - filter: - kind: query@1 - query: tag:work -Private: - name: Private - description: Private repositories - always-visible: - kind: query@1 - query: RepoM OR is:pinned - filter: - kind: query@1 - query: (-tag:work OR tag:prive) \ No newline at end of file diff --git a/_ref/RepoM.Sorting.yaml b/_ref/RepoM.Sorting.yaml deleted file mode 100644 index 8985b78e..00000000 --- a/_ref/RepoM.Sorting.yaml +++ /dev/null @@ -1,93 +0,0 @@ -Work: - type: composition-comparer@1 - comparers: - - type: score-comparer@1 - score-provider: - type: is-pinned-scorer@1 - weight: 1 - - type: score-comparer@1 - score-provider: - type: tag-scorer@1 - weight: 1 - tag: Team1 - - type: score-comparer@1 - score-provider: - type: tag-scorer@1 - weight: 1 - tag: Work - - type: az-comparer@1 - property: Name - weight: 1 -Work Dynamic: - type: composition-comparer@1 - comparers: - - type: score-comparer@1 - score-provider: - type: is-pinned-scorer@1 - weight: 1 - - type: score-comparer@1 - score-provider: - type: tag-scorer@1 - weight: 1 - tag: Team1 - - type: score-comparer@1 - score-provider: - type: usage-scorer@1 - max-score: 20 - windows: - - until: 00:15:00 - weight: 4 - max-items: 10 - - until: 01:00:00 - weight: 3 - max-items: 5 - - until: 24:00:00 - weight: 2 - max-items: 5 - - until: 168:00:00 - weight: 1 - max-items: 10 - - type: last-opened-comparer@1 - weight: 1 - - type: score-comparer@1 - score-provider: - type: tag-scorer@1 - weight: 1 - tag: Work - - type: az-comparer@1 - property: Name - weight: 1 -Prive: - type: composition-comparer@1 - comparers: - - type: score-comparer@1 - score-provider: - type: is-pinned-scorer@1 - weight: 1 - - type: score-comparer@1 - score-provider: - type: tag-scorer@1 - weight: 1 - tag: Prive - - type: score-comparer@1 - score-provider: - type: usage-scorer@1 - max-score: 20 - windows: - - until: 00:15:00 - weight: 4 - max-items: 10 - - until: 01:00:00 - weight: 3 - max-items: 5 - - until: 24:00:00 - weight: 2 - max-items: 5 - - until: 168:00:00 - weight: 1 - max-items: 10 - - type: last-opened-comparer@1 - weight: 1 - - type: az-comparer@1 - property: Name - weight: 1 \ No newline at end of file diff --git a/_ref/RepositoryActions.yaml b/_ref/RepositoryActions.yaml deleted file mode 100644 index 3e429858..00000000 --- a/_ref/RepositoryActions.yaml +++ /dev/null @@ -1,93 +0,0 @@ -version: 1 - -variables: -- name: IsRepoM - value: '{empty}{StringContains({Repository.SafePath}, "RepoM")}' - -repository-specific-env-files: -- filename: '{Repository.SafePath}{slash}.git{slash}repom.env' - when: '{var.IsRepoM}' -- filename: '{Repository.SafePath}{slash}repom.env' - when: true - -repository-specific-config-files: -- filename: '{Repository.SafePath}{slash}.git{slash}RepositoryActions.json' -- filename: '{Repository.SafePath}{slash}RepositoryActions.json' - -repository-tags: -- tag: Work - when: '{StringContains({Repository.SafePath}, "Work")}' -- tag: Private - when: '{Not({StringContains({Repository.SafePath}, "Work")})}' - -repository-actions: - variables: - - name: key - value: abc - actions: - - type: command@1 - variables: - - name: Test2 - value: -- T3sT2 - enabled: true - name: '{OpenIn} Windows File Explorer' - command: '"{Repository.SafePath}"' - active: true - - type: command@1 - name: '{OpenIn} Windows Terminal' - command: wt - arguments: -d "{Repository.SafePath}" - active: true - - type: command@1 - name: '{OpenIn} Windows Command Shell' - command: cmd - arguments: /K "cd /d {Repository.SafePath}" - active: false - - type: executable@1 - name: '{OpenIn} Windows PowerShell' - executables: - - '%WINDIR%/System32/WindowsPowerShell/v1.0/powershell.exe' - arguments: -executionpolicy bypass -noexit -command "Set-Location '{Repository.SafePath}'" - active: false - - type: executable@1 - name: '{OpenIn} Visual Studio Code' - executables: - - '%LocalAppData%/Programs/Microsoft VS Code/code.exe' - - '%ProgramW6432%/Microsoft VS Code/code.exe' - arguments: '"{Repository.SafePath}"' - active: true - - type: executable@1 - name: '{OpenIn} Sourcetree' - executables: - - '%LocalAppData%/SourceTree/SourceTree.exe' - - '%PROGRAMFILES(X86)%/Atlassian/SourceTree/SourceTree.exe' - arguments: -f "{Repository.Location}{backslash}{Repository.Name}" - active: true - - type: executable@1 - name: '{OpenIn} Everything' - executables: - - '%ProgramW6432%/Everything/Everything.exe' - arguments: -s """"{Repository.Path}""" " - active: true - - type: executable@1 - name: '{OpenIn} TotalCommander' - executables: - - '%ProgramW6432%/totalcmd/TOTALCMD64.EXE' - - '%SystemDrive%/totalcmd/TOTALCMD64.EXE' - arguments: /O /T /L="{Repository.SafePath}" - active: true - - type: separator@1 - - type: browse-repository@1 - - type: separator@1 - - type: git-fetch@1 - - type: git-pull@1 - - type: git-push@1 - - type: git-checkout@1 - - type: separator@1 - - type: ignore-repositories@1 - - type: separator@1 - - type: associate-file@1 - name: '{Open} Visual Studio solutions' - extension: '*.sln' - command: start - arguments: '"{FilePath}"' diff --git a/_setup/RepoM.nsi b/_setup/RepoM.nsi index e2439f8c..e9737803 100644 --- a/_setup/RepoM.nsi +++ b/_setup/RepoM.nsi @@ -53,7 +53,6 @@ Section "RepoM" File /r ..\_output\win\Assemblies\*.* File ..\_ref\PathEd.exe ; Add PathEd.exe to add the RepoM directory to the system's PATH easily ; File ..\_ref\SendKeys.exe ; Add SendKeys.exe to add the RepoM directory for grr. - File ..\_ref\RepositoryActions.yaml ; Can be copied in-app for the default settings CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}.lnk" $INSTDIR\${PRODUCT_NAME}.exe ; Add the installation folder to the system PATH -> to enable grr.exe diff --git a/src/RepoM.Api/Common/FilesCompareSettingsService.cs b/src/RepoM.Api/Common/FilesCompareSettingsService.cs index f6f96e3b..3172b696 100644 --- a/src/RepoM.Api/Common/FilesCompareSettingsService.cs +++ b/src/RepoM.Api/Common/FilesCompareSettingsService.cs @@ -73,23 +73,7 @@ private Dictionary LoadInner() if (!_fileSystem.File.Exists(file)) { - var templateFilename = _fileSystem.Path.Combine(_appDataPathProvider.AppResourcesPath, FILENAME); - if (_fileSystem.File.Exists(templateFilename)) - { - try - { - _fileSystem.File.Copy(templateFilename, file); - } - catch (Exception e) - { - _logger.LogError(e, "Could not copy template file '{TemplateFilename}' to '{File}'", templateFilename, file); - } - } - - if (!_fileSystem.File.Exists(file)) - { - throw new FileNotFoundException("Comparer configuration file not found", file); - } + throw new FileNotFoundException("Comparer configuration file not found", file); } try diff --git a/src/RepoM.Api/Common/FilesFilterSettingsService.cs b/src/RepoM.Api/Common/FilesFilterSettingsService.cs index d8f3ac12..ea9b2284 100644 --- a/src/RepoM.Api/Common/FilesFilterSettingsService.cs +++ b/src/RepoM.Api/Common/FilesFilterSettingsService.cs @@ -41,23 +41,7 @@ private Dictionary Load() if (!_fileSystem.File.Exists(file)) { - var templateFilename = _fileSystem.Path.Combine(_appDataPathProvider.AppResourcesPath, FILENAME); - if (_fileSystem.File.Exists(templateFilename)) - { - try - { - _fileSystem.File.Copy(templateFilename, file); - } - catch (Exception e) - { - _logger.LogError(e, "Could not copy template file '{TemplateFilename}' to '{File}'", templateFilename, file); - } - } - - if (!_fileSystem.File.Exists(file)) - { - throw new FileNotFoundException("Filtering configuration file not found", file); - } + throw new FileNotFoundException("Filtering configuration file not found", file); } try diff --git a/src/RepoM.Api/EnsureStartup.cs b/src/RepoM.Api/EnsureStartup.cs index 6b73a05b..771c5a84 100644 --- a/src/RepoM.Api/EnsureStartup.cs +++ b/src/RepoM.Api/EnsureStartup.cs @@ -20,7 +20,11 @@ public EnsureStartup(IFileSystem fileSystem, IAppDataPathProvider appDataProvide public async Task EnsureFilesAsync() { - await CheckOrCreateAsync("RepositoryActionsV2.yaml", () => EmbeddedResources.GetRepositoryActionsV2Yaml()); + await CheckOrCreateAsync("RepositoryActionsV2.yaml", EmbeddedResources.GetRepositoryActionsV2Yaml).ConfigureAwait(false); + await CheckOrCreateAsync("RepoM.Filtering.yaml", EmbeddedResources.GetFilteringYaml).ConfigureAwait(false); + await CheckOrCreateAsync("RepoM.Ordering.yaml", EmbeddedResources.GetSortingYaml).ConfigureAwait(false); + await CheckOrCreateAsync("RepoM.Ordering.yaml", EmbeddedResources.GetSortingYaml).ConfigureAwait(false); + await CheckOrCreateAsync("appsettings.serilog.json", EmbeddedResources.GetSerilogAppSettings).ConfigureAwait(false); } private async Task CheckOrCreateAsync(string filename, Func func) diff --git a/src/RepoM.Api/IO/DefaultAppDataPathProvider.cs b/src/RepoM.Api/IO/DefaultAppDataPathProvider.cs index 9468bab1..ca9795b4 100644 --- a/src/RepoM.Api/IO/DefaultAppDataPathProvider.cs +++ b/src/RepoM.Api/IO/DefaultAppDataPathProvider.cs @@ -7,7 +7,6 @@ namespace RepoM.Api.IO; public class DefaultAppDataPathProvider : IAppDataPathProvider { private static readonly string _applicationDataRepoM = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "RepoM"); - private static readonly string _appResourcesPath = GetAppResourcePath(); private DefaultAppDataPathProvider() { @@ -16,25 +15,4 @@ private DefaultAppDataPathProvider() public static DefaultAppDataPathProvider Instance { get; } = new(); public string AppDataPath => _applicationDataRepoM; - - - public string AppResourcesPath => _appResourcesPath; - - private static string GetAppResourcePath() - { - var entryAssembly = System.Reflection.Assembly.GetEntryAssembly(); - if (entryAssembly == null) - { - throw new NotSupportedException("Could not get entry point of assembly."); - } - - var result = Path.GetDirectoryName(entryAssembly.Location); - - if (result == null) - { - throw new FileNotFoundException("Could not find location of entry assembly"); - } - - return result; - } } \ No newline at end of file diff --git a/src/RepoM.Api/RepoM.Api.csproj b/src/RepoM.Api/RepoM.Api.csproj index 982ccd84..69512c40 100644 --- a/src/RepoM.Api/RepoM.Api.csproj +++ b/src/RepoM.Api/RepoM.Api.csproj @@ -22,9 +22,9 @@ - + - + diff --git a/src/RepoM.Api/Resources/EmbeddedResources.cs b/src/RepoM.Api/Resources/EmbeddedResources.cs index 9f5ef2c9..1802625a 100644 --- a/src/RepoM.Api/Resources/EmbeddedResources.cs +++ b/src/RepoM.Api/Resources/EmbeddedResources.cs @@ -1,7 +1,6 @@ namespace RepoM.Api.Resources; using System.IO; -using System.Linq; using System.Reflection; using LibGit2Sharp; @@ -12,12 +11,27 @@ internal static class EmbeddedResources public static Stream GetRepositoryActionsV2Yaml() { - return ResolveFromAssembly("RepositoryActionsV2.yaml") ?? throw new NotFoundException("File not found."); + return ResolveFromAssembly("RepositoryActionsV2.yaml"); } - private static Stream? ResolveFromAssembly(string relativeFilename) + public static Stream GetSortingYaml() + { + return ResolveFromAssembly("RepoM.Sorting.yaml"); + } + + public static Stream GetFilteringYaml() + { + return ResolveFromAssembly("RepoM.Filtering.yaml"); + } + + public static Stream GetSerilogAppSettings() + { + return ResolveFromAssembly("appsettings.serilog.json"); + } + + private static Stream ResolveFromAssembly(string relativeFilename) { var embeddedFilename = $"{_namespace}.{relativeFilename}"; - return _assembly.GetManifestResourceStream(embeddedFilename); + return _assembly.GetManifestResourceStream(embeddedFilename) ?? throw new NotFoundException($"{relativeFilename} not found."); } } \ No newline at end of file diff --git a/src/RepoM.Api/Resources/RepositoryActions.yaml b/src/RepoM.Api/Resources/RepositoryActions.yaml deleted file mode 100644 index 378b6d39..00000000 --- a/src/RepoM.Api/Resources/RepositoryActions.yaml +++ /dev/null @@ -1,46 +0,0 @@ -version: 1 - -variables: -- name: IsRepoM - value: '{empty}{StringContains({Repository.SafePath}, "RepoM")}' - -repository-specific-env-files: -- filename: '{Repository.SafePath}{slash}.git{slash}repom.env' - when: '{var.IsRepoM}' -- filename: '{Repository.SafePath}{slash}repom.env' - when: true - -repository-specific-config-files: -- filename: '{Repository.SafePath}{slash}.git{slash}RepositoryActions.json' -- filename: '{Repository.SafePath}{slash}RepositoryActions.json' - -repository-tags: -- tag: Work - when: '{StringContains({Repository.SafePath}, "Work")}' -- tag: Private - when: '{Not({StringContains({Repository.SafePath}, "Work")})}' - -repository-actions: - variables: - - name: key - value: abc - actions: - - type: command@1 - variables: - - name: Test2 - value: -- T3sT2 - enabled: true - name: '{OpenIn} Windows File Explorer' - command: '"{Repository.SafePath}"' - active: true - - - type: separator@1 - - type: browse-repository@1 - - type: separator@1 - - type: git-fetch@1 - - type: git-pull@1 - - type: git-push@1 - - type: git-checkout@1 - - type: separator@1 - - type: ignore-repositories@1 - - type: separator@1 \ No newline at end of file diff --git a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml index 6ab9f0e0..dfb1fa6d 100644 --- a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml +++ b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml @@ -5,10 +5,6 @@ context: ret input == null end - func translate(input) - ret input - end - func get_filename(path) ret path | string.split("\\") | array.last end @@ -52,26 +48,20 @@ context: end remote_name_origin = get_remote_origin_name(); - is_work_repository = remotes_contain("BDO-NL"); + is_work_repository = remotes_contain("My-Work"); is_bdo_tis_repository = is_work_repository && file.file_exists(repository.linux_path + "/.azuredevops/Pipelines/gated.yml") is_github_repository = remotes_contain("github.com"); - is_integration_test_framework = remotes_contain("IntegrationServices.IntegrationTestFramework"); - is_end_to_end_api_test_framework = remotes_contain("EndToEndApiTestFramework"); + solution_files = file.find_files(repository.linux_path, "*.sln"); solution_file = array.first(solution_files); system_test_csproj_files = file.find_files(repository.linux_path, "*.SystemTests.csproj"); smoke_tests_csproj_files = file.find_files(repository.linux_path, "*.SmokeTests.csproj"); exe_vs_code = env.LocalAppData + "/Programs/Microsoft VS Code/code.exe"; - exe_heidi_sql = "C:/StandAloneProgramFiles/HeidiSQL_12.3_64_Portable/heidisql.exe"; - exe_ssms = "C:/Program Files (x86)/Microsoft SQL Server Management Studio 18/Common7/IDE/Ssms.exe"; - exe_monitoring = "C:/Projects/Private/git/SimpleTestRunner/src/TestRunner.Application/bin/Release/net6.0-windows/TestRunner.Application.exe" path_repo_tis_wat = `C:\Users\Munckhof CJJ\OneDrive - BDO\BDO\TisWatConfig\` + remote_name_origin; path_bdo_repo_root = `C:\Projects\Bdo\git\`; - url_bdo_devops = "https://dev.azure.com/tfs-bdonl/BDO-NL/"; - - root_path_repom: C:\\Users\\Munckhof CJJ\\OneDrive - BDO\\BDO\\RepoM\\ # Specific var files @@ -112,18 +102,6 @@ context: name: runsettings_template_file value: '{{ env.REPOZ_CONFIG_PATH }}\\Runsettings.Template.runsettings' -- type: set-variable@1 - name: devops_environments - value: - - name: Develop - url: '-d.bdodt.nl' - - name: Test - url: '-t.bdodt.nl' - - name: Acceptation - url: '-a.bdo.nl' - - name: Production - url: '.bdo.nl' - # - type: load-file@1 # filename: '{{ repo_yaml_file }}' # enabled: is_bdo_tis_repository @@ -141,36 +119,10 @@ context: enabled: is_work_repository tags: -- tag: TW - when: 'repository_path_contains "C:/Repositories/"' -- tag: DQE - when: 'repository_path_contains "Projects/Bdo/git/DataQualityEngine"' -- tag: DRC - when: 'repository_path_contains("Projects/Bdo/git/DRC") || repository_path_contains ("DataRotonde Core")' -- tag: APT - when: 'repository_path_contains "Projects/Bdo/git/APT"' -- tag: EA - when: 'repository_path_contains "Projects/Bdo/git/E-Accounting"' -- tag: EAS - when: 'repository_path_contains("Projects/Bdo/git/ExtAuthService") || repository_path_contains("Projects/Bdo/git/External Auth Service")' -- tag: PE - when: 'repository_path_contains "Projects/Bdo/git/PE"' -- tag: wiki - when: 'repository_path_contains("Projects/Bdo/git") && repository_path_contains("Wiki")' -- tag: BDO +- tag: Work when: is_work_repository -- tag: TIS - when: 'is_work_repository && file.file_exists(repository.linux_path + "/.azuredevops/Pipelines/gated.yml")' -- tag: wcf - when: 'is_work_repository && !string.empty(env.URL_SERVICE) && string.contains(env.URL_SERVICE, ".svc")' -- tag: Test - when: 'is_integration_test_framework || is_end_to_end_api_test_framework' -- tag: Compliance - when: 'is_work_repository && repository_path_contains("Projects/Bdo/git/Compliance")' -- tag: github - when: 'repository_path_contains "Projects/Github"' -- tag: Prive - when: '!is_work_repository && ( repository_path_contains("Projects/Private") || repository_path_contains("Projects/Bdo-prive") )' +- tag: Private + when: '!is_work_repository || repository_path_contains("Projects/Private") ' action-menu: @@ -229,354 +181,10 @@ action-menu: - type: separator@1 -# Documentation per repository -- type: folder@1 - name: Docs - active: file.dir_exists(repo_docs_directory) - actions: - - type: executable@1 - name: Open in Visual Studio Code - executable: '{{ exe_vs_code }}' - arguments: '"{{ repo_docs_directory }}"' - - type: command@1 - name: Open in Windows File Explorer - command: '"{{ repo_docs_directory }}"' - -- type: folder@1 - name: DevOps - active: is_work_repository - actions: - - type: browse-repository@1 - - - type: browser@1 - name: Pipelines - # url: '{{ url_bdo_devops }}_build?definitionScope={{ web.url_encode(env.DEVOPS_PIPELINE_PATH_SUFFIX) }}' - url: '{{ url_bdo_devops }}_build?definitionScope={{ env.DEVOPS_PIPELINE_PATH_SUFFIX }}' - active: '!string.empty(env.DEVOPS_PIPELINE_PATH_SUFFIX)' - profile: BDO - - - type: folder@1 - name: Pull Request - active: '!string.empty(env.DEVOPS_GIT_REPO_NAME)' - context: - - type: evaluate-script@1 - content: |- - project_id = env.AZURE_DEVOPS_PROJECT_ID; - prs = azure_devops.get_pull_requests(env.AZURE_DEVOPS_PROJECT_ID); - now = date.now | date.to_string "%Y-%m-%d" - devops_guid_reviewer = "5d084100-0024-67e1-b736-8b669ca9397e"; - - actions: - - - type: command@1 - name: Create local release branch - command: cmd - arguments: /k cd "{{ repository.linux_path }}" & git pull & git checkout -b release/{{ date.now | date.to_string "%Y.%m.%d" }} & exit - active: repository.branch == "develop" - - - type: azure-devops-create-pr@1 - project-id: "{{ project_id }}" - name: Create release to master {{ now }} - pr-title: 'Release {{ now }}' - to-branch: master - reviewer-ids: - - "{{ devops_guid_reviewer }}" - draft-pr: true - include-work-items: true - open-in-browser: true - auto-complete: - merge-strategy: NoFastForward - delete-source-branch: true - transition-work-items: true - active: repository.branch | string.starts_with "release/" - - - type: azure-devops-create-pr@1 - context: - - type: evaluate-script@1 - content: |- - branch_name = sanitize_feature_branch_name(); - project-id: "{{ project_id }}" - name: Create hotfix to master ({{ branch_name | string.truncate 20 ".." }}) - pr-title: 'Hotfix {{ branch_name }}' - to-branch: master - reviewer-ids: - - "{{ devops_guid_reviewer }}" - draft-pr: true - include-work-items: true - open-in-browser: true - auto-complete: - merge-strategy: Squash - delete-source-branch: true - transition-work-items: true - active: repository.branch | string.starts_with "hotfix/" - - - type: azure-devops-create-pr@1 - project-id: "{{ project_id }}" - name: Create release to main {{ now }} - pr-title: 'Release {{ now }}' - to-branch: main - reviewer-ids: - - "{{ devops_guid_reviewer }}" - draft-pr: true - include-work-items: true - open-in-browser: true - auto-complete: - merge-strategy: NoFastForward - delete-source-branch: true - transition-work-items: true - active: repository.branch | string.starts_with "release/" - - - type: azure-devops-create-pr@1 - project-id: "{{ project_id }}" - name: Create master to develop - to-branch: develop - pr-title: Master to develop - reviewer-ids: - - "{{ devops_guid_reviewer }}" - draft-pr: true - include-work-items: false - open-in-browser: true - auto-complete: - merge-strategy: NoFastForward - delete-source-branch: true - transition-work-items: true - active: repository.branch == "master" || repository.branch == "main" - - - type: azure-devops-create-pr@1 - context: - - type: evaluate-script@1 - content: |- - branch_name = sanitize_feature_branch_name(); - project-id: "{{ project_id }}" - name: Create feature to develop ({{ branch_name | string.truncate 20 ".." }}) - pr-title: '{{ branch_name }}' - to-branch: develop - reviewer-ids: - - "{{ devops_guid_reviewer }}" - draft-pr: true - include-work-items: true - open-in-browser: true - auto-complete: - merge-strategy: Squash - delete-source-branch: true - transition-work-items: true - active: is_feature_branch() - - - type: azure-devops-create-pr@1 - context: - - type: evaluate-script@1 - content: |- - branch_name = sanitize_feature_branch_name(); - project-id: "{{ project_id }}" - name: Create feature to main ({{ branch_name | string.truncate 20 ".." }}) - pr-title: '{{ branch_name }}' - to-branch: main - reviewer-ids: - - "{{ devops_guid_reviewer }}" - draft-pr: true - include-work-items: true - open-in-browser: true - auto-complete: - merge-strategy: Squash - delete-source-branch: true - transition-work-items: true - active: is_feature_branch() - - - type: azure-devops-create-pr@1 - context: - - type: evaluate-script@1 - content: |- - branch_name = sanitize_feature_branch_name(); - project-id: "{{ project_id }}" - name: Create feature to master ({{ branch_name | string.truncate 20 ".." }}) - pr-title: '{{ branch_name }}' - to-branch: master - reviewer-ids: - - "{{ devops_guid_reviewer }}" - draft-pr: true - include-work-items: true - open-in-browser: true - auto-complete: - merge-strategy: Squash - delete-source-branch: true - transition-work-items: true - active: is_feature_branch() - - - type: separator@1 - - - type: browser@1 - active: array.size(prs) == 0 - name: Browse - url: '{{ url_bdo_devops }}_git/{{ env.DEVOPS_GIT_REPO_NAME }}/pullrequests?_a=active' - profile: BDO - - - type: foreach@1 - active: array.size(prs) > 0 - enumerable: prs - variable: pr - actions: - - type: browser@1 - name: '{{ pr.name | string.truncate 40 "..." }}' - url: '{{ pr.url }}' - profile: BDO - - - type: browser@1 - name: Wiki - url: '{{ url_bdo_devops }}_wiki/wikis/{{ env.WIKI_URL_SUFFIX }}' - active: '!string.empty(env.WIKI_URL_SUFFIX)' - profile: BDO - -- type: folder@1 - name: '{{ if string.contains(env.URL_SERVICE, ".svc") }}Wcf Service{{ else }}Swagger{{ end }}' - active: is_work_repository && !string.empty(env.URL_SERVICE) && !applications - actions: - - type: foreach@1 - enumerable: devops_environments - variable: environment - actions: - - type: browser@1 - name: '{{ environment.name }}' - url: '{{ string.replace(env.URL_SERVICE, ".bdo.nl", environment.url) }}' - profile: BDO - -- type: folder@1 - name: 'Swagger/Wcf' - active: is_work_repository && applications - actions: - - type: foreach@1 - enumerable: devops_environments - variable: 'environment' - actions: - - type: folder@1 - name: '{{ environment.name }}' - actions: - - type: foreach@1 - enumerable: applications - variable: application - actions: - - type: browser@1 - name: '{{ application.name }}' - url: '{{ string.replace(application.url, ".bdo.nl", environment.url) }}' - active: array.size(application.sub) == 0 - profile: BDO - - type: folder@1 - name: '{{ application.name }}' - active: array.size(application.sub) > 0 - actions: - - type: foreach@1 - enumerable: application.sub - variable: sub - actions: - - type: browser@1 - name: '{{ sub.name }}' - url: '{{ string.replace(application.url, ".bdo.nl", environment.url) }}{{ sub.url }}' - profile: BDO - -- type: folder@1 - name: Analysis - active: 'is_work_repository && (!string.empty(env.WHITESOURCE_PROJECT_ID) || !string.empty(env.SONARCLOUD_PROJECT_ID) )' - actions: - - type: browser@1 - name: SonarCloud - url: 'https://sonarcloud.io/project/overview?id={{ env.SONARCLOUD_PROJECT_ID }}' - profile: BDO - active: '!string.empty(env.SONARCLOUD_PROJECT_ID)' - - type: browser@1 - name: SonarCloud Settings - url: https://sonarcloud.io/project/settings?category=exclusions&id={{ env.SONARCLOUD_PROJECT_ID }} - profile: BDO - active: '!string.empty(env.SONARCLOUD_PROJECT_ID)' - - type: browser@1 - name: Whitesource - url: 'https://saas-eu.whitesourcesoftware.com/Wss/WSS.html#!project;id={{ env.WHITESOURCE_PROJECT_ID }}' - profile: BDO - active: '!string.empty(env.WHITESOURCE_PROJECT_ID)' - - type: browser@1 - name: LogicMonitor - url: https://bdonl.logicmonitor.com/santaba/uiv3/website/index.jsp#tree/{{ env.LOGICMONITOR_ID }} - profile: BDO - active: '!string.empty(env.LOGICMONITOR_ID)' - - - type: folder@1 - name: ApplicationInsights - active: 'is_work_repository && !string.empty(env.RESOURCE_GROUP) && !string.empty(env.APPLICATION_INSIGHTS)' - actions: - - type: foreach@1 - enumerable: azure_environments - variable: environment - actions: - - type: browser@1 - name: '{{ environment.name }}' - url: 'https://portal.azure.com/#@{{ environment.tentant }}/resource/subscriptions/{{ environment.subscription }}/resourceGroups/{{ string.replace(env.RESOURCE_GROUP, "BDONL", environment.resourcegroup_prefix) }}/providers/microsoft.insights/components/{{ string.replace(env.APPLICATION_INSIGHTS, "bdonl", environment.resourcegroup_prefix) }}/overview' - profile: '{{ environment.browser_profile }}' - -- type: folder@1 - name: Tests - context: - - type: render-variable@1 - name: runsettings_path - value: '{{ repo_environment_file_directory }}' - # SystemTests - - type: render-variable@1 - name: system_tests_filename - value: '{{ array.first(system_test_csproj_files) }}' - enabled: 'array.size(system_test_csproj_files) > 0' - - type: set-variable@1 - name: system_tests_filter - value: --filter "TestCategory=SystemTests&TestCategory!=PipelineIgnore" - - type: set-variable@1 - name: smoke_tests_filter - value: --filter "TestCategory!=SystemTests&TestCategory!=PipelineIgnore" - - type: evaluate-variable@1 - name: system_tests_filename_exists - value: 'array.size(system_test_csproj_files) > 0' - # SmokeTests - - type: render-variable@1 - name: smoke_tests_filename - value: '{{ array.first(smoke_tests_csproj_files) }}' - enabled: 'array.size(smoke_tests_csproj_files) > 0' - - type: evaluate-variable@1 - name: smoke_tests_filename_exists - value: 'array.size(smoke_tests_csproj_files) > 0' - actions: - - - type: folder@1 - name: dotnet test - actions: - - type: command@1 - name: Unittests sln - command: cmd - arguments: /k dotnet test -c release "{{ solution_file }}" --filter "FullyQualifiedName!=TestAutomation&TestCategory!=SystemTests" --verbosity q - - - type: foreach@1 - enumerable: 'runsettings_environments' - variable: environment - iteration-context: - - type: render-variable@1 - name: runsettings_file - value: '{{ repo_environment_file_directory }}\\{{ environment.filename }}' - - type: evaluate-variable@1 - name: runsettings_file_exists - value: 'file.file_exists(repo_environment_file_directory + "\\" + environment.filename)' - actions: - - type: command@1 - name: TA Systeem {{ environment.name }} - command: cmd - arguments: /k dotnet test -c release "{{ system_tests_filename }}" {{ system_tests_filter }} --settings:"{{ runsettings_file }}" - active: 'system_tests_filename_exists && runsettings_file_exists' - - type: command@1 - name: TA Smoke {{ environment.name }} - command: cmd - arguments: /k dotnet test -c release "{{ smoke_tests_filename }}" {{ smoke_tests_filter }} --settings:"{{ runsettings_file }}" - active: 'smoke_tests_filename_exists && runsettings_file_exists' - -- type: separator@1 - -- type: browse-repository@1 - - type: folder@1 name: Git actions: + - type: browse-repository@1 - type: git-fetch@1 - type: git-pull@1 - type: git-push@1 @@ -592,21 +200,12 @@ action-menu: - type: folder@1 name: '-- Examples --' actions: - - type: clipboard-copy@1 - name: Copy current branch name - text: '{{ repository.branch }}' - - - type: clipboard-copy@1 - name: Copy command 'git checkout -b {{ repository.branch | string.truncate 15 "..." }}' - text: '{{ repository.branch }}' - active: 'repository.branch | string.starts_with "feature/"' + + - type: just-text@1 + name: 'Current branch is {{ repository.branch }}' - type: command@1 name: 'Create Directory {{ repo_docs_directory }}' command: cmd arguments: /k mkdir "{{ repo_docs_directory }}" active: '!file.dir_exists(repo_docs_directory)' - - - type: just-text@1 - name: 'Usage counter: {{ statistics.count }}' - active: true \ No newline at end of file diff --git a/src/RepoM.Api/Resources/appsettings.serilog.json b/src/RepoM.Api/Resources/appsettings.serilog.json new file mode 100644 index 00000000..6ed7718c --- /dev/null +++ b/src/RepoM.Api/Resources/appsettings.serilog.json @@ -0,0 +1,18 @@ +{ + "Serilog": { + "Using": [ "Serilog.Sinks.File" ], + "MinimumLevel": "Verbose", + "WriteTo": [ + { + "Name": "File", + "Args": + { + "path": "%APPDATA%/RepoM/Logs/repom.txt", + "rollingInterval": "Day", + "outputTemplate": "{Timestamp:HH:mm:ss.fff zzz} [{Level:u3}] [{ThreadId}:{ThreadName}] {Message}{NewLine}{Exception}" + } + } + ], + "Enrich": [ "WithThreadId" ] + } +} \ No newline at end of file diff --git a/src/RepoM.App/App.xaml.cs b/src/RepoM.App/App.xaml.cs index 2e6b515b..68a51096 100644 --- a/src/RepoM.App/App.xaml.cs +++ b/src/RepoM.App/App.xaml.cs @@ -64,7 +64,7 @@ protected override async void OnStartup(StartupEventArgs e) IHmacService hmacService = new HmacSha256Service(); IPluginFinder pluginFinder = new PluginFinder(fileSystem, hmacService); - IConfiguration config = SetupConfiguration(fileSystem); + IConfiguration config = SetupConfiguration(); ILoggerFactory loggerFactory = CreateLoggerFactory(config); ILogger logger = loggerFactory.CreateLogger(nameof(App)); logger.LogInformation("Started"); @@ -74,6 +74,8 @@ protected override async void OnStartup(StartupEventArgs e) #if DEBUG Bootstrapper.Container.Verify(SimpleInjector.VerificationOption.VerifyAndDiagnose); +#else + Bootstrapper.Container.Options.EnableAutoVerification = false; #endif EnsureStartup ensureStartup = Bootstrapper.Container.GetInstance(); @@ -81,8 +83,6 @@ protected override async void OnStartup(StartupEventArgs e) UseRepositoryMonitor(Bootstrapper.Container); - _ = Bootstrapper.Container.GetInstance(); // not sure if this is required. - _moduleService = Bootstrapper.Container.GetInstance(); _hotKeyService = Bootstrapper.Container.GetInstance(); _windowSizeService = Bootstrapper.Container.GetInstance(); @@ -115,30 +115,10 @@ protected override void OnExit(ExitEventArgs e) base.OnExit(e); } - private static IConfiguration SetupConfiguration(IFileSystem fileSystem) + private static IConfiguration SetupConfiguration() { const string FILENAME = "appsettings.serilog.json"; var fullFilename = Path.Combine(DefaultAppDataPathProvider.Instance.AppDataPath, FILENAME); - if (!fileSystem.File.Exists(fullFilename)) - { - try - { - var fullFilenameTemplate = Path.Combine(DefaultAppDataPathProvider.Instance.AppResourcesPath, FILENAME); - if (fileSystem.File.Exists(fullFilenameTemplate)) - { - fileSystem.File.Copy(fullFilenameTemplate, fullFilename); - } - } - catch (Exception) - { - // swallow - } - } - - if (!fileSystem.File.Exists(fullFilename)) - { - fullFilename = FILENAME; - } IConfigurationBuilder builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) diff --git a/src/RepoM.Core.Plugin/Common/IAppDataPathProvider.cs b/src/RepoM.Core.Plugin/Common/IAppDataPathProvider.cs index 137b61d7..eba01b99 100644 --- a/src/RepoM.Core.Plugin/Common/IAppDataPathProvider.cs +++ b/src/RepoM.Core.Plugin/Common/IAppDataPathProvider.cs @@ -3,6 +3,4 @@ namespace RepoM.Core.Plugin.Common; public interface IAppDataPathProvider { string AppDataPath { get; } - - string AppResourcesPath { get; } } \ No newline at end of file From 80f3662248fd01146b13972f901244716b759c4f Mon Sep 17 00:00:00 2001 From: Coen van den Munckhof Date: Tue, 2 Apr 2024 21:13:27 +0200 Subject: [PATCH 4/7] Update --- src/RepoM.Api/Resources/RepoM.Filtering.yaml | 2 +- .../Resources/RepositoryActionsV2.yaml | 45 +++++-------------- 2 files changed, 13 insertions(+), 34 deletions(-) diff --git a/src/RepoM.Api/Resources/RepoM.Filtering.yaml b/src/RepoM.Api/Resources/RepoM.Filtering.yaml index 62335d1e..52ff09c4 100644 --- a/src/RepoM.Api/Resources/RepoM.Filtering.yaml +++ b/src/RepoM.Api/Resources/RepoM.Filtering.yaml @@ -15,4 +15,4 @@ Private: query: RepoM OR is:pinned filter: kind: query@1 - query: (-tag:work OR tag:prive) \ No newline at end of file + query: (-tag:work OR tag:private) \ No newline at end of file diff --git a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml index dfb1fa6d..9a713b37 100644 --- a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml +++ b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml @@ -1,6 +1,11 @@ context: - type: evaluate-script@1 content: |- + # at this moment, you must leave this function intact + func translate(input) + ret input + end + func is_null(input) ret input == null end @@ -49,19 +54,13 @@ context: remote_name_origin = get_remote_origin_name(); is_work_repository = remotes_contain("My-Work"); - is_bdo_tis_repository = is_work_repository && file.file_exists(repository.linux_path + "/.azuredevops/Pipelines/gated.yml") is_github_repository = remotes_contain("github.com"); solution_files = file.find_files(repository.linux_path, "*.sln"); solution_file = array.first(solution_files); - system_test_csproj_files = file.find_files(repository.linux_path, "*.SystemTests.csproj"); - smoke_tests_csproj_files = file.find_files(repository.linux_path, "*.SmokeTests.csproj"); exe_vs_code = env.LocalAppData + "/Programs/Microsoft VS Code/code.exe"; - path_repo_tis_wat = `C:\Users\Munckhof CJJ\OneDrive - BDO\BDO\TisWatConfig\` + remote_name_origin; - path_bdo_repo_root = `C:\Projects\Bdo\git\`; - - root_path_repom: C:\\Users\\Munckhof CJJ\\OneDrive - BDO\\BDO\\RepoM\\ # Specific var files @@ -70,10 +69,6 @@ context: value: 'G:\\My Drive\\RepoDocs\\github.com\\{{ remote_name_origin }}' enabled: is_github_repository -- type: render-variable@1 - name: repo_docs_directory - value: 'C:\\Users\\Munckhof CJJ\\OneDrive - BDO\\BDO\\RepoDocs\\{{ remote_name_origin }}' - # Env files - type: render-variable@1 name: repo_environment_file_directory @@ -85,33 +80,15 @@ context: - type: render-variable@1 name: repo_yaml_file - value: '{{ env.REPOZ_CONFIG_PATH }}\\{{ remote_name_origin }}\\RepoMV2.yaml' - -- type: render-variable@1 - name: repo_environment_template_file - value: '{{ env.REPOZ_CONFIG_PATH }}\\RepoM.Template.env' + value: 'C:\\WorkCofigs\\{{ remote_name_origin }}\\RepoMV2.yaml' # Runsettings -- type: render-variable@1 - name: runsettings_file_directory - value: '{{ env.REPOZ_CONFIG_PATH }}\\{{ remote_name_origin }}' -- type: render-variable@1 - name: runsettings_file - value: '{{ env.REPOZ_CONFIG_PATH }}\\{{ remote_name_origin }}\\local.runsettings' -- type: render-variable@1 - name: runsettings_template_file - value: '{{ env.REPOZ_CONFIG_PATH }}\\Runsettings.Template.runsettings' - -# - type: load-file@1 -# filename: '{{ repo_yaml_file }}' -# enabled: is_bdo_tis_repository - - type: load-file@1 filename: '{{ repo_environment_file }}' enabled: is_work_repository - type: load-file@1 - filename: '{{ env.REPOZ_CONFIG_PATH }}\\BDO.env' + filename: '{{ env.REPOZ_CONFIG_PATH }}\\work.env' enabled: is_work_repository - type: load-file@1 @@ -119,10 +96,12 @@ context: enabled: is_work_repository tags: -- tag: Work + +- tag: work when: is_work_repository -- tag: Private - when: '!is_work_repository || repository_path_contains("Projects/Private") ' + +- tag: private + when: '!is_work_repository && repository_path_contains("Projects/Private")' action-menu: From 76be54b190f0cc6467a8aae810bb189beebf0de5 Mon Sep 17 00:00:00 2001 From: Coen van den Munckhof Date: Tue, 2 Apr 2024 21:35:42 +0200 Subject: [PATCH 5/7] .. --- src/RepoM.Api/EnsureStartup.cs | 9 ++-- tests/RepoM.Api.Tests/EnsureStartupTests.cs | 55 +++++++++++++++++++++ 2 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 tests/RepoM.Api.Tests/EnsureStartupTests.cs diff --git a/src/RepoM.Api/EnsureStartup.cs b/src/RepoM.Api/EnsureStartup.cs index 771c5a84..6c3a1d22 100644 --- a/src/RepoM.Api/EnsureStartup.cs +++ b/src/RepoM.Api/EnsureStartup.cs @@ -23,7 +23,6 @@ public async Task EnsureFilesAsync() await CheckOrCreateAsync("RepositoryActionsV2.yaml", EmbeddedResources.GetRepositoryActionsV2Yaml).ConfigureAwait(false); await CheckOrCreateAsync("RepoM.Filtering.yaml", EmbeddedResources.GetFilteringYaml).ConfigureAwait(false); await CheckOrCreateAsync("RepoM.Ordering.yaml", EmbeddedResources.GetSortingYaml).ConfigureAwait(false); - await CheckOrCreateAsync("RepoM.Ordering.yaml", EmbeddedResources.GetSortingYaml).ConfigureAwait(false); await CheckOrCreateAsync("appsettings.serilog.json", EmbeddedResources.GetSerilogAppSettings).ConfigureAwait(false); } @@ -31,12 +30,14 @@ private async Task CheckOrCreateAsync(string filename, Func func) { var fullFilename = Path.Combine(_appDataProvider.AppDataPath, filename); - if (!_fileSystem.File.Exists(fullFilename)) + if (_fileSystem.File.Exists(fullFilename)) { - await using Stream stream = func.Invoke(); - await TryCreateAsync(fullFilename, stream).ConfigureAwait(false); + return; } + await using Stream stream = func.Invoke(); + await TryCreateAsync(fullFilename, stream).ConfigureAwait(false); + if (!_fileSystem.File.Exists(fullFilename)) { throw new FileNotFoundException(fullFilename); diff --git a/tests/RepoM.Api.Tests/EnsureStartupTests.cs b/tests/RepoM.Api.Tests/EnsureStartupTests.cs new file mode 100644 index 00000000..24b50835 --- /dev/null +++ b/tests/RepoM.Api.Tests/EnsureStartupTests.cs @@ -0,0 +1,55 @@ +namespace RepoM.Api.Tests; + +using System; +using System.IO; +using System.IO.Abstractions; +using System.Threading.Tasks; +using FakeItEasy; +using FluentAssertions; +using RepoM.Core.Plugin.Common; +using Xunit; + +public class EnsureStartupTests +{ + private readonly IFileSystem _fileSystem = A.Fake(); + private readonly IAppDataPathProvider _appDataProvider = A.Fake(); + private readonly EnsureStartup _sut; + + public EnsureStartupTests() + { + _sut = new EnsureStartup(_fileSystem, _appDataProvider); + A.CallTo(() => _appDataProvider.AppDataPath).Returns(Path.Combine("C:", "my-dummy", "path")); + } + + [Fact] + public void Ctor_ShouldThrow_WhenArgumentNull() + { + // arrange + + // act + Func act1 = () => new EnsureStartup(_fileSystem, null!); + Func act2 = () => new EnsureStartup(null!, _appDataProvider); + + // assert + act1.Should().Throw(); + act2.Should().Throw(); + } + + [Theory] + [InlineData("RepositoryActionsV2.yaml")] + [InlineData("RepoM.Filtering.yaml")] + [InlineData("RepoM.Ordering.yaml")] + [InlineData("appsettings.serilog.json")] + public async Task EnsureFilesAsync_ShouldCheckIfFileExists(string filename) + { + // arrange + var expectedFilename = Path.Combine("C:", "my-dummy", "path", filename); + A.CallTo(() => _fileSystem.File.Exists(A._)).Returns(true); + + // act + await _sut.EnsureFilesAsync(); + + // assert + A.CallTo(() => _fileSystem.File.Exists(expectedFilename)).MustHaveHappenedOnceExactly(); + } +} \ No newline at end of file From 885c3d9eeb08c7bce183dc37433e885c933bdc0a Mon Sep 17 00:00:00 2001 From: Coen van den Munckhof Date: Tue, 2 Apr 2024 21:42:37 +0200 Subject: [PATCH 6/7] .. --- tests/RepoM.Api.Tests/EnsureStartupTests.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/RepoM.Api.Tests/EnsureStartupTests.cs b/tests/RepoM.Api.Tests/EnsureStartupTests.cs index 24b50835..4edbbe7e 100644 --- a/tests/RepoM.Api.Tests/EnsureStartupTests.cs +++ b/tests/RepoM.Api.Tests/EnsureStartupTests.cs @@ -52,4 +52,21 @@ public async Task EnsureFilesAsync_ShouldCheckIfFileExists(string filename) // assert A.CallTo(() => _fileSystem.File.Exists(expectedFilename)).MustHaveHappenedOnceExactly(); } + + [Theory] + [InlineData("RepositoryActionsV2.yaml")] + [InlineData("RepoM.Filtering.yaml")] + [InlineData("RepoM.Ordering.yaml")] + [InlineData("appsettings.serilog.json")] + public async Task EnsureFilesAsync_ShouldWhenFileDoesNotExists(string filename) + { + // arrange + A.CallTo(() => _fileSystem.File.Exists(A.That.EndsWith(filename))).Returns(false); + + // act + Func act = _sut.EnsureFilesAsync; + + // assert + await act.Should().ThrowAsync(); + } } \ No newline at end of file From db2436bd6e466188c4af9aab96e27d653c73c7b5 Mon Sep 17 00:00:00 2001 From: Coen van den Munckhof Date: Tue, 2 Apr 2024 22:02:20 +0200 Subject: [PATCH 7/7] .. --- tests/RepoM.Api.Tests/EnsureStartupTests.cs | 24 +++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/tests/RepoM.Api.Tests/EnsureStartupTests.cs b/tests/RepoM.Api.Tests/EnsureStartupTests.cs index 4edbbe7e..00ec3872 100644 --- a/tests/RepoM.Api.Tests/EnsureStartupTests.cs +++ b/tests/RepoM.Api.Tests/EnsureStartupTests.cs @@ -3,6 +3,7 @@ namespace RepoM.Api.Tests; using System; using System.IO; using System.IO.Abstractions; +using System.Threading; using System.Threading.Tasks; using FakeItEasy; using FluentAssertions; @@ -58,15 +59,34 @@ public async Task EnsureFilesAsync_ShouldCheckIfFileExists(string filename) [InlineData("RepoM.Filtering.yaml")] [InlineData("RepoM.Ordering.yaml")] [InlineData("appsettings.serilog.json")] - public async Task EnsureFilesAsync_ShouldWhenFileDoesNotExists(string filename) + public async Task EnsureFilesAsync_ShouldThrowFileNotFoundException_WhenFileDoesNotExists(string filename) { // arrange + A.CallTo(() => _fileSystem.File.Exists(A._)).Returns(true); A.CallTo(() => _fileSystem.File.Exists(A.That.EndsWith(filename))).Returns(false); // act Func act = _sut.EnsureFilesAsync; // assert - await act.Should().ThrowAsync(); + await act.Should().ThrowAsync().WithMessage("*" + filename); + } + + [Theory] + [InlineData("RepositoryActionsV2.yaml")] + [InlineData("RepoM.Filtering.yaml")] + [InlineData("RepoM.Ordering.yaml")] + [InlineData("appsettings.serilog.json")] + public async Task EnsureFilesAsync_ShouldCreate_WhenFileDoesNotExists(string filename) + { + // arrange + A.CallTo(() => _fileSystem.File.Exists(A._)).Returns(true); + A.CallTo(() => _fileSystem.File.Exists(A.That.EndsWith(filename))).ReturnsNextFromSequence(false, true); + + // act + await _sut.EnsureFilesAsync(); + + // assert + A.CallTo(() => _fileSystem.File.WriteAllBytesAsync(A.That.EndsWith(filename), A._, A._)).MustHaveHappenedOnceExactly(); } } \ No newline at end of file