Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements an intermediate build cache #305

Merged
merged 6 commits into from
Apr 25, 2022

Conversation

ForestEckhardt
Copy link
Contributor

Resolves #279
Resolves #94

Checklist

  • I have viewed, signed, and submitted the Contributor License Agreement.
  • I have linked issue(s) that this PR should close using keywords or the Github UI (See docs)
  • I have added an integration test, if necessary.
  • I have reviewed the styleguide for guidance on my code quality.
  • I'm happy with the commit history on this PR (I have rebased/squashed as needed).

@fg-j
Copy link

fg-j commented Apr 13, 2022

I experimented with this by attempting to build Blogifier, a meaty .NET project.

I used old versions of the runtime, SDK, and ASP.NET buildpack because this app is impacted by paketo-buildpacks/dotnet-core#670.

I built this buildpack locally and used the following build command:

pack build blog --env BP_DOTNET_PROJECT_PATH="./Blogifier"  \
--env BP_DOTNET_PUBLISH_FLAGS="--verbosity=detailed --self-contained=true" \
--path ./src \
-b paketo-buildpacks/[email protected] \
-b paketo-buildpacks/[email protected] \
-b paketo-buildpacks/[email protected] \
-b paketo-buildpacks/icu \
-b $buildpack_directory/build/buildpackage.cnb \
-b paketo-buildpacks/dotnet-execute \
--verbose

The build fails with the following error:

Build FAILED.
[builder]
[builder]              "/workspace/Blogifier/Blogifier.csproj" (Publish target) (1:7) ->
[builder]              "/workspace/Blogifier.Admin/Blogifier.Admin.csproj" (default target) (2:6) ->
[builder]              (ResolvePackageAssets target) ->
[builder]                /layers/paketo-buildpacks_dotnet-core-sdk/dotnet-core-sdk/sdk/6.0.102/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(267,5): error NETSDK1047: Assets file '/layers/paketo-buildpacks_dotnet-publish/intermediate-build-cache/project.assets.json' doesn't have a target for 'net6.0/browser-wasm'. Ensure that restore has run and that you have included 'net6.0' in the TargetFrameworks for your project. You may also need to include 'browser-wasm' in your project's RuntimeIdentifiers. [/workspace/Blogifier.Admin/Blogifier.Admin.csproj]
[builder]
[builder]
[builder]              "/workspace/Blogifier/Blogifier.csproj" (Publish target) (1:7) ->
[builder]              "/workspace/Blogifier.Core/Blogifier.Core.csproj" (default target) (3:6) ->
[builder]              (CoreCompile target) ->
[builder]                /workspace/Blogifier.Core/Data/AppDbContext.cs(2,17): error CS0234: The type or namespace name 'EntityFrameworkCore' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/Migrations/20210404234633_Init.cs(2,17): error CS0234: The type or namespace name 'EntityFrameworkCore' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/Migrations/20210404234633_Init.Designer.cs(4,17): error CS0234: The type or namespace name 'EntityFrameworkCore' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/Migrations/20210404234633_Init.Designer.cs(5,17): error CS0234: The type or namespace name 'EntityFrameworkCore' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/Migrations/20210404234633_Init.Designer.cs(6,17): error CS0234: The type or namespace name 'EntityFrameworkCore' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/Migrations/20210404234633_Init.Designer.cs(7,17): error CS0234: The type or namespace name 'EntityFrameworkCore' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/Migrations/AppDbContextModelSnapshot.cs(4,17): error CS0234: The type or namespace name 'EntityFrameworkCore' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/Migrations/AppDbContextModelSnapshot.cs(5,17): error CS0234: The type or namespace name 'EntityFrameworkCore' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/Migrations/AppDbContextModelSnapshot.cs(6,17): error CS0234: The type or namespace name 'EntityFrameworkCore' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Extensions/ServiceCollectionExtensions.cs(3,17): error CS0234: The type or namespace name 'EntityFrameworkCore' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Extensions/ServiceCollectionExtensions.cs(4,28): error CS0234: The type or namespace name 'Configuration' does not exist in the namespace 'Microsoft.Extensions' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Extensions/ServiceCollectionExtensions.cs(6,7): error CS0246: The type or namespace name 'Pomelo' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Extensions/StringExtensions.cs(1,17): error CS0234: The type or namespace name 'AspNetCore' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Extensions/StringExtensions.cs(7,7): error CS0246: The type or namespace name 'Markdig' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/AnalyticsProvider.cs(3,17): error CS0234: The type or namespace name 'EntityFrameworkCore' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/AuthorProvider.cs(4,17): error CS0234: The type or namespace name 'EntityFrameworkCore' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/AuthorProvider.cs(5,28): error CS0234: The type or namespace name 'Configuration' does not exist in the namespace 'Microsoft.Extensions' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/BlogProvider.cs(3,17): error CS0234: The type or namespace name 'EntityFrameworkCore' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/CategoryProvider.cs(3,17): error CS0234: The type or namespace name 'EntityFrameworkCore' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/EmailProvider.cs(2,7): error CS0246: The type or namespace name 'MailKit' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/EmailProvider.cs(3,7): error CS0246: The type or namespace name 'MailKit' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/EmailProvider.cs(4,7): error CS0246: The type or namespace name 'MimeKit' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/FeedProvider.cs(2,17): error CS0234: The type or namespace name 'SyndicationFeed' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/FeedProvider.cs(3,17): error CS0234: The type or namespace name 'SyndicationFeed' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/NewsletterProvider.cs(4,17): error CS0234: The type or namespace name 'EntityFrameworkCore' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/PostProvider.cs(5,17): error CS0234: The type or namespace name 'EntityFrameworkCore' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/PostProvider.cs(6,28): error CS0234: The type or namespace name 'Configuration' does not exist in the namespace 'Microsoft.Extensions' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/StorageProvider.cs(3,17): error CS0234: The type or namespace name 'AspNetCore' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/SyndicationProvider.cs(4,17): error CS0234: The type or namespace name 'EntityFrameworkCore' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/Migrations/20210404234633_Init.cs(6,33): error CS0246: The type or namespace name 'Migration' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Extensions/ServiceCollectionExtensions.cs(13,90): error CS0246: The type or namespace name 'IConfiguration' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/Migrations/20210404234633_Init.Designer.cs(11,6): error CS0246: The type or namespace name 'DbContextAttribute' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/Migrations/20210404234633_Init.Designer.cs(11,6): error CS0246: The type or namespace name 'DbContext' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/Migrations/20210404234633_Init.Designer.cs(12,6): error CS0246: The type or namespace name 'MigrationAttribute' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/Migrations/20210404234633_Init.Designer.cs(12,6): error CS0246: The type or namespace name 'Migration' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/Migrations/AppDbContextModelSnapshot.cs(11,47): error CS0246: The type or namespace name 'ModelSnapshot' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/Migrations/20210404234633_Init.cs(8,36): error CS0246: The type or namespace name 'MigrationBuilder' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/Migrations/20210404234633_Init.cs(253,38): error CS0246: The type or namespace name 'MigrationBuilder' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/Migrations/AppDbContextModelSnapshot.cs(10,6): error CS0246: The type or namespace name 'DbContextAttribute' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/Migrations/AppDbContextModelSnapshot.cs(10,6): error CS0246: The type or namespace name 'DbContext' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/Migrations/20210404234633_Init.Designer.cs(15,50): error CS0246: The type or namespace name 'ModelBuilder' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/Migrations/AppDbContextModelSnapshot.cs(13,44): error CS0246: The type or namespace name 'ModelBuilder' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/AppDbContext.cs(6,33): error CS0246: The type or namespace name 'DbContext' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/FeedProvider.cs(12,24): error CS0246: The type or namespace name 'AtomEntry' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/AppDbContext.cs(16,16): error CS0246: The type or namespace name 'DbSet<>' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/AppDbContext.cs(17,16): error CS0246: The type or namespace name 'DbSet<>' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/FeedProvider.cs(24,37): error CS0246: The type or namespace name 'AtomEntry' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/AppDbContext.cs(18,16): error CS0246: The type or namespace name 'DbSet<>' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/AppDbContext.cs(19,16): error CS0246: The type or namespace name 'DbSet<>' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/AppDbContext.cs(20,16): error CS0246: The type or namespace name 'DbSet<>' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/AppDbContext.cs(21,16): error CS0246: The type or namespace name 'DbSet<>' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/AppDbContext.cs(22,16): error CS0246: The type or namespace name 'DbSet<>' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/AuthorProvider.cs(30,42): error CS0246: The type or namespace name 'IConfiguration' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/AppDbContext.cs(23,16): error CS0246: The type or namespace name 'DbSet<>' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/AppDbContext.cs(25,49): error CS0246: The type or namespace name 'ModelBuilder' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/AppDbContext.cs(8,28): error CS0246: The type or namespace name 'DbContextOptions<>' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Data/AppDbContext.cs(10,29): error CS0246: The type or namespace name 'DbContextOptions<>' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/EmailProvider.cs(51,15): error CS0246: The type or namespace name 'SmtpClient' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/SyndicationProvider.cs(97,28): error CS1069: The type name 'SyndicationItem' could not be found in the namespace 'System.ServiceModel.Syndication'. This type has been forwarded to assembly 'System.ServiceModel.Syndication, Version=0.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' Consider adding a reference to that assembly. [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/PostProvider.cs(38,26): error CS0246: The type or namespace name 'IConfiguration' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/PostProvider.cs(40,82): error CS0246: The type or namespace name 'IConfiguration' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/StorageProvider.cs(18,29): error CS0246: The type or namespace name 'IFormFile' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]                /workspace/Blogifier.Core/Providers/StorageProvider.cs(100,42): error CS0246: The type or namespace name 'IFormFile' could not be found (are you missing a using directive or an assembly reference?) [/workspace/Blogifier.Core/Blogifier.Core.csproj]
[builder]
[builder]           0 Warning(s)
[builder]           64 Error(s)
[builder]
[builder]       Time Elapsed 00:00:10.40
[builder] failed to execute 'dotnet publish': exit status 1
[builder]       Failed after 10.764077s

@ForestEckhardt
Copy link
Contributor Author

ForestEckhardt commented Apr 18, 2022

There is an underlying issue that causes this to happen https://stackoverflow.com/questions/45575280/msbuild-nuget-restoreoutputpath-how-to-make-it-work. I am not entirely sure what to do about this issue at the exact moment but I will keep looking. It may be as simple as setting the MSBuildProjectExtensionsPath to the same value.

See also this issue thread dotnet/msbuild#1603.

@fg-j
Copy link

fg-j commented Apr 18, 2022

If/when we get this working, I think it'll be important to make sure we have an integration test fixture that fails without the fix and passes with the right incantation (I suspect this comes down to having NuGet packages). @ForestEckhardt the issues you linked make this seem hacky/subject to change, so I'd like to be sure we catch if they change something under the hood that breaks this.

@ForestEckhardt
Copy link
Contributor Author

ForestEckhardt commented Apr 18, 2022

@fg-j I did a little bit of looking and it seems that that the approved way to do this is through a Directory.Build.props file in the app source. This allows you to set the BaseIntermediateOutputPath in way that is respected both by Nuget and the SDK, although I am still trying to verify this interaction.

@ForestEckhardt
Copy link
Contributor Author

Update: It took some doing but I am now using a Directory.Build.props file to point to an intermediate build cache. After disabling Nuget caching to ensure that the change was working. I have seen an improvement of ~4-5 seconds in rebuild speed for the Blogifier app with log lines indicating that files are being copies out of the cache into the app output. With the Nuget cache enabled I am seeing an improvement of ~11 seconds in build speed alone which does not include the time saved by not having to redownload the SDK and runtimes.

I will update this PR to use this new configuration.

@fg-j fg-j self-assigned this Apr 18, 2022
@fg-j
Copy link

fg-j commented Apr 18, 2022

@ForestEckhardt I was able to repro your success with Blogifier. Then I took this for a spin with a Steeltoe sample app and unfortunately I saw something else go weird.

Building this microservice
with a version of the .NET Core buildpack that includes this dotnet-publish buildpack:

pack build store-ui -b $buildpack_path/build/buildpackage.cnb --env BP_DOTNET_PUBLISH_FLAGS="--verbosity=detailed"

results in an error:

[builder]              (CoreCompile target) ->
[builder]                /workspace/Program.cs(31,18): error CS1061: 'IHostBuilder' does not contain a definition for 'AddAllActuators' and no accessible extension method 'AddAllActuators' accepting a first argument of type 'IHostBuilder' could be found (are you missing a using directive or an assembly reference?) [/workspace/MusicStoreService.csproj]
[builder]                CSC : error CS1705: Assembly 'Microsoft.EntityFrameworkCore.Relational' with identity 'Microsoft.EntityFrameworkCore.Relational, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' uses 'Microsoft.EntityFrameworkCore, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' which has a higher version than referenced assembly 'Microsoft.EntityFrameworkCore' with identity 'Microsoft.EntityFrameworkCore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' [/workspace/MusicStoreService.csproj]
[builder]                CSC : error CS1705: Assembly 'Steeltoe.Connector.EFCore' with identity 'Steeltoe.Connector.EFCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null' uses 'Microsoft.EntityFrameworkCore, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' which has a higher version than referenced assembly 'Microsoft.EntityFrameworkCore' with identity 'Microsoft.EntityFrameworkCore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' [/workspace/MusicStoreService.csproj]
[builder]                /workspace/Startup.cs(29,22): error CS7036: There is no argument given that corresponds to the required formal parameter 'config' of 'TracingServiceCollectionExtensions.AddDistributedTracing(IServiceCollection, IConfiguration)' [/workspace/MusicStoreService.csproj]

whereas building with the latest version of the language family succeeds:

pack build store-ui -b gcr.io/paketo-buildpacks/dotnet-core  --env BP_DOTNET_PUBLISH_FLAGS="--verbosity=detailed"

I'm going to dig a bit for the cause.

Edit: I've done some digging but I can't find anything in the Microsoft docs that link the errors seen above and use of the BaseIntermediateOutputPath directory. Here's some information I have managed to gather:

  • error CS1705
  • error CS7036 - The various StackOverflow discussions I've found about this error point to incorrectly-written code (e.g. missing definition of a default constructor). This doesn't seem applicable in this case, since the source code is unchanged between the working and broken cases. It's a bit of a head-scratcher. Maybe the intermediate path doesn't contain all of the necessary *.dlls somehow (resulting in compilation errors about incompletely defined classes)? Truly bizarre.

@fg-j
Copy link

fg-j commented Apr 20, 2022

In the latest commit, I've switched our approach to simply copying the whole obj directory into the cache layer and then copying it back into the project working directory at rebuild time. This is clearly hackier, but apparently less prone to the errors that cropped up when setting the BaseIntermediateOutputPath at build time. This approach seems to improve rebuild speed and works for the Steeltoe sample apps and the Blogifier example.

The tradeoff here is that copying the files around slows things down, but I think this is negligible in the context of a substantial .NET build.

@sophiewigmore
Copy link
Member

@ForestEckhardt @fg-j the changes look great, and make sense. Per Frankie's comment:

If/when we get this working, I think it'll be important to make sure we have an integration test fixture that fails without the fix and passes with the right incantation (I suspect this comes down to having NuGet packages). @ForestEckhardt the issues you linked make this seem hacky/subject to change, so I'd like to be sure we catch if they change something under the hood that breaks this.

Can one of y'all add this?

@ForestEckhardt
Copy link
Contributor Author

@sophiewigmore I think that I came to the conclusion to the underlying issue is very opaque and I don't think that this is going to change soon in the future so I am not sure and additional integration test will tell us much.

@ForestEckhardt ForestEckhardt added the semver:patch A change requiring a patch version bump label Apr 21, 2022
@fg-j
Copy link

fg-j commented Apr 21, 2022

@ForestEckhardt I think it's worth adding an integration test that tests rebuilding to make sure the build cache is being loaded correctly

I can add one.

Edit: @ForestEckhardt , @sophiewigmore I've added an integration test for rebuilds. I've also added more unit test coverage to the cache loading and storing process that helps illuminate why some of the filesystem operations (especially os.RemoveAll() and os.MkdirAll()) are necessary. Ideally, deleting any of those operations will now break an explanatory unit test.

Comment on lines +65 to +97
for i := 0; i < 2; i++ {
var logs fmt.Stringer
image, logs, err = pack.WithNoColor().Build.
WithBuildpacks(
icuBuildpack,
dotnetCoreRuntimeBuildpack,
dotnetCoreAspNetBuildpack,
dotnetCoreSDKBuildpack,
buildpack,
dotnetExecuteBuildpack,
).
WithEnv(map[string]string{
"BP_DOTNET_PUBLISH_FLAGS": "--verbosity=normal",
}).
Execute(name, source)
Expect(err).NotTo(HaveOccurred(), logs.String())
images[image.ID] = ""

Expect(logs).To(ContainLines(
MatchRegexp(` Running 'dotnet publish .* --verbosity=normal'`),
))

container, err = docker.Container.Run.
WithEnv(map[string]string{"PORT": "8080"}).
WithPublish("8080").
WithPublishAll().
Execute(image.ID)
Expect(err).NotTo(HaveOccurred())
containers[container.ID] = ""

Eventually(container).Should(BeAvailable())
Eventually(container).Should(Serve(ContainSubstring("source_6_app")).OnPort(8080))
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fg-j it's not super clear to me from this test how to tell that the cache is being reused on the rebuild. Am I missing something?

Copy link

@fg-j fg-j Apr 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the idea here is to test that loading the cache when it's non-empty and running dotnet publish works as expected. Since the intermediate build layer is always marked cache and we always try to load the cache before building, building and then rebuilding tests that a) the cache is saved correctly after the first build and b) the cache is useable during the second build. Analogous to this rebuild test in the go-build buildpack.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok, the success of the build is enough to know that the cache is used by nature of the code.

I think I was expecting to see an assertion around the cache layer SHA, but I realize we can't do that because it's only a cache layer, not launch.

@sophiewigmore sophiewigmore merged commit 2e057bb into main Apr 25, 2022
@sophiewigmore sophiewigmore deleted the implment-incremental-build-cache branch April 25, 2022 15:57
fg-j pushed a commit that referenced this pull request May 6, 2022
This reverts commit 2e057bb.
Due to rebuild bug
@fg-j fg-j mentioned this pull request May 6, 2022
5 tasks
sophiewigmore pushed a commit that referenced this pull request May 6, 2022
* add test that ensures source code change is reflected in recompiled app

* Revert "Implements an intermediate build cache (#305)"

This reverts commit 2e057bb.
Due to rebuild bug
fg-j pushed a commit that referenced this pull request May 6, 2022
* add test that ensures source code change is reflected in recompiled app

* Revert "Implements an intermediate build cache (#305)"

This reverts commit 2e057bb.
Due to rebuild bug
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver:patch A change requiring a patch version bump
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Reuse incremental compilation data Layer reuse between builds
3 participants