Code Monkey home page Code Monkey logo

dotnet-affected's People

Contributors

bartlomiejgawel avatar batkaevruslan avatar leonardochaia avatar megakid avatar satano avatar shlomiassaf avatar tanordheim avatar wterpstra avatar xicefox avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

dotnet-affected's Issues

Ability to exclude projects

We have unit tests and integration tests in the same repository.
We have a CI pipeline where the unit tests will run and we don't want this pipeline to run the integration tests, even if some of these projects have had changes.
So I think it would be useful to have some way to exclude these projects from the dotnet-affected output.

Incorrect evaluation of 'Directory.Packages.props'

The logic for processing Directory.Packages.props in a central package versioning report does not follow the spec:

var packagePropsPath = changedFiles
.SingleOrDefault(f => f.EndsWith("Directory.Packages.props"));

It assumes a single Directory.Packages.props can exist in a repo.

If there are multiple, and both have changed in the same run it will throw.

From Microsoft docs:

NuGet's .props files automatically import a file named Directory.Packages.props if it's found in the project folder or any of its ancestors.

I.E the first Directory.Packages.props file found in the project's directory or any other folder up to the root (solution directory) is used. If a file is found and there are additional files in ancestor folders they are ignored by the build.

Usually, one will build nested Directory.Packages.props files like this:

<Project>

    <!-- First import top level package props... -->

    <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory).., Directory.Packages.props))\Directory.Packages.props" />

    <!-- Override/Add with project local versioning -->

    <ItemGroup>
        <PackageVersion Include="System.Text.Json" Version="6.0.4" />
    </ItemGroup>
</Project>

Since MS Build Project instance is used to load the package props:

var project = new Project(reader);

I can only assume the only file we need to load is the one closest to the project folder and ignore (but not fail) others.

For the a 1st phase fix this will suffice.

It is however, not 100% accurate, but a bit more complex to perfect it... I'll elaborate in a new comment below

NullReference exception when running dotnet affected on a set of changes that adds the Directory.Packages.props file

I just added central management of NuGet packages and it dotnet affected fails with a NullReferenceException. From the stacktrace it looks like it tries to read the Directory.Packages.props from the 'previous' commit but it (obviously) can't find it there and throws a NullReference exception.

From GitChangesProvider:

private static string ReadTextFile(string pathToFile, Commit commit)
        {
            var blob = (Blob)commit[pathToFile].Target; // When commit does not contain file it will go boom here

            using var content = new StreamReader(blob.GetContentStream(), Encoding.UTF8);
            return content.ReadToEnd();
        }

I think it would be wise to check for this and return an empty string instead.

Stacktrace:

2022-03-14T08:57:01.5290841Z Unhandled exception: System.NullReferenceException: Object reference not set to an instance of an object.
2022-03-14T08:57:01.5293712Z    at Affected.Cli.GitChangesProvider.ReadTextFile(String pathToFile, Commit commit) in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Infrastructure/GitChangesProvider.cs:line 44
2022-03-14T08:57:01.5296484Z    at Affected.Cli.GitChangesProvider.GetTextFileContents(String directory, String pathToFile, String from, String to) in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Infrastructure/GitChangesProvider.cs:line 33
2022-03-14T08:57:01.5299157Z    at Affected.Cli.Commands.CommandExecutionContext.DetermineChangedNugetPackages() in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Commands/Context/CommandExecutionContext.cs:line 117
2022-03-14T08:57:01.5300524Z    at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
2022-03-14T08:57:01.5301503Z    at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
2022-03-14T08:57:01.5302372Z    at System.Lazy`1.CreateValue()
2022-03-14T08:57:01.5303471Z    at System.Lazy`1.get_Value()
2022-03-14T08:57:01.5305352Z    at Affected.Cli.Commands.CommandExecutionContext.get_ChangedNuGetPackages() in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Commands/Context/CommandExecutionContext.cs:line 45
2022-03-14T08:57:01.5307691Z    at Affected.Cli.Views.AffectedInfoView..ctor(ICommandExecutionContext context) in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Views/AffectedInfoView.cs:line 12
2022-03-14T08:57:01.5310675Z    at Affected.Cli.Commands.AffectedRootCommand.AffectedCommandHandler.InvokeAsync(InvocationContext ic) in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Commands/AffectedRootCommand.cs:line 63
2022-03-14T08:57:01.5312292Z    at System.CommandLine.NamingConventionBinder.CommandHandler.GetExitCodeAsync(Object returnValue, InvocationContext context)
2022-03-14T08:57:01.5313540Z    at System.CommandLine.NamingConventionBinder.ModelBindingCommandHandler.InvokeAsync(InvocationContext context)
2022-03-14T08:57:01.5314727Z    at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()
2022-03-14T08:57:01.5315982Z --- End of stack trace from previous location ---
2022-03-14T08:57:01.5316963Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass18_0.<<UseParseErrorReporting>b__0>d.MoveNext()
2022-03-14T08:57:01.5318265Z --- End of stack trace from previous location ---
2022-03-14T08:57:01.5320615Z    at Affected.Cli.ErrorHandlingMiddleware.<>c__DisplayClass0_0.<<UseRenderingErrorHandler>b__0>d.MoveNext() in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/CommandLine/ErrorHandlingMiddleware.cs:line 26
2022-03-14T08:57:01.5322317Z --- End of stack trace from previous location ---
2022-03-14T08:57:01.5323270Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<AddMiddleware>b__0>d.MoveNext()
2022-03-14T08:57:01.5324520Z --- End of stack trace from previous location ---
2022-03-14T08:57:01.5325468Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<AddMiddleware>b__0>d.MoveNext()
2022-03-14T08:57:01.5326705Z --- End of stack trace from previous location ---
2022-03-14T08:57:01.5327673Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<AddMiddleware>b__0>d.MoveNext()
2022-03-14T08:57:01.5328904Z --- End of stack trace from previous location ---
2022-03-14T08:57:01.5329870Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass13_0.<<UseHelp>b__0>d.MoveNext()
2022-03-14T08:57:01.5331099Z --- End of stack trace from previous location ---
2022-03-14T08:57:01.5332076Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass22_0.<<UseVersionOption>b__0>d.MoveNext()
2022-03-14T08:57:01.5333324Z --- End of stack trace from previous location ---
2022-03-14T08:57:01.5334294Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass20_0.<<UseTypoCorrections>b__0>d.MoveNext()
2022-03-14T08:57:01.5335581Z --- End of stack trace from previous location ---
2022-03-14T08:57:01.5336489Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__19_0>d.MoveNext()
2022-03-14T08:57:01.5337708Z --- End of stack trace from previous location ---
2022-03-14T08:57:01.5338672Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass17_0.<<UseParseDirective>b__0>d.MoveNext()
2022-03-14T08:57:01.5339957Z --- End of stack trace from previous location ---
2022-03-14T08:57:01.5340881Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__6_0>d.MoveNext()
2022-03-14T08:57:01.5342110Z --- End of stack trace from previous location ---
2022-03-14T08:57:01.5343264Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass9_0.<<UseExceptionHandler>b__0>d.MoveNext()
2022-03-14T08:57:04.9154009Z Unhandled exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
2022-03-14T08:57:04.9156920Z  ---> System.NullReferenceException: Object reference not set to an instance of an object.
2022-03-14T08:57:04.9159581Z    at Affected.Cli.GitChangesProvider.ReadTextFile(String pathToFile, Commit commit) in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Infrastructure/GitChangesProvider.cs:line 44
2022-03-14T08:57:04.9163573Z    at Affected.Cli.GitChangesProvider.GetTextFileContents(String directory, String pathToFile, String from, String to) in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Infrastructure/GitChangesProvider.cs:line 33
2022-03-14T08:57:04.9167268Z    at Affected.Cli.Commands.CommandExecutionContext.DetermineChangedNugetPackages() in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Commands/Context/CommandExecutionContext.cs:line 117
2022-03-14T08:57:04.9169070Z    at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
2022-03-14T08:57:04.9170410Z    at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
2022-03-14T08:57:04.9171669Z    at System.Lazy`1.CreateValue()
2022-03-14T08:57:04.9172606Z    at System.Lazy`1.get_Value()
2022-03-14T08:57:04.9174839Z    at Affected.Cli.Commands.CommandExecutionContext.get_ChangedNuGetPackages() in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Commands/Context/CommandExecutionContext.cs:line 45
2022-03-14T08:57:04.9182464Z    at Affected.Cli.Views.AffectedInfoView..ctor(ICommandExecutionContext context) in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Views/AffectedInfoView.cs:line 12
2022-03-14T08:57:04.9185195Z    at Affected.Cli.Commands.DescribeCommand.CommandHandler.InvokeAsync(InvocationContext ic) in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Commands/DescribeCommand.cs:line 30
2022-03-14T08:57:04.9186740Z    --- End of inner exception stack trace ---
2022-03-14T08:57:04.9187761Z    at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
2022-03-14T08:57:04.9189100Z    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
2022-03-14T08:57:04.9190225Z    at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
2022-03-14T08:57:04.9191254Z    at System.CommandLine.NamingConventionBinder.ModelBindingCommandHandler.InvokeAsync(InvocationContext context)
2022-03-14T08:57:04.9192501Z    at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()
2022-03-14T08:57:04.9193740Z --- End of stack trace from previous location ---
2022-03-14T08:57:04.9194444Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass18_0.<<UseParseErrorReporting>b__0>d.MoveNext()
2022-03-14T08:57:04.9195120Z --- End of stack trace from previous location ---
2022-03-14T08:57:04.9196154Z    at Affected.Cli.ErrorHandlingMiddleware.<>c__DisplayClass0_0.<<UseRenderingErrorHandler>b__0>d.MoveNext() in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/CommandLine/ErrorHandlingMiddleware.cs:line 26
2022-03-14T08:57:04.9197036Z --- End of stack trace from previous location ---
2022-03-14T08:57:04.9197531Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<AddMiddleware>b__0>d.MoveNext()
2022-03-14T08:57:04.9198196Z --- End of stack trace from previous location ---
2022-03-14T08:57:04.9198692Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<AddMiddleware>b__0>d.MoveNext()
2022-03-14T08:57:04.9199350Z --- End of stack trace from previous location ---
2022-03-14T08:57:04.9199846Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<AddMiddleware>b__0>d.MoveNext()
2022-03-14T08:57:04.9200500Z --- End of stack trace from previous location ---
2022-03-14T08:57:04.9200981Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass13_0.<<UseHelp>b__0>d.MoveNext()
2022-03-14T08:57:04.9201607Z --- End of stack trace from previous location ---
2022-03-14T08:57:04.9202126Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass22_0.<<UseVersionOption>b__0>d.MoveNext()
2022-03-14T08:57:04.9202770Z --- End of stack trace from previous location ---
2022-03-14T08:57:04.9203291Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass20_0.<<UseTypoCorrections>b__0>d.MoveNext()
2022-03-14T08:57:04.9204101Z --- End of stack trace from previous location ---
2022-03-14T08:57:04.9204592Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__19_0>d.MoveNext()
2022-03-14T08:57:04.9205208Z --- End of stack trace from previous location ---
2022-03-14T08:57:04.9205706Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass17_0.<<UseParseDirective>b__0>d.MoveNext()
2022-03-14T08:57:04.9206373Z --- End of stack trace from previous location ---
2022-03-14T08:57:04.9206853Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__6_0>d.MoveNext()
2022-03-14T08:57:04.9207498Z --- End of stack trace from previous location ---
2022-03-14T08:57:04.9208001Z    at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass9_0.<<UseExceptionHandler>b__0>d.MoveNext()

Can we have an MSBuild Task that, when used, makes `dotnet build` only what's affected?

I've never built an MSBuild Task before so I don't really know, but I was thinking that maybe if we can use the underlying logic behind discovering affected projects inside a Task, we may be able to modify which projects will be build.

So in CI you would reference a nuget package that would add the affected task and you just need to build. No need to generate the traversal and stuff.

That would be a nice way to integrate with existing projects!

Make '--verbose' parameter more verbose

When I use --verbose parameter, it show some more info. but this is just some statistical info: count of changed files and projects. This itself is fine.

describe command is interesting, because it writes which projects are changed and which are affected by changes. But this command just prints this information, it does not saves .proj file.

It would be nice to have describe's command information in standard output when using --verbose. This is good for logs, where we can immediately see which projects have changed. In CI builds, there is hard (or no at all) possibility to inspect output .proj file, but logs are available for a long time.

Finding affected projects take longer then expected

Hi, I have cases when finding affected projects takes more then 10 minutes, then I abort my job and can't continue from this point.
I suggest to have an option to configure timeout and if timeout reached then mark all solution as affected (all csproj files).

We have a big solution project and sometimes when there's a lot of changes and it just hangs forever :(

Deleted file does not affect project

I've noticed that if file deletion is the only change, dotnet-affected does not include the project in the list of affected.

File deletion can break compilation of the project, so it must be returned as affected.

Repro:
I've created a test to show the issue (test fails):

        [Fact]
        public async Task When_file_is_deleted_from_project_project_should_have_changed()
        {
            // Create a project
            var projectName = "InventoryManagement";
            var msBuildProject = Repository.CreateCsProject(projectName);
            // Create a file with some changes
            var targetFilePath = Path.Combine(projectName, "file.cs");
            await this.Repository.CreateTextFileAsync(targetFilePath, "// Initial content");

            // Make a commit and keep track of the sha
            this._fromCommit = Repository.StageAndCommit()
                .Sha;

            this.Repository.DeleteFile(targetFilePath);
            // Commit the changes
            this._toCommit = Repository.StageAndCommit()
                .Sha;

            Assert.Single(AffectedSummary.ProjectsWithChangedFiles);
            Assert.Empty(AffectedSummary.AffectedProjects);

            var projectInfo = AffectedSummary.ProjectsWithChangedFiles.Single();
            Assert.Equal(projectName, projectInfo.GetProjectName());
            Assert.Equal(msBuildProject.FullPath, projectInfo.GetFullPath());
        }

How should we handle not having any changes?

Currently the tool just outputs nothing:

dotnet affected generate --verbose --output /tmp/tobuild.proj --to <redacted> --from <redacted>

Finding all csproj at /var/jenkins_home/workspace/<redacted>

Building Dependency Graph

Found 92 projects

Finding changes from <redacted> against <redacted>

Found 24 changed files inside 0 projects.

Files inside these projects have changed:

These projects are affected by those changes:

Generating Traversal SDK Project

Creating file at /tmp/tobuild.proj

Should we exit with > 0?

At least improve presentation messages

Support discovering projects through an existing Traversal project

dotnet-affected currently supports discovering projects from an existing solution file via --solution-path, or by recursively searching the repository path (either the current working directory or the path specified via --repository-path).

In order to use dotnet-affected in a repository that already uses the Traversal SDK, users first need to generate a solution file from their existing traversal file, and then provide that solution file to dotnet-affected so it can in turn generate a new Traversal file.

It would be awesome if dotnet-affected could cut out the middleperson and parse an existing Traversal project to determine which project files it should consider.

Thanks for all the work you've put into this project, it's a great tool!

Add format options to README.md and --help

First of all, I love your project! Thank you for your work!

It would be cool to have a support for a command flag, which outputs a txt/json (preferably json) besides the traversal file, including all the affected project names (could be a file or just command line output). This would be especially useful for ci runs where you need to decide which projects to deploy. With json, you could pipe the information to further tools and parse them to objects.

I would really appreciate if this would be included in this tool.

split code to library and CLI

Thank you for this tool!

I would like to suggest splitting it into a standalone library and cli tool.

We have a dedicated process with an internal tool and integration this one would be great however it only comes as a CLI tool.

It will be great to have this as a library and getting back the list of projects as the response and doing whatever we need with it.

Support reading projects from a solution file

I have a repository with a large amount of projects inside that i'd like to scan for affected changes. This repo contains a sub repo with also many projects, however, my project only uses a single project from that subrepo (not optimal, but it works). This project is included in my solution but the others are not.

I have tested something where I added the functionality to pass a --solution-path <solution-path> argument with the path to the solution from which to load the projects. I will take the liberty to create a pull request so you can inspect this feature.

Changes in Directory.Build.props not detected

We work with a Directory.Build.Props file that adds some of the Tags to all projects in the same folder. When this file changes, dotnet-affected does not detect the change, even if it can affect the whole project (for example changing .net version)

Example:

<Project>
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <LangVersion>10.0</LangVersion>
    <RuntimeIdentifiers>win-x64</RuntimeIdentifiers>
    <Product>My Product</Product>
  </PropertyGroup>
</Project>

I dont know how that could be detected either.

Missing support for ManagePackageVersionsCentrally

When using ManagePackageVersionsCentrally as the model of package versioning then the affected doesn't know
which project is affected from a version change, it's crucial in case dependency upgrade will cause a CI break.

Running tool in Azure Pipelines will throw exception

When running the tool in Azure Pipelines to inspect my repository it throws the following exception:

Command I run:

dotnet affected -p $(System.DefaultWorkingDirectory) --from origin/develop generate --output $(System.DefaultWorkingDirectory)\changed.proj
Unhandled exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at System.CommandLine.Rendering.Views.ScreenView.Render(Region region)
   at Affected.Cli.Views.ViewRenderingContext.Render(View rootView) in C:\Projects\dotnet-affected\src\dotnet-affected\Views\ViewRenderingContext.cs:line 29
   at Affected.Cli.Commands.GenerateCommand.GenTraversalHandler(IConsole console, String output, CommandExecutionData data, ViewRenderingContext renderingContext) in C:\Projects\dotnet-affected\src\dotnet-affected\Commands\GenerateCommand.cs:line 71
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Delegate.DynamicInvokeImpl(Object[] args)
   at System.Delegate.DynamicInvoke(Object[] args)
   at System.CommandLine.Invocation.ModelBindingCommandHandler.InvokeAsync(InvocationContext context)
   at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass23_0.<<UseParseErrorReporting>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<UseHelp>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass27_0.<<UseVersionOption>b__1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass25_0.<<UseTypoCorrections>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__24_0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass22_0.<<UseParseDirective>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass11_0.<<UseDebugDirective>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__10_0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass14_0.<<UseExceptionHandler>b__0>d.MoveNext()

It looks like the System.CommandLine.Rendering package cannot handle the way that Azure DevOps handles the stdout.

Ability to distinguish between changed and affected projects

Currently the tool helpfully reports all the changed or affected projects, both in .proj and in json.
One thing that is missing is to be able to know what project have actually changed and what are affected by the change.

Reason

This information is extremely useful in certain CI/CD scenarious.
For example, when we want to automatically bump the major version for the project that were actually changed, but the affected projects would probably get only a patch version bump.

Possible implementation

I see that internally the tool does have all this information, and I think that it'd be beneficial to propagate it into the output.

Json output can contain a new State field:

[
  {
    "Name": "Project1",
    "FilePath": "/path/to/project1.csproj",
    "State": "Changed"
  },
  {
    "Name": "Project2",
    "FilePath": "/path/to/project2.csproj",
    "State": "Affected"
  },
]

And for MSBuild we can have two item groups (Changed and Affected):

<Project Sdk="Microsoft.Build.Traversal/3.0.3">
  <ItemGroup Label="Changed">
    <ProjectReference Include="/path/to/project1.csproj" />
  </ItemGroup>
  <ItemGroup Label="Affected">
    <ProjectReference Include="/path/to/project2.csproj" />
  </ItemGroup>
</Project>

Support other kinds of MSBuild projects

Currently, when using --repository-path, only .csproj files will be discovered.

When using a --solution-path, all projects inside the solution will be taken into account.

We should discover all MSBuild projs when using the --repository-path as well.

Error: Couldn't find Git Commit or Branch with name

Hi, I'm running a Github workflow and getting the following error:
Unhandled exception: System.InvalidOperationException: Couldn't find Git Commit or Branch with name develop in repository /home/runner/work/[...]/[...]/.git/

The command that runs is:
dotnet affected -f text traversal --from feature/nuget-publish-workflow --to develop

When I run this on my local working dir I'm not getting the error, but if I fetch the repo with the same command the GH action does, then I can reproduce the error locally (I'm fetching with fetch-depth: 0).

Full stack trace:

/usr/share/dotnet/dotnet affected -f text traversal --from feature/nuget-publish-workflow --to develop
Unhandled exception: System.InvalidOperationException: Couldn't find Git Commit or Branch with name develop in repository /home/runner/work/[...]/[...]/.git/
   at Affected.Cli.GitChangesProvider.GetCommitOrThrow(Repository repo, String name) in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Infrastructure/GitChangesProvider.cs:line 137
   at Affected.Cli.GitChangesProvider.GetCommitOrHead(Repository repository, String name) in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Infrastructure/GitChangesProvider.cs:line [12](https://github.com/[...]/[...]/actions/runs/3215661710/jobs/5256915063#step:5:13)0
   at Affected.Cli.GitChangesProvider.ParseRevisionRanges(Repository repository, String from, String to) in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Infrastructure/GitChangesProvider.cs:line 67
   at Affected.Cli.GitChangesProvider.GetChangesForRange[T](Repository repository, String from, String to) in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Infrastructure/GitChangesProvider.cs:line 86
   at Affected.Cli.GitChangesProvider.GetChangedFiles(String directory, String from, String to) in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Infrastructure/GitChangesProvider.cs:line 15
   at Affected.Cli.Commands.CommandExecutionContext.DetermineChangedFiles() in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Commands/Context/CommandExecutionContext.cs:line 56
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.get_Value()
   at Affected.Cli.Commands.CommandExecutionContext.DetermineChangedProjects() in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Commands/Context/CommandExecutionContext.cs:line 66
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.get_Value()
   at Affected.Cli.Commands.CommandExecutionContext.get_ChangedProjects() in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Commands/Context/CommandExecutionContext.cs:line 47
   at Affected.Cli.Commands.AffectedRootCommand.AffectedCommandHandler.InvokeAsync(InvocationContext ic) in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Commands/AffectedRootCommand.cs:line 69
   at System.CommandLine.NamingConventionBinder.CommandHandler.GetExitCodeAsync(Object returnValue, InvocationContext context)
   at System.CommandLine.NamingConventionBinder.ModelBindingCommandHandler.InvokeAsync(InvocationContext context)
   at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass18_0.<<UseParseErrorReporting>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Affected.Cli.ErrorHandlingMiddleware.<>c__DisplayClass0_0.<<UseRenderingErrorHandler>b__0>d.MoveNext() in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/CommandLine/ErrorHandlingMiddleware.cs:line 26
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<AddMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<AddMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<AddMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass13_0.<<UseHelp>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass22_0.<<UseVersionOption>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass20_0.<<UseTypoCorrections>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__19_0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass17_0.<<UseParseDirective>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__6_0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass9_0.<<UseExceptionHandler>b__0>d.MoveNext()
Error: dotnet affected failed!
Error: Unhandled exception: System.InvalidOperationException: Couldn't find Git Commit or Branch with name develop in repository /home/runner/work/[...]/[...]/.git/
   at Affected.Cli.GitChangesProvider.GetCommitOrThrow(Repository repo, String name) in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Infrastructure/GitChangesProvider.cs:line [13](https://github.com/[...]/[...]/actions/runs/3215661710/jobs/5256915063#step:5:14)7
   at Affected.Cli.GitChangesProvider.GetCommitOrHead(Repository repository, String name) in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Infrastructure/GitChangesProvider.cs:line 120
   at Affected.Cli.GitChangesProvider.ParseRevisionRanges(Repository repository, String from, String to) in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Infrastructure/GitChangesProvider.cs:line 67
   at Affected.Cli.GitChangesProvider.GetChangesForRange[T](Repository repository, String from, String to) in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Infrastructure/GitChangesProvider.cs:line 86
   at Affected.Cli.GitChangesProvider.GetChangedFiles(String directory, String from, String to) in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Infrastructure/GitChangesProvider.cs:line [15](https://github.com/[...]/[...]/actions/runs/3215661710/jobs/5256915063#step:5:16)
   at Affected.Cli.Commands.CommandExecutionContext.DetermineChangedFiles() in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Commands/Context/CommandExecutionContext.cs:line 56
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.get_Value()
   at Affected.Cli.Commands.CommandExecutionContext.DetermineChangedProjects() in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Commands/Context/CommandExecutionContext.cs:line 66
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.get_Value()
   at Affected.Cli.Commands.CommandExecutionContext.get_ChangedProjects() in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Commands/Context/CommandExecutionContext.cs:line 47
   at Affected.Cli.Commands.AffectedRootCommand.AffectedCommandHandler.InvokeAsync(InvocationContext ic) in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/Commands/AffectedRootCommand.cs:line 69
   at System.CommandLine.NamingConventionBinder.CommandHandler.GetExitCodeAsync(Object returnValue, InvocationContext context)
   at System.CommandLine.NamingConventionBinder.ModelBindingCommandHandler.InvokeAsync(InvocationContext context)
   at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass18_0.<<UseParseErrorReporting>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Affected.Cli.ErrorHandlingMiddleware.<>c__DisplayClass0_0.<<UseRenderingErrorHandler>b__0>d.MoveNext() in /home/runner/work/dotnet-affected/dotnet-affected/src/dotnet-affected/CommandLine/ErrorHandlingMiddleware.cs:line 26
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass[16](https://github.com/[...]/[...]/actions/runs/3215661710/jobs/5256915063#step:5:17)_0.<<AddMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<AddMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<AddMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass13_0.<<UseHelp>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass22_0.<<UseVersionOption>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass20_0.<<UseTypoCorrections>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__19_0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass[17](https://github.com/[...]/[...]/actions/runs/3215661710/jobs/5256915063#step:5:18)_0.<<UseParseDirective>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__6_0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass9_0.<<UseExceptionHandler>b__0>d.MoveNext()

Text file contains duplicated projects

Hello,

First of all, thank you so much for this truly amazing tool!

I've noticed that a text file contains duplicated projects.

Here you can find a sample reproduction:
https://github.com/bartlomiejgawel/dotnet-affected-bug

You can clone it and run the following command:

dotnet affected --from b4d7eab --to 71b0a49 --format text traversal --dry-run

Expected behaviour: I expected that both files will contain the same number of affected projects (3) but only the proj file met my expectations. The text file contained 4 affected projects (DotnetAffected.FirstApp.csproj was duplicated).

Actual behaviour: You can see that the text file contains a duplicated project (DotnetAffected.FirstApp.csproj) comparing to the proj file:

DRY-RUN: WRITE affected.txt
DRY-RUN: CONTENTS:
DotnetAffected\DotnetAffected.FirstApp\DotnetAffected.FirstApp.csproj
DotnetAffected\DotnetAffected.Library\DotnetAffected.Library.csproj
DotnetAffected\DotnetAffected.FirstApp\DotnetAffected.FirstApp.csproj
DotnetAffected\DotnetAffected.SecondApp\DotnetAffected.SecondApp.csproj

DRY-RUN: WRITE affected.proj
DRY-RUN: CONTENTS:
<Project Sdk="Microsoft.Build.Traversal/3.0.3">
  <ItemGroup>
    <ProjectReference Include="DotnetAffected\DotnetAffected.FirstApp\DotnetAffected.FirstApp.csproj" />
    <ProjectReference Include="DotnetAffected\DotnetAffected.Library\DotnetAffected.Library.csproj" />
    <ProjectReference Include="DotnetAffected\DotnetAffected.SecondApp\DotnetAffected.SecondApp.csproj" />
  </ItemGroup>
</Project>

dotnet-affected version: 2.2.0

.NET 6 support

The dotnet-affected tool cannot run on .NET 6.

You can invoke the tool using the following command: dotnet-affected
Tool 'dotnet-affected' (version '2.0.0-preview-1') was successfully installed.
It was not possible to find any compatible framework version
The framework 'Microsoft.NETCore.App', version '5.0.0' (x64) was not found.
  - The following frameworks were found:
      6.0.0 at [/opt/hostedtoolcache/dotnet/shared/Microsoft.NETCore.App]

You can resolve the problem by installing the specified framework and/or SDK.

The specified framework can be found at:
  - https://aka.ms/dotnet-core-applaunch?framework=Microsoft.NETCore.App&framework_version=5.0.0&arch=x64&rid=ubuntu.20.04-x64
It was not possible to find any compatible framework version
The framework 'Microsoft.NETCore.App', version '5.0.0' (x64) was not found.
  - The following frameworks were found:
      6.0.0 at [/opt/hostedtoolcache/dotnet/shared/Microsoft.NETCore.App]

You can resolve the problem by installing the specified framework and/or SDK.

Add unit tests for GitChangesProvider

I think we need to add some unit tests for the GitChangesProvider, there is a bunch of test cases that we should be able to unit test.

How?

If we use to LibGit2Sharp to initialize a new repository in a temp directory and making a few commits we should be able to test the scenarios below.

Test cases:

  1. Given the repository contains two commits that changes a file, when getting changed files between the two commits, then the file should be marked changed
  2. Given the repository contains three commits that changes a file, when getting changed files between the first commit and the working directory, then the file should be marked changed

Depending whether or not #23 gets merged:

  1. Given the repository contains two commits that changes the version of a centrally managed NuGet package, when getting changed NuGet packages between the two commits, then the packages should be marked changed
  2. Given the repository contains two commits that changes the version of a centrally managed NuGet package, when getting changed NuGet packages between the first commit and working directory, then the packages should be marked changed

Will this cover all use cases?

Improve error handling

Currently when there's any exception (except for the NoChangesException) full stacktrace is shown to the end user.

We should throw known exceptions and using the error middleware convert them to an exit code and a view explaining what happened.

We shoould also catch infra exceptions (like git repo not found at path) and convert them to something we can understand.

Version 3.1.0 does not work on Alpine Linux

Hello,

I've noticed a regression introduced with version 3.1.0.

You can reproduce it in the following way:

  1. Clone https://github.com/bartlomiejgawel/dotnet-affected-bug
  2. Create a docker image and install version 3.0.0 by running the following command:
docker build -f Dockerfile -t dotnet-affected-3.0.0-alpine .

for the following Dockerfile file:

FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine

RUN dotnet tool install dotnet-affected --global --version 3.0.0

ENV PATH "$PATH:/root/.dotnet/tools"
  1. Create a docker image and install version 3.1.0 by running the following command:
docker build -f Dockerfile -t dotnet-affected-3.1.0-alpine .

for the following Dockerfile file:

FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine

RUN dotnet tool install dotnet-affected --global --version 3.1.0

ENV PATH "$PATH:/root/.dotnet/tools"
  1. Run the following command:
docker run --rm -v "$(pwd):/src" -w /src dotnet-affected-3.0.0-alpine /bin/sh -c "dotnet affected --from b4d7eab --to 71b0a49"

You can see that it works smoothly and creates an affected.proj file as expected.

  1. Run the following command:
docker run --rm -v "$(pwd):/src" -w /src dotnet-affected-3.1.0-alpine /bin/sh -c "dotnet affected --from b4d7eab --to 71b0a49"

You can see that it exits with status code 139.

Notice that standard dotnet SDK works correctly (also outside the container on Windows):

  1. Create a docker image and install version 3.1.0 by running the following command:
docker build -f Dockerfile -t dotnet-affected-3.1.0 .

for the following Dockerfile file:

FROM mcr.microsoft.com/dotnet/sdk:6.0

RUN dotnet tool install dotnet-affected --global --version 3.1.0

ENV PATH "$PATH:/root/.dotnet/tools"
  1. Run the following command:
docker run --rm -v "$(pwd):/src" -w /src dotnet-affected-3.1.0 /bin/sh -c "dotnet affected --from b4d7eab --to 71b0a49"

You can see that it works smoothly and creates an affected.proj file as expected.

I've checked what's changed between 3.0.0 and 3.1.0:
v3.0.0...v3.1.0

And maybe one of the updated packages caused this regression?

Add JSON formatter

We should add a JSON output formatter that outputs changed/affected projects.

This is useful for automation purposes.

Dotnet 7 partial support

When using dotnet-affected version 3.0.0-preview-4 I get error loading configuration manager but output still return that all services changed

Project is using dotnet 7

Unhandled exception: System.IO.FileLoadException: Could not load file or assembly 'System.Configuration.ConfigurationManager, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. Could not find or load a specific file. (0x80131621)
File name: 'System.Configuration.ConfigurationManager, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'
 ---> System.IO.FileLoadException: Could not load file or assembly 'System.Configuration.ConfigurationManager, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.
   at System.Runtime.Loader.AssemblyLoadContext.LoadFromPath(IntPtr ptrNativeAssemblyLoadContext, String ilPath, String niPath, ObjectHandleOnStack retAssembly)
   at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String assemblyPath)
   at System.Reflection.Assembly.LoadFrom(String assemblyFile)

Code Coverage for Affected Projects only

When testing only what's affected, the coverage report will show incorrect results.

For example, given this project structure:

  1. Project.Shared
  2. Project (.1)
  3. Project.Tests (depends on .2)
  4. Shared.Tests (depends on .1)

If .2 has changes, .3 will be affected so we will build and test .2 and .3, but there's no need to test .4 since .1 has not changed.
Hence, the coverage report will show a low coverage percentage for .1 since its test have not run

We should be able to filter down the coverage report to only include the resulting projects of dotnet-affected.

Internal MSBuild Error: ../my-solution.sln unexpectedly not a rooted path

Did anyone face similar issue? I recently upgraded from 3.1.1 to 3.2.0

Running the following command

dotnet dotnet-affected -v --format text traversal --solution-path ../my-solution.sln --output-dir ../ --from origin/feat-upgrade --to origin/develop

I now get the following error

Unhandled exception: Microsoft.Build.Framework.InternalErrorException: MSB0001: Internal MSBuild Error: ../awork-backend.sln unexpectedly not a rooted path

Any ideas or suggestions?

why the tool loos for packages.props and not Directory.Packages.props

hi!
i'm trying to run the tool on a .net7 solution and i'm getting the following error:

running dotnet affected tool from local/tech/feature to master
Unhandled exception: Microsoft.Build.Exceptions.InvalidProjectFileException: The expression "[MSBuild]::GetDirectoryNameOfFileAbove(/builds/project1, Directory.Build.targets)" cannot be evaluated. The imported project "/project1/Packages.props" was not found. Confirm that the expression in the Import declaration "/project1/Packages.props" is correct, and that the file exists on disk.  /tmp/sw-cache/nuget/global-packages/microsoft.build.centralpackageversions/2.0.79/Sdk/Sdk.targets  /usr/share/dotnet/sdk/7.0.404/Microsoft.Common.targets

how do I ensure that the tool looks uopn Directory.Packages.props ?

.NET Core 3.1 support

First of all, thanks for putting all this effort into this tool!

I was wondering if it's possible to support .NET Core 3.1 as well. I tested this locally and had some issues at first with the earlier SDK versions (3.1.100, 3.1.301) not resolving the type GraphConstructionMetrics correctly. However with latest SDK version 4.1.408 it is working fine.

I will take the liberty to open a pull request for this!

Update System.CommandLine

  • Update System.CommandLine and related to latest version
  • Remove custom DI logic from CLI. To be replaced with the BinderBase.
  • Add logging with ILogger to replace places where IConsole is being used for logging (search for TODO: Logging)

How to build/deploy monorepo with several APIs where each API has smoke test and DB migration projects

Not sure this is the best place to ask, but it is at least somewhat related to dotnet-affected, and given the helpful responses I have received so far here, I figured I'd try.

I have a monorepo with many APIs. Each API has a smoke test project and a DB migrations project. These do not have a project reference to the API project (I could add that if needed as a workaround), but they should still always be built and packaged (as separate artifacts) along with the API, so that when the API is deployed, the release pipeline can run the DB migrations and smoke tests.

Our migration to a monorepo has just been completed and there is still work left to do. Currently I am not using dotnet-affected. Each API still has a separate Azure DevOps pipeline for build (YAML) and deploy (UI). I have set up path triggers in the build pipelines so that the APIs are rebuilt for changes to files I know may influence the build. This gives many false positives, it's fairly high maintenance in the face of refactors (since project references are not picked up and have to be manually added to the path trigger list), and of course means that common libraries are restored/re-built many times (once for each pipeline).

I would like to experiment with dotnet-affected, but I'm not sure how best to accomplish what I need, which is this:

  • Build everything that has changed for each push (changed since the last successful build)
  • If an API is built, also build its smoke tests and DB migrations projects (the best way to do this might be to just add a project reference to the main API project, even though it's a hack)
  • Pack and publish the API project, DB migrations project and smoke test project as artifacts to a release pipeline (a separate pipeline for each API), and only do this for the built/changed APIs (including if there are changes only to the smoke test project or DB migrations project)

How can this best be accomplished using dotnet-affected?

Tool not working

Machine: MacOS ARM
Dotnet version: 6.0.202

i run it like:

dotnet affected --repository-path=/Users/myname/Repos/projectname --solution-path=/Users/projectname/Repos/projectname/dotnet

and like:

dotnet affected --repository-path=/Users/myname/Repos/projectname --solution-path=/Users/projectname/Repos/projectname/dotnet/projectname.sln

both are giving me errors like:

Unhandled exception: Microsoft.Build.Exceptions.InvalidProjectFileException: SDK Resolver Failure: "The SDK resolver "NuGetSdkResolver" failed while attempting to resolve the SDK "Microsoft.NET.Sdk". Exception: "System.ArgumentNullException: Value cannot be null. (Parameter 'path')
   at System.IO.Directory.GetParent(String path)

And

Unhandled exception: Microsoft.Build.Exceptions.InvalidProjectFileException: The project file could not be loaded. Access to the path '/Users/myname/Repos/projectname/dotnet' is denied.  /Users/myname/Repos/projectname/dotnet

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.