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

Fix acceptance test regressions caused by .NET6 release #157

Closed
matthewrobertson opened this issue Nov 11, 2021 · 24 comments
Closed

Fix acceptance test regressions caused by .NET6 release #157

matthewrobertson opened this issue Nov 11, 2021 · 24 comments
Labels
kind/bug Something isn't working lang/.net .NET Buildpacks

Comments

@matthewrobertson
Copy link
Member

matthewrobertson commented Nov 11, 2021

It looks like the .NET6 release broke many of our acceptance tests. I would have expected the dotnet runtime buildpack to automatically respect the version in the .csproj but it seems this is not the case. For now we pinned the GOOGLE_RUNTIME_VERSION in all the acceptance tests but we should find a way to remove this. We should also add some .NET6 specific acceptance tests.

@matthewrobertson matthewrobertson changed the title Add support for .NET6 Fix acceptance test regressions caused by .NET6 release Nov 11, 2021
@matthewrobertson
Copy link
Member Author

here is a log dump of a failed run:

    third_party/gcp_buildpacks/builders/gcp/base/acceptance/acceptance.go:210: Building application simple-dotnet-app-gcpbase-dotnet-test-afubquvohq (logs /usr/local/google/_blaze_kaylanguyen/d1578faa96be633106ec542b2619a4da/execroot/google3/blaze-out/k8-opt/testlogs/third_party/gcp_buildpacks/builders/gcp/base/acceptance/dotnet_test/test.outputs/buildpack-acceptance-logs/gcpbase-dotnet-test-afubquvohq/pack-build)
    third_party/gcp_buildpacks/builders/gcp/base/acceptance/acceptance.go:210: Error building application simple-dotnet-app-gcpbase-dotnet-test-afubquvohq: exit status 1, logs:
        Builder 'gcpbase-dotnet-test-afubquvohq' is trusted
        Selected run image 'gcr.io/buildpacks/gcp/run:v1'
        Creating builder with the following buildpacks:
        -> 'google.config.entrypoint@0.9.0'
        -> 'google.cpp.clear_source@0.1.0'
        -> 'google.cpp.functions-framework@0.1.0'
        -> 'google.go.clear_source@0.9.0'
        -> 'google.dotnet.runtime@0.9.1'
        -> 'google.dotnet.publish@0.9.0'
        -> 'google.dotnet.functions-framework@0.0.1'
        -> 'google.go.runtime@0.9.1'
        -> 'google.go.build@0.9.0'
        -> 'google.go.gopath@0.9.0'
        -> 'google.go.functions-framework@0.9.4'
        -> 'google.java.entrypoint@0.9.0'
        -> 'google.java.exploded-jar@0.9.0'
        -> 'google.java.functions-framework@1.1.0'
        -> 'google.java.gradle@0.9.0'
        -> 'google.java.maven@0.9.0'
        -> 'google.java.graalvm@0.1.0'
        -> 'google.java.native-image@0.1.0'
        -> 'google.java.runtime@0.9.1'
        -> 'google.java.clear_source@0.9.0'
        -> 'google.nodejs.runtime@0.9.2'
        -> 'google.nodejs.npm@0.9.0'
        -> 'google.nodejs.yarn@0.9.0'
        -> 'google.nodejs.functions-framework@0.9.3'
        -> 'google.python.runtime@0.9.1'
        -> 'google.python.pip@0.9.2'
        -> 'google.python.functions-framework@0.9.5'
        -> 'google.python.missing-entrypoint@0.9.0'
        -> 'google.utils.label@0.0.1'
        Provided Environment Variables
          'GOOGLE_DEBUG=true
          GOOGLE_RANDOM=jlvubqqo'
        Using build cache volume 'pack-cache-library_simple-dotnet-app-gcpbase-dotnet-test-afubquvohq_latest-068b0e703e14.build'
        Build cache 'pack-cache-library_simple-dotnet-app-gcpbase-dotnet-test-afubquvohq_latest-068b0e703e14.build' cleared
        Running the 'creator' on OS 'linux' with:
        Container Settings:
          Args: '/cnb/lifecycle/creator -daemon -launch-cache /launch-cache -log-level debug -cache-dir /cache -run-image gcr.io/buildpacks/gcp/run:v1 -skip-restore -process-type web simple-dotnet-app-gcpbase-dotnet-test-afubquvohq'
          System Envs: 'CNB_PLATFORM_API=0.4'
          Image: 'pack.local/builder/6a6f6573636c74747261:latest'
          User: 'root'
          Labels: 'map[author:pack]'
        Host Settings:
          Binds: 'pack-cache-library_simple-dotnet-app-gcpbase-dotnet-test-afubquvohq_latest-068b0e703e14.build:/cache /var/run/docker.sock:/var/run/docker.sock pack-cache-library_simple-dotnet-app-gcpbase-dotnet-test-afubquvohq_latest-068b0e703e14.launch:/launch-cache pack-layers-gjoqzkqbel:/layers pack-app-nsduxyniih:/workspace'
          Network Mode: ''
        ===> DETECTING
        ======== Output: google.dotnet.functions-framework@0.0.1 ========
        Opting out: GOOGLE_FUNCTION_TARGET not set
        ======== Output: google.dotnet.runtime@0.9.1 ========
        --------------------------------------------------------------------------------
        Running "find . -regex .*\\.\\(cs\\|fs\\|vb\\)proj"
        ./simple.csproj
        Done "find . -regex .*\\.\\(cs\\|fs\\|vb\\)proj" (13.648104ms)
        Opting in: found project files: ./simple.csproj
        ======== Output: google.dotnet.publish@0.9.0 ========
        --------------------------------------------------------------------------------
        Running "find . -regex .*\\.\\(cs\\|fs\\|vb\\)proj"
        ./simple.csproj
        Done "find . -regex .*\\.\\(cs\\|fs\\|vb\\)proj" (2.47061ms)
        Opting in: found project files: ./simple.csproj
        ======== Output: google.config.entrypoint@0.9.0 ========
        Opting out: GOOGLE_ENTRYPOINT not set and Procfile not found
        ======== Output: google.utils.label@0.0.1 ========
        Opting in: always enabled
        ======== Results ========
        skip: google.dotnet.functions-framework@0.0.1
        pass: google.dotnet.runtime@0.9.1
        pass: google.dotnet.publish@0.9.0
        skip: google.config.entrypoint@0.9.0
        pass: google.utils.label@0.0.1
        Resolving plan... (try #1)
        3 of 5 buildpacks participating
        google.dotnet.runtime 0.9.1
        google.dotnet.publish 0.9.0
        google.utils.label    0.0.1
        ===> ANALYZING
        Previous image with name "simple-dotnet-app-gcpbase-dotnet-test-afubquvohq" not found
        Skipping buildpack layer analysis
        ===> BUILDING
        ERROR: failed to build: exit status 1
        
        === .NET - Runtime (google.dotnet.runtime@0.9.1) ===
        --------------------------------------------------------------------------------
        Running "bash -c curl --fail --show-error --silent --location https://dotnetcli.blob.core.windows.net/dotnet/Sdk/LTS/latest.version | tail -n 1"
        6.0.100Done "bash -c curl --fail --show-error --silent --location https:/..." (313.092788ms)
        Using the latest LTS version of .NET Core SDK: 6.0.100
        DEBUG: ***** CACHE MISS: "sdk"
        DEBUG: ***** CACHE MISS: "runtime"
        Installing .NET SDK v6.0.100
        --------------------------------------------------------------------------------
        Running "ln --symbolic --force /layers/google.dotnet.runtime/sdk /layers/google.dotnet.runtime/runtime/sdk"
        Done "ln --symbolic --force /layers/google.dotnet.runtime/sdk /lay..." (2.196065ms)
        --------------------------------------------------------------------------------
        Running "bash -c curl --fail --show-error --silent --location --retry 3 https://dotnetcli.azureedge.net/dotnet/Sdk/6.0.100/dotnet-sdk-6.0.100-linux-x64.tar.gz | tar xz --directory /layers/google.dotnet.runtime/runtime --keep-directory-symlink --strip-components=1"
        Done "bash -c curl --fail --show-error --silent --location --retry..." (3.369308251s)
        === .NET - Publish (google.dotnet.publish@0.9.0) ===
        --------------------------------------------------------------------------------
        Running "find . -regex .*\\.\\(cs\\|fs\\|vb\\)proj"
        ./simple.csproj
        Done "find . -regex .*\\.\\(cs\\|fs\\|vb\\)proj" (2.168742ms)
        Installing application dependencies.
        --------------------------------------------------------------------------------
        Running "find . -regex .*\\.\\(cs\\|fs\\|vb\\)proj"
        ./simple.csproj
        Done "find . -regex .*\\.\\(cs\\|fs\\|vb\\)proj" (1.487268ms)
        --------------------------------------------------------------------------------
        Running "dotnet --version"
        6.0.100
        Done "dotnet --version" (293.313367ms)
        DEBUG: Current dependency hash: "07a29b7f2f8d90c2518157bd1d0ddca2e320d97cea2f7edba4531b86b3ef2461"
        DEBUG:   Cache dependency hash: ""
        DEBUG: No metadata found from a previous build, skipping cache.
        DEBUG: ***** CACHE MISS: "prod dependencies"
        --------------------------------------------------------------------------------
        Running "dotnet restore --packages /layers/google.dotnet.publish/packages ./simple.csproj (DOTNET_CLI_TELEMETRY_OPTOUT=true)"
        
        Welcome to .NET 6.0!
        ---------------------
        SDK Version: 6.0.100
        
        ----------------
        Installed an ASP.NET Core HTTPS development certificate.
        To trust the certificate run 'dotnet dev-certs https --trust' (Windows and macOS only).
        Learn about HTTPS: https://aka.ms/dotnet-https
        ----------------
        Write your first app: https://aka.ms/dotnet-hello-world
        Find out what's new: https://aka.ms/dotnet-whats-new
        Explore documentation: https://aka.ms/dotnet-docs
        Report issues and find source on GitHub: https://github.com/dotnet/core
        Use 'dotnet --help' to see available commands or visit: https://aka.ms/dotnet-cli
        --------------------------------------------------------------------------------------
        /workspace/simple.csproj : error MSB4242: SDK Resolver Failure: "The SDK resolver "Microsoft.DotNet.MSBuildWorkloadSdkResolver" failed while attempting to resolve the SDK "Microsoft.NET.Sdk.Web". Exception: "System.IO.DirectoryNotFoundException: Could not find a part of the path '/layers/google.dotnet.runtime/sdk-manifests'.
        /workspace/simple.csproj : error MSB4242:    at System.IO.Enumeration.FileSystemEnumerator`1.CreateDirectoryHandle(String path, Boolean ignoreNotFound)
        /workspace/simple.csproj : error MSB4242:    at System.IO.Enumeration.FileSystemEnumerator`1.Init()
        /workspace/simple.csproj : error MSB4242:    at System.IO.Enumeration.FileSystemEnumerator`1..ctor(String directory, Boolean isNormalized, EnumerationOptions options)
        /workspace/simple.csproj : error MSB4242:    at System.IO.Enumeration.FileSystemEnumerable`1..ctor(String directory, FindTransform transform, EnumerationOptions options, Boolean isNormalized)
        /workspace/simple.csproj : error MSB4242:    at System.IO.Enumeration.FileSystemEnumerableFactory.UserDirectories(String directory, String expression, EnumerationOptions options)
        /workspace/simple.csproj : error MSB4242:    at System.IO.Directory.InternalEnumeratePaths(String path, String searchPattern, SearchTarget searchTarget, EnumerationOptions options)
        /workspace/simple.csproj : error MSB4242:    at System.IO.Directory.GetDirectories(String path, String searchPattern, EnumerationOptions enumerationOptions)
        /workspace/simple.csproj : error MSB4242:    at System.IO.Directory.GetDirectories(String path)
        /workspace/simple.csproj : error MSB4242:    at Microsoft.NET.Sdk.WorkloadManifestReader.SdkDirectoryWorkloadManifestProvider.FallbackForMissingManifest(String manifestId)
        /workspace/simple.csproj : error MSB4242:    at Microsoft.NET.Sdk.WorkloadManifestReader.SdkDirectoryWorkloadManifestProvider.GetManifestDirectories()
        /workspace/simple.csproj : error MSB4242:    at Microsoft.NET.Sdk.WorkloadManifestReader.SdkDirectoryWorkloadManifestProvider.GetManifests()+MoveNext()
        /workspace/simple.csproj : error MSB4242:    at Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver.LoadManifestsFromProvider(IWorkloadManifestProvider manifestProvider)
        /workspace/simple.csproj : error MSB4242:    at Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver.Create(IWorkloadManifestProvider manifestProvider, String dotnetRootPath, String sdkVersion, String userProfileDir)
        /workspace/simple.csproj : error MSB4242:    at Microsoft.NET.Sdk.WorkloadMSBuildSdkResolver.CachingWorkloadResolver.Resolve(String sdkReferenceName, String dotnetRootPath, String sdkVersion, String userProfileDir)
        /workspace/simple.csproj : error MSB4242:    at Microsoft.NET.Sdk.WorkloadMSBuildSdkResolver.WorkloadSdkResolver.Resolve(SdkReference sdkReference, SdkResolverContext resolverContext, SdkResultFactory factory)
        /workspace/simple.csproj : error MSB4242:    at Microsoft.Build.BackEnd.SdkResolution.SdkResolverService.ResolveSdk(Int32 submissionId, SdkReference sdk, LoggingContext loggingContext, ElementLocation sdkReferenceLocation, String solutionPath, String projectPath, Boolean interactive, Boolean isRunningInVisualStudio)""
        Done "dotnet restore --packages /layers/google.dotnet.publish/pack..." (603.264469ms)
        Failure: (ID: ee233542) ..."Microsoft.NET.Sdk.Web". Exception: "System.IO.DirectoryNotFoundException: Could not find a part of the path '/layers/google.dotnet.runtime/sdk-manifests'.
        /workspace/simple.csproj : error MSB4242:    at System.IO.Enumeration.FileSystemEnumerator`1.CreateDirectoryHandle(String path, Boolean ignoreNotFound)
        /workspace/simple.csproj : error MSB4242:    at System.IO.Enumeration.FileSystemEnumerator`1.Init()
        /workspace/simple.csproj : error MSB4242:    at System.IO.Enumeration.FileSystemEnumerator`1..ctor(String directory, Boolean isNormalized, EnumerationOptions options)
        /workspace/simple.csproj : error MSB4242:    at System.IO.Enumeration.FileSystemEnumerable`1..ctor(String directory, FindTransform transform, EnumerationOptions options, Boolean isNormalized)
        /workspace/simple.csproj : error MSB4242:    at System.IO.Enumeration.FileSystemEnumerableFactory.UserDirectories(String directory, String expression, EnumerationOptions options)
        /workspace/simple.csproj : error MSB4242:    at System.IO.Directory.InternalEnumeratePaths(String path, String searchPattern, SearchTarget searchTarget, EnumerationOptions options)
        /workspace/simple.csproj : error MSB4242:    at System.IO.Directory.GetDirectories(String path, String searchPattern, EnumerationOptions enumerationOptions)
        /workspace/simple.csproj : error MSB4242:    at System.IO.Directory.GetDirectories(String path)
        /workspace/simple.csproj : error MSB4242:    at Microsoft.NET.Sdk.WorkloadManifestReader.SdkDirectoryWorkloadManifestProvider.FallbackForMissingManifest(String manifestId)
        /workspace/simple.csproj : error MSB4242:    at Microsoft.NET.Sdk.WorkloadManifestReader.SdkDirectoryWorkloadManifestProvider.GetManifestDirectories()
        /workspace/simple.csproj : error MSB4242:    at Microsoft.NET.Sdk.WorkloadManifestReader.SdkDirectoryWorkloadManifestProvider.GetManifests()+MoveNext()
        /workspace/simple.csproj : error MSB4242:    at Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver.LoadManifestsFromProvider(IWorkloadManifestProvider manifestProvider)
        /workspace/simple.csproj : error MSB4242:    at Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver.Create(IWorkloadManifestProvider manifestProvider, String dotnetRootPath, String sdkVersion, String userProfileDir)
        /workspace/simple.csproj : error MSB4242:    at Microsoft.NET.Sdk.WorkloadMSBuildSdkResolver.CachingWorkloadResolver.Resolve(String sdkReferenceName, String dotnetRootPath, String sdkVersion, String userProfileDir)
        /workspace/simple.csproj : error MSB4242:    at Microsoft.NET.Sdk.WorkloadMSBuildSdkResolver.WorkloadSdkResolver.Resolve(SdkReference sdkReference, SdkResolverContext resolverContext, SdkResultFactory factory)
        /workspace/simple.csproj : error MSB4242:    at Microsoft.Build.BackEnd.SdkResolution.SdkResolverService.ResolveSdk(Int32 submissionId, SdkReference sdk, LoggingContext loggingContext, ElementLocation sdkReferenceLocation, String solutionPath, String projectPath, Boolean interactive, Boolean isRunningInVisualStudio)""
        --------------------------------------------------------------------------------
        Sorry your project couldn't be built.
        Our documentation explains ways to configure Buildpacks to better recognise your project:
         -> https://github.com/GoogleCloudPlatform/buildpacks/blob/main/README.md
        If you think you've found an issue, please report it:
         -> https://github.com/GoogleCloudPlatform/buildpacks/issues/new
        --------------------------------------------------------------------------------
        ERROR: failed to build: executing lifecycle: failed with status code: 145

@matthewrobertson
Copy link
Member Author

To me it looks like we are automatically installing the latest .NET SDK (Version: 6.0.100). But this isn't compatible with the TargetFramework that the sample apps have declared in their csproj:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

</Project>

My naive idea is that we should update the runtime buildpack to parse the TargetFramework from the csproj and use it to determine which version of .NET should get installed at build time. @jskeet would know better than me though

@jskeet
Copy link
Member

jskeet commented Nov 12, 2021

There are two issues here, I think:

  • Making sure we've got the right SDK available to build the app
  • Making sure we've got the right runtime available to deploy the app

The first point is relatively straightward to support, I suspect: we can install both .NET 6.0 and .NET Core 3.1 SDKs side-by-side, which should allow us to build either. I'm assuming it doesn't matter too much if the Docker image we use when building is larger than it really needs to be.
(If we don't end up using a single Docker image but installing the SDK each time, then presumably installing both would end up being significantly slower, in which case Matthew's idea of parsing the TargetFramework does indeed sound necessary.)

The second point is trickier, as we don't want to deploy an image that is larger than it needs to be. We may not need to parse the TargetFramework from the csproj file though - we may find that after publishing, there's sufficient information in the output JSON files (that live alongside the binaries) to give us the information we need. That has an advantage over parsing csproj files, in that project files could do all kinds of complex tricks that we'd either have to not support or do significant work in order to replicate msbuild logic. The output JSON file should be a lot simpler to handle - but we'll need to investigate what we end up with in each case.

@matthewrobertson
Copy link
Member Author

@jskeet in this case the tests that started failing were for the GCP Buildpacks, which install all tools, SDKs etc at build time. It looks like our current logic for determining which .NET SDK we should install is:

  1. Use the version specified in the GOOGLE_RUNTIME_VERSION env var
  2. Use the Sdk.Version specified in global.json
  3. Use the latest version available as determined by calling https://dotnetcli.blob.core.windows.net/dotnet/Sdk/LTS/latest.version

I am wondering if we can be a bit smarter in step#3. I guess what would need is for Microsoft to expose an API that allows us to ask for "the latest SDK version compatible with this target framework". Maybe they already do and we just need to figure out how to construct the proper URL.

@spew
Copy link
Contributor

spew commented Nov 16, 2021

Ahh nice, that makes sense.

@briandealwis briandealwis added lang/.net .NET Buildpacks kind/bug Something isn't working labels Nov 22, 2021
@jjdelorme
Copy link

Trying to use the build pack with a .NET 6.0 application now fails as well. It was working with preview7, but I'm getting the same error above, even when explicitly specifying --env=GOOGLE_RUNTIME_VERSION=6.0.100. This was working a couple of months ago.

@spew
Copy link
Contributor

spew commented Nov 26, 2021

Hi @jjdelorme, thanks for reporting your issue. I have a fix for this and it will likely be available late next week.

@jjdelorme
Copy link

Hi @spew, any updates on this? Thank you!

@spew
Copy link
Contributor

spew commented Dec 14, 2021

Hello @jjdelorme thanks for asking. I'm behind on this one but should have a fix out by end of year.

@meteatamel
Copy link

Hi @spew, is there an update on supporting .NET 6 in buildpacks?

@spew
Copy link
Contributor

spew commented Jan 20, 2022

Hi @meteatamel I have submitted 1 out of 3 commits remaining to get .NET6 working, I am hoping to get them all in by next week (they are all complete).

You can take a look at the first commit here: dac47e0

@spew
Copy link
Contributor

spew commented Feb 2, 2022

Just got another commit in: 3ea8b29

There is one more coming and then .NET 6 should work.

@meteatamel
Copy link

Thanks for the update. I'll be the first one to try! :-)

@jjdelorme
Copy link

jjdelorme commented Feb 3, 2022 via email

@EatonZ
Copy link

EatonZ commented Feb 3, 2022

Me 3 🤩

@spew
Copy link
Contributor

spew commented Feb 3, 2022

This should be fixed, I just built a sample .NET 6.0 application with the following:

pack build sample-dotnet --builder gcr.io/buildpacks/builder

@spew
Copy link
Contributor

spew commented Feb 3, 2022

Please do let me know of any issues.

@EatonZ
Copy link

EatonZ commented Feb 3, 2022

@spew With your changes, it is not necessary to specify GOOGLE_RUNTIME_VERSION for .NET 6? When the non-LTS .NET 7 comes out this fall, what will happen then?

@spew
Copy link
Contributor

spew commented Feb 3, 2022

It is not necessary to specify GOOGLE_RUNTIME_VERSION. The .NET buildpack will look at your csproj / runtimeconfig.json and figure out the right SDK & runtime to use based on the value for TargetFramework.

When .NET 7 comes out, assuming nothing changes about the download URLs / untarring, and the TargetFramework name in the csproj is net7.0, then .NET 7 will JustWork.

@jjdelorme
Copy link

Just confirming it worked for .NET 6! Thank you!

@EatonZ
Copy link

EatonZ commented Feb 3, 2022

Thanks for your work, @spew. I can also confirm it works.

The .NET buildpack will look at your csproj / runtimeconfig.json and figure out the right SDK & runtime to use based on the value for TargetFramework.

If that is the case, you have essentially solved #89 as well. I'll go ahead and close that issue.

@spew
Copy link
Contributor

spew commented Feb 3, 2022

Thanks, glad to hear that it works for all of you as well!

@spew spew closed this as completed Feb 3, 2022
@meteatamel
Copy link

Whoo! Thanks for the fix, works great for .NET 5 and 6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Something isn't working lang/.net .NET Buildpacks
Projects
None yet
Development

No branches or pull requests

7 participants