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

Update to ASP.NET Core 3.0 #444

Merged
merged 19 commits into from
Jan 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .azure/pipelines/ci-official.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ jobs:
pool:
vmImage: vs2017-win2016
steps:
- task: DotNetCoreInstaller@0
displayName: 'Use .NET Core SDK 2.2.100'
- task: UseDotNet@2
displayName: 'Use .NET Core SDK 3.0.X'
inputs:
version: 2.2.100
version: 3.0.x

- task: Npm@1
displayName: Install frontend dependencies
Expand Down
2 changes: 2 additions & 0 deletions BaGet.sln
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0B44364D-952B-497A-82E0-C9AAE94E0369}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
src\Directory.Build.props = src\Directory.Build.props
nuget.config = nuget.config
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BaGet.Core.Server", "src\BaGet.Core.Server\BaGet.Core.Server.csproj", "{D68B56AC-98DD-4DA7-B4F8-1243538A8A5C}"
Expand Down
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 80

FROM microsoft/dotnet:2.2-sdk AS build
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
RUN apt-get install -y nodejs
WORKDIR /src
COPY /src .
Expand Down
7 changes: 7 additions & 0 deletions nuget.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>
2 changes: 1 addition & 1 deletion samples/BaGet.Protocol.Samples.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>

<IsPackable>false</IsPackable>
<NoWarn>IDE0007</NoWarn>
Expand Down
2 changes: 1 addition & 1 deletion src/BaGet.Aws/BaGet.Aws.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
<TargetFrameworks>netcoreapp3.0</TargetFrameworks>
Copy link
Owner Author

Choose a reason for hiding this comment

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

⚠️ This project will temporarily require .NET Core 3 as EF Core 3.0 requires .NET Standard 2.1. EF Core 3.1 reintroduced .NET Standard 2.0 support. I will re-add .NET Framework and .NET Standard 2.0 support once I've migrated BaGet to ASP.NET Core 3.1.


<PackageTags>NuGet;Amazon;Cloud</PackageTags>
<Description>The libraries to host BaGet on AWS.</Description>
Expand Down
2 changes: 1 addition & 1 deletion src/BaGet.Azure/BaGet.Azure.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
<TargetFrameworks>netcoreapp3.0</TargetFrameworks>
Copy link
Owner Author

Choose a reason for hiding this comment

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

⚠️ This project will temporarily require .NET Core 3 as EF Core 3.0 requires .NET Standard 2.1. EF Core 3.1 reintroduced .NET Standard 2.0 support. I will re-add .NET Framework and .NET Standard 2.0 support once I've migrated BaGet to ASP.NET Core 3.1.


<PackageTags>NuGet;Azure;Cloud</PackageTags>
<Description>The libraries to host BaGet on Azure.</Description>
Expand Down
11 changes: 7 additions & 4 deletions src/BaGet.Core.Server/BaGet.Core.Server.csproj
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
<TargetFrameworks>netcoreapp3.0</TargetFrameworks>

<Description>BaGet's NuGet server implementation</Description>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.HttpOverrides" version="$(MicrosoftAspNetCorePackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" version="$(MicrosoftAspNetCorePackageVersion)" />
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="$(MicrosoftAspNetCorePackageVersion)" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,119 +4,109 @@

namespace BaGet.Extensions
{
public static class IRouteBuilderExtensions
public static class IEndpointRouteBuilderExtensions
{
public static IRouteBuilder MapServiceIndexRoutes(this IRouteBuilder routes)
public static void MapServiceIndexRoutes(this IEndpointRouteBuilder endpoints)
{
return routes.MapRoute(
endpoints.MapControllerRoute(
name: Routes.IndexRouteName,
template: "v3/index.json",
defaults: new { controller = "ServiceIndex", action = "GetAsync" });
pattern: "v3/index.json",
defaults: new { controller = "ServiceIndex", action = "Get" });
}

public static IRouteBuilder MapPackagePublishRoutes(this IRouteBuilder routes)
public static void MapPackagePublishRoutes(this IEndpointRouteBuilder endpoints)
{
routes.MapRoute(
endpoints.MapControllerRoute(
name: Routes.UploadPackageRouteName,
template: "api/v2/package",
pattern: "api/v2/package",
defaults: new { controller = "PackagePublish", action = "Upload" },
constraints: new { httpMethod = new HttpMethodRouteConstraint("PUT") });

routes.MapRoute(
endpoints.MapControllerRoute(
name: Routes.DeleteRouteName,
template: "api/v2/package/{id}/{version}",
pattern: "api/v2/package/{id}/{version}",
defaults: new { controller = "PackagePublish", action = "Delete" },
constraints: new { httpMethod = new HttpMethodRouteConstraint("DELETE") });

routes.MapRoute(
endpoints.MapControllerRoute(
name: Routes.RelistRouteName,
template: "api/v2/package/{id}/{version}",
pattern: "api/v2/package/{id}/{version}",
defaults: new { controller = "PackagePublish", action = "Relist" },
constraints: new { httpMethod = new HttpMethodRouteConstraint("POST") });

return routes;
}

public static IRouteBuilder MapSymbolRoutes(this IRouteBuilder routes)
public static void MapSymbolRoutes(this IEndpointRouteBuilder endpoints)
{
routes.MapRoute(
endpoints.MapControllerRoute(
name: Routes.UploadSymbolRouteName,
template: "api/v2/symbol",
pattern: "api/v2/symbol",
defaults: new { controller = "Symbol", action = "Upload" },
constraints: new { httpMethod = new HttpMethodRouteConstraint("PUT") });

routes.MapRoute(
name: Routes.SymbolDownloadRouteName,
template: "api/download/symbols/{file}/{key}/{file2}",
defaults: new { controller = "Symbol", action = "Get" });

routes.MapRoute(
endpoints.MapControllerRoute(
name: Routes.SymbolDownloadRouteName,
template: "api/download/symbols/{prefix}/{file}/{key}/{file2}",
pattern: "api/download/symbols/{file}/{key}/{file2}",
defaults: new { controller = "Symbol", action = "Get" });

return routes;
endpoints.MapControllerRoute(
name: Routes.PrefixedSymbolDownloadRouteName,
pattern: "api/download/symbols/{prefix}/{file}/{key}/{file2}",
defaults: new { controller = "Symbol", action = "Get" });
}

public static IRouteBuilder MapSearchRoutes(this IRouteBuilder routes)
public static void MapSearchRoutes(this IEndpointRouteBuilder endpoints)
{
routes.MapRoute(
endpoints.MapControllerRoute(
name: Routes.SearchRouteName,
template: "v3/search",
defaults: new { controller = "Search", action = "SearchAsync" });
pattern: "v3/search",
defaults: new { controller = "Search", action = "Search" });

routes.MapRoute(
endpoints.MapControllerRoute(
name: Routes.AutocompleteRouteName,
template: "v3/autocomplete",
defaults: new { controller = "Search", action = "AutocompleteAsync" });
pattern: "v3/autocomplete",
defaults: new { controller = "Search", action = "Autocomplete" });

// This is an unofficial API to find packages that depend on a given package.
routes.MapRoute(
endpoints.MapControllerRoute(
name: Routes.DependentsRouteName,
template: "v3/dependents",
defaults: new { controller = "Search", action = "DependentsAsync" });

return routes;
pattern: "v3/dependents",
defaults: new { controller = "Search", action = "Dependents" });
}

public static IRouteBuilder MapPackageMetadataRoutes(this IRouteBuilder routes)
public static void MapPackageMetadataRoutes(this IEndpointRouteBuilder endpoints)
{
routes.MapRoute(
endpoints.MapControllerRoute(
name: Routes.RegistrationIndexRouteName,
template: "v3/registration/{id}/index.json",
defaults: new { controller = "PackageMetadata", action = "RegistrationIndexAsync" });
pattern: "v3/registration/{id}/index.json",
defaults: new { controller = "PackageMetadata", action = "RegistrationIndex" });

routes.MapRoute(
endpoints.MapControllerRoute(
name: Routes.RegistrationLeafRouteName,
template: "v3/registration/{id}/{version}.json",
defaults: new { controller = "PackageMetadata", action = "RegistrationLeafAsync" });

return routes;
pattern: "v3/registration/{id}/{version}.json",
defaults: new { controller = "PackageMetadata", action = "RegistrationLeaf" });
}

public static IRouteBuilder MapPackageContentRoutes(this IRouteBuilder routes)
public static void MapPackageContentRoutes(this IEndpointRouteBuilder endpoints)
{
routes.MapRoute(
endpoints.MapControllerRoute(
name: Routes.PackageVersionsRouteName,
template: "v3/package/{id}/index.json",
defaults: new { controller = "PackageContent", action = "GetPackageVersionsAsync" });
pattern: "v3/package/{id}/index.json",
defaults: new { controller = "PackageContent", action = "GetPackageVersions" });

routes.MapRoute(
endpoints.MapControllerRoute(
name: Routes.PackageDownloadRouteName,
template: "v3/package/{id}/{version}/{idVersion}.nupkg",
defaults: new { controller = "PackageContent", action = "DownloadPackageAsync" });
pattern: "v3/package/{id}/{version}/{idVersion}.nupkg",
defaults: new { controller = "PackageContent", action = "DownloadPackage" });

routes.MapRoute(
endpoints.MapControllerRoute(
name: Routes.PackageDownloadManifestRouteName,
template: "v3/package/{id}/{version}/{id2}.nuspec",
defaults: new { controller = "PackageContent", action = "DownloadNuspecAsync" });
pattern: "v3/package/{id}/{version}/{id2}.nuspec",
defaults: new { controller = "PackageContent", action = "DownloadNuspec" });

routes.MapRoute(
endpoints.MapControllerRoute(
name: Routes.PackageDownloadReadmeRouteName,
template: "v3/package/{id}/{version}/readme",
defaults: new { controller = "PackageContent", action = "DownloadReadmeAsync" });

return routes;
pattern: "v3/package/{id}/{version}/readme",
defaults: new { controller = "PackageContent", action = "DownloadReadme" });
}
}
}
32 changes: 32 additions & 0 deletions src/BaGet.Core.Server/Extensions/IHostExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Threading;
using System.Threading.Tasks;
using BaGet.Core;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;

namespace BaGet.Extensions
{
public static class IHostExtensions
{
public static async Task RunMigrationsAsync(this IHost host, CancellationToken cancellationToken)
{
// Run migrations if necessary.
var options = host.Services.GetRequiredService<IOptions<BaGetOptions>>();

if (options.Value.RunMigrationsAtStartup && options.Value.Database.Type != DatabaseType.AzureTable)
{
using (var scope = host.Services.CreateScope())
{
var ctx = scope.ServiceProvider.GetRequiredService<IContext>();

// TODO: An "InvalidOperationException" is thrown and caught due to a bug
// in EF Core 3.0. This is fixed in 3.1.
// See: https://github.com/dotnet/efcore/issues/18307
await ctx.Database.MigrateAsync(cancellationToken);
}
}
}
}
}
10 changes: 5 additions & 5 deletions src/BaGet.Core.Server/Extensions/IServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using BaGet.Configuration;
using BaGet.Controllers;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Cors.Infrastructure;
using Microsoft.AspNetCore.Http.Features;
Expand All @@ -14,15 +15,14 @@ public static class IServiceCollectionExtensions
public static IServiceCollection ConfigureHttpServices(this IServiceCollection services)
{
services
.AddMvc()
.AddApplicationPart(typeof(BaGet.Controllers.PackageContentController).Assembly)
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddJsonOptions(options =>
.AddControllers()
.AddApplicationPart(typeof(PackageContentController).Assembly)
.SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
});


services.AddCors();
services.AddHttpContextAccessor();
services.AddSingleton<IConfigureOptions<CorsOptions>, ConfigureCorsOptions>();
Expand Down
1 change: 1 addition & 0 deletions src/BaGet.Core.Server/Routes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ public class Routes
public const string PackageDownloadManifestRouteName = "package-download-manifest";
public const string PackageDownloadReadmeRouteName = "package-download-readme";
public const string SymbolDownloadRouteName = "symbol-download";
public const string PrefixedSymbolDownloadRouteName = "prefixed-symbol-download";
}
}
2 changes: 1 addition & 1 deletion src/BaGet.Core/BaGet.Core.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
<TargetFrameworks>netcoreapp3.0</TargetFrameworks>
Copy link
Owner Author

Choose a reason for hiding this comment

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

⚠️ This project will temporarily require .NET Core 3 as EF Core 3.0 requires .NET Standard 2.1. EF Core 3.1 reintroduced .NET Standard 2.0 support. I will re-add .NET Framework and .NET Standard 2.0 support once I've migrated BaGet to ASP.NET Core 3.1.


<Description>The core libraries that power BaGet.</Description>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/BaGet.Core/Search/DatabaseSearchService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,8 @@ IQueryable<Package> AddSearchFilters(IQueryable<Package> packageQuery)
}

var packageIds = search.Select(p => p.Id)
.OrderBy(id => id)
.Distinct()
.OrderBy(id => id)
Copy link
Owner Author

@loic-sharma loic-sharma Jan 21, 2020

Choose a reason for hiding this comment

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

This is a works around an EF Core 3 bug. See npgsql/efcore.pg#1195 (comment)

.Skip(skip)
.Take(take);

Expand Down
6 changes: 3 additions & 3 deletions src/BaGet.Core/Storage/PackageStorageService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public async Task SavePackageContentAsync(
lowercasedNormalizedVersion,
packagePath);

throw new InvalidOperationException($"Failed to store package {lowercasedId} {lowercasedNormalizedVersion}");
throw new InvalidOperationException($"Failed to store package {lowercasedId} {lowercasedNormalizedVersion} due to conflict");
}

// Store the package's nuspec.
Expand All @@ -82,7 +82,7 @@ public async Task SavePackageContentAsync(
lowercasedNormalizedVersion,
nuspecPath);

throw new InvalidOperationException($"Failed to store package {lowercasedId} {lowercasedNormalizedVersion} nuspec");
throw new InvalidOperationException($"Failed to store package {lowercasedId} {lowercasedNormalizedVersion} nuspec due to conflict");
}

// Store the package's readme, if one exists.
Expand All @@ -104,7 +104,7 @@ public async Task SavePackageContentAsync(
lowercasedNormalizedVersion,
readmePath);

throw new InvalidOperationException($"Failed to store package {lowercasedId} {lowercasedNormalizedVersion} readme");
throw new InvalidOperationException($"Failed to store package {lowercasedId} {lowercasedNormalizedVersion} readme due to conflict");
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/BaGet.Database.MySql/BaGet.Database.MySql.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
<TargetFrameworks>netcoreapp3.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
<TargetFrameworks>netcoreapp3.0</TargetFrameworks>
Copy link
Owner Author

Choose a reason for hiding this comment

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

⚠️ This project will temporarily require .NET Core 3 as EF Core 3.0 requires .NET Standard 2.1. EF Core 3.1 reintroduced .NET Standard 2.0 support. I will re-add .NET Framework and .NET Standard 2.0 support once I've migrated BaGet to ASP.NET Core 3.1.

</PropertyGroup>

<ItemGroup>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.2.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.0.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading