Skip to content

Commit

Permalink
Update to ASP.NET Core 3.0 (#444)
Browse files Browse the repository at this point in the history
Updates BaGet to ASP.NET Core 3.0. This is based off @MarkZither's work (see #443). Thank you for all the help @MarkZither!

⚠️ Many of BaGet's projects will **temporarily** require .NET Core 3 because 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.

Part of #439
  • Loading branch information
loic-sharma authored Jan 21, 2020
1 parent dcbd51d commit 05bfc61
Show file tree
Hide file tree
Showing 32 changed files with 230 additions and 191 deletions.
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>

<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>

<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>

<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)
.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>
</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

0 comments on commit 05bfc61

Please sign in to comment.