Browse Source
Fixes: #189 Fixes: #153 This change rejiggers the docker build infrastructure to publish the project and generate a Dockerfile in the same directory. This way they can't be on separate drives! Also added some focused tests for single-phase docker build.davidfowl/dependencies
24 changed files with 479 additions and 52 deletions
@ -0,0 +1,89 @@ |
|||
// Licensed to the .NET Foundation under one or more agreements.
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
|||
// See the LICENSE file in the project root for more information.
|
|||
|
|||
using System.IO; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Tye; |
|||
using Xunit; |
|||
using static E2ETest.TestHelpers; |
|||
|
|||
namespace E2ETest |
|||
{ |
|||
// Tests permutations of our Dockerfile-related behaviors.
|
|||
public partial class TyeBuildTests |
|||
{ |
|||
[ConditionalFact] |
|||
[SkipIfDockerNotRunning] |
|||
public async Task TyeBuild_SinglePhase_GeneratedDockerfile() |
|||
{ |
|||
var projectName = "single-phase-dockerfile"; |
|||
var environment = "production"; |
|||
var imageName = "test/single-phase-dockerfile"; |
|||
|
|||
await DockerAssert.DeleteDockerImagesAsync(output, imageName); |
|||
|
|||
using var projectDirectory = CopyTestProjectDirectory(projectName); |
|||
File.Delete(Path.Combine(projectDirectory.DirectoryPath, "Dockerfile")); |
|||
Assert.False(File.Exists(Path.Combine(projectDirectory.DirectoryPath, "Dockerfile")), "Dockerfile should be gone."); |
|||
|
|||
var projectFile = new FileInfo(Path.Combine(projectDirectory.DirectoryPath, "tye.yaml")); |
|||
|
|||
var outputContext = new OutputContext(sink, Verbosity.Debug); |
|||
var application = await ApplicationFactory.CreateAsync(outputContext, projectFile); |
|||
|
|||
application.Registry = new ContainerRegistry("test"); |
|||
|
|||
try |
|||
{ |
|||
await BuildHost.ExecuteBuildAsync(outputContext, application, environment, interactive: false); |
|||
|
|||
var publishOutput = Assert.Single(application.Services.Single().Outputs.OfType<ProjectPublishOutput>()); |
|||
Assert.False(Directory.Exists(publishOutput.Directory.FullName), $"Directory {publishOutput.Directory.FullName} should be deleted."); |
|||
|
|||
await DockerAssert.AssertImageExistsAsync(output, imageName); |
|||
} |
|||
finally |
|||
{ |
|||
await DockerAssert.DeleteDockerImagesAsync(output, imageName); |
|||
} |
|||
} |
|||
|
|||
[ConditionalFact] |
|||
[SkipIfDockerNotRunning] |
|||
public async Task TyeBuild_SinglePhase_ExistingDockerfile() |
|||
{ |
|||
var projectName = "single-phase-dockerfile"; |
|||
var environment = "production"; |
|||
var imageName = "test/single-phase-dockerfile"; |
|||
|
|||
await DockerAssert.DeleteDockerImagesAsync(output, imageName); |
|||
|
|||
using var projectDirectory = CopyTestProjectDirectory(projectName); |
|||
Assert.True(File.Exists(Path.Combine(projectDirectory.DirectoryPath, "Dockerfile")), "Dockerfile should exist."); |
|||
|
|||
|
|||
var projectFile = new FileInfo(Path.Combine(projectDirectory.DirectoryPath, "tye.yaml")); |
|||
|
|||
var outputContext = new OutputContext(sink, Verbosity.Debug); |
|||
var application = await ApplicationFactory.CreateAsync(outputContext, projectFile); |
|||
|
|||
application.Registry = new ContainerRegistry("test"); |
|||
|
|||
try |
|||
{ |
|||
await BuildHost.ExecuteBuildAsync(outputContext, application, environment, interactive: false); |
|||
|
|||
var publishOutput = Assert.Single(application.Services.Single().Outputs.OfType<ProjectPublishOutput>()); |
|||
Assert.False(Directory.Exists(publishOutput.Directory.FullName), $"Directory {publishOutput.Directory.FullName} should be deleted."); |
|||
|
|||
await DockerAssert.AssertImageExistsAsync(output, imageName); |
|||
} |
|||
finally |
|||
{ |
|||
await DockerAssert.DeleteDockerImagesAsync(output, imageName); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Hosting; |
|||
using Microsoft.Extensions.Configuration; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Microsoft.Extensions.Logging; |
|||
|
|||
namespace multi_phase_dockerfile |
|||
{ |
|||
public class Program |
|||
{ |
|||
public static void Main(string[] args) |
|||
{ |
|||
CreateHostBuilder(args).Build().Run(); |
|||
} |
|||
|
|||
public static IHostBuilder CreateHostBuilder(string[] args) => |
|||
Host.CreateDefaultBuilder(args) |
|||
.ConfigureWebHostDefaults(webBuilder => |
|||
{ |
|||
webBuilder.UseStartup<Startup>(); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
{ |
|||
"iisSettings": { |
|||
"windowsAuthentication": false, |
|||
"anonymousAuthentication": true, |
|||
"iisExpress": { |
|||
"applicationUrl": "http://localhost:39765", |
|||
"sslPort": 44389 |
|||
} |
|||
}, |
|||
"profiles": { |
|||
"IIS Express": { |
|||
"commandName": "IISExpress", |
|||
"launchBrowser": true, |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
}, |
|||
"multi_phase_dockerfile": { |
|||
"commandName": "Project", |
|||
"launchBrowser": true, |
|||
"applicationUrl": "https://localhost:5001;http://localhost:5000", |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Builder; |
|||
using Microsoft.AspNetCore.Hosting; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Hosting; |
|||
|
|||
namespace multi_phase_dockerfile |
|||
{ |
|||
public class Startup |
|||
{ |
|||
// This method gets called by the runtime. Use this method to add services to the container.
|
|||
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
|
|||
public void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
} |
|||
|
|||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
|||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) |
|||
{ |
|||
if (env.IsDevelopment()) |
|||
{ |
|||
app.UseDeveloperExceptionPage(); |
|||
} |
|||
|
|||
app.UseRouting(); |
|||
|
|||
app.UseEndpoints(endpoints => |
|||
{ |
|||
endpoints.MapGet("/", async context => |
|||
{ |
|||
await context.Response.WriteAsync("Hello World!"); |
|||
}); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
{ |
|||
"Logging": { |
|||
"LogLevel": { |
|||
"Default": "Information", |
|||
"Microsoft": "Warning", |
|||
"Microsoft.Hosting.Lifetime": "Information" |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
{ |
|||
"Logging": { |
|||
"LogLevel": { |
|||
"Default": "Information", |
|||
"Microsoft": "Warning", |
|||
"Microsoft.Hosting.Lifetime": "Information" |
|||
} |
|||
}, |
|||
"AllowedHosts": "*" |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netcoreapp3.1</TargetFramework> |
|||
<RootNamespace>multi_phase_dockerfile</RootNamespace> |
|||
</PropertyGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,10 @@ |
|||
# tye application configuration file |
|||
# read all about it at https://github.com/dotnet/tye |
|||
# |
|||
# when you've given us a try, we'd love to know what you think: |
|||
# https://aka.ms/AA7q20u |
|||
# |
|||
name: multi-phase-dockerfile |
|||
services: |
|||
- name: multi-phase-dockerfile |
|||
project: multi-phase-dockerfile.csproj |
|||
@ -0,0 +1,4 @@ |
|||
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 |
|||
WORKDIR /app |
|||
COPY . /app |
|||
ENTRYPOINT ["dotnet", "single-phase-dockerfile.dll"] |
|||
@ -0,0 +1,26 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Hosting; |
|||
using Microsoft.Extensions.Configuration; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Microsoft.Extensions.Logging; |
|||
|
|||
namespace single_phase_dockerfile |
|||
{ |
|||
public class Program |
|||
{ |
|||
public static void Main(string[] args) |
|||
{ |
|||
CreateHostBuilder(args).Build().Run(); |
|||
} |
|||
|
|||
public static IHostBuilder CreateHostBuilder(string[] args) => |
|||
Host.CreateDefaultBuilder(args) |
|||
.ConfigureWebHostDefaults(webBuilder => |
|||
{ |
|||
webBuilder.UseStartup<Startup>(); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
{ |
|||
"iisSettings": { |
|||
"windowsAuthentication": false, |
|||
"anonymousAuthentication": true, |
|||
"iisExpress": { |
|||
"applicationUrl": "http://localhost:15313", |
|||
"sslPort": 44306 |
|||
} |
|||
}, |
|||
"profiles": { |
|||
"IIS Express": { |
|||
"commandName": "IISExpress", |
|||
"launchBrowser": true, |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
}, |
|||
"single_phase_dockerfile": { |
|||
"commandName": "Project", |
|||
"launchBrowser": true, |
|||
"applicationUrl": "https://localhost:5001;http://localhost:5000", |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Builder; |
|||
using Microsoft.AspNetCore.Hosting; |
|||
using Microsoft.AspNetCore.Http; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Hosting; |
|||
|
|||
namespace single_phase_dockerfile |
|||
{ |
|||
public class Startup |
|||
{ |
|||
// This method gets called by the runtime. Use this method to add services to the container.
|
|||
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
|
|||
public void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
} |
|||
|
|||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
|||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) |
|||
{ |
|||
if (env.IsDevelopment()) |
|||
{ |
|||
app.UseDeveloperExceptionPage(); |
|||
} |
|||
|
|||
app.UseRouting(); |
|||
|
|||
app.UseEndpoints(endpoints => |
|||
{ |
|||
endpoints.MapGet("/", async context => |
|||
{ |
|||
await context.Response.WriteAsync("Hello World!"); |
|||
}); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
{ |
|||
"Logging": { |
|||
"LogLevel": { |
|||
"Default": "Information", |
|||
"Microsoft": "Warning", |
|||
"Microsoft.Hosting.Lifetime": "Information" |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
{ |
|||
"Logging": { |
|||
"LogLevel": { |
|||
"Default": "Information", |
|||
"Microsoft": "Warning", |
|||
"Microsoft.Hosting.Lifetime": "Information" |
|||
} |
|||
}, |
|||
"AllowedHosts": "*" |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netcoreapp3.1</TargetFramework> |
|||
<RootNamespace>single_phase_dockerfile</RootNamespace> |
|||
</PropertyGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,10 @@ |
|||
# tye application configuration file |
|||
# read all about it at https://github.com/dotnet/tye |
|||
# |
|||
# when you've given us a try, we'd love to know what you think: |
|||
# https://aka.ms/AA7q20u |
|||
# |
|||
name: single-phase-dockerfile |
|||
services: |
|||
- name: single-phase-dockerfile |
|||
project: single-phase-dockerfile.csproj |
|||
Loading…
Reference in new issue