mirror of https://github.com/dotnet/tye.git
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.pull/195/head
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