diff --git a/src/Microsoft.Tye.Core/ApplicationExecutor.cs b/src/Microsoft.Tye.Core/ApplicationExecutor.cs index ad6b3627..800c5933 100644 --- a/src/Microsoft.Tye.Core/ApplicationExecutor.cs +++ b/src/Microsoft.Tye.Core/ApplicationExecutor.cs @@ -27,6 +27,8 @@ namespace Microsoft.Tye public async Task ExecuteAsync(ApplicationBuilder application) { + var serviceOutputs = new List(); + foreach (var service in application.Services) { using var tracker = output.BeginStep($"Processing Service '{service.Name}'..."); @@ -36,9 +38,12 @@ namespace Microsoft.Tye await step.ExecuteAsync(output, application, service); stepTracker.MarkComplete(); } + serviceOutputs.AddRange(service.Outputs); tracker.MarkComplete(); } + var ingressOutputs = new List(); + foreach (var ingress in application.Ingress) { using var tracker = output.BeginStep($"Processing Ingress '{ingress.Name}'..."); @@ -48,6 +53,7 @@ namespace Microsoft.Tye await step.ExecuteAsync(output, application, ingress); stepTracker.MarkComplete(); } + ingressOutputs.AddRange(ingress.Outputs); tracker.MarkComplete(); } diff --git a/src/Microsoft.Tye.Core/DeployApplicationKubernetesManifestStep.cs b/src/Microsoft.Tye.Core/DeployApplicationKubernetesManifestStep.cs index cd7cf247..2fa78a57 100644 --- a/src/Microsoft.Tye.Core/DeployApplicationKubernetesManifestStep.cs +++ b/src/Microsoft.Tye.Core/DeployApplicationKubernetesManifestStep.cs @@ -2,6 +2,7 @@ // 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.Collections.Generic; using System.CommandLine.Invocation; using System.IO; using System.Text; diff --git a/src/Microsoft.Tye.Core/PorterManifestGenerator.cs b/src/Microsoft.Tye.Core/PorterManifestGenerator.cs new file mode 100644 index 00000000..1c5bb0c9 --- /dev/null +++ b/src/Microsoft.Tye.Core/PorterManifestGenerator.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Tye; +using YamlDotNet.RepresentationModel; + +namespace Microsoft.Tye +{ + public class PorterManifestGenerator + { + public static YamlDocument CreatePorterManifest(OutputContext output, IEnumerable dockerImages, ApplicationBuilder application) + { + // write to temp directory for this step, make sure we allow generating to current directory + var root = new YamlMappingNode(); + root.Add("name", application.Name); + root.Add("description", "test"); + // TODO versioning + root.Add("version", "0.1.0"); + root.Add("tag", $"{application.Registry}/{application.Name}:0.1.0"); + + if (dockerImages.Count() > 0) + { + var images = new YamlMappingNode(); + root.Add("images", images); + foreach (var image in dockerImages) + { + var mapping = new YamlMappingNode(); + images.Add(image.ImageName, mapping); + mapping.Add("imageType", "docker"); + mapping.Add("repository", image.ImageName); // TODO may need repository here. + mapping.Add("tag", image.ImageTag); + } + } + + return new YamlDocument(root); + } + } +} diff --git a/src/Microsoft.Tye.Core/PorterPublisher.cs b/src/Microsoft.Tye.Core/PorterPublisher.cs new file mode 100644 index 00000000..e080e8af --- /dev/null +++ b/src/Microsoft.Tye.Core/PorterPublisher.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using YamlDotNet.RepresentationModel; + +namespace Microsoft.Tye +{ + public static class PorterPublisher + { + public static async Task PublishAsync(OutputContext output, YamlDocument document, ApplicationBuilder builder) + { + var tempFile = TempFile.Create(); + + { + await using var stream = File.OpenWrite(tempFile.FilePath); + await using var writer = new StreamWriter(stream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), leaveOpen: true); + var yamlStream = new YamlStream(document); + yamlStream.Save(writer, assignAnchors: false); + + await ProcessUtil.RunAsync("porter", $"publish -f {tempFile.FilePath}"); + } + } + } +} diff --git a/src/Microsoft.Tye.Core/PublishPorterStep.cs b/src/Microsoft.Tye.Core/PublishPorterStep.cs new file mode 100644 index 00000000..5973dc9f --- /dev/null +++ b/src/Microsoft.Tye.Core/PublishPorterStep.cs @@ -0,0 +1,26 @@ +// 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.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.Tye +{ + public class PublishPorterStep : ApplicationExecutor.ApplicationStep + { + public override string DisplayText => "Publishing Porter Bundle ..."; + + public string Environment { get; set; } = "production"; + + public override async Task ExecuteAsync(OutputContext output, ApplicationBuilder application) + { + var dockerImages = application.Services.SelectMany(s => s.Outputs.OfType()); + // TODO Check if existing porter.yaml file exists. + var document = PorterManifestGenerator.CreatePorterManifest(output, dockerImages, application); + + await PorterPublisher.PublishAsync(output, document, application); + } + } +} diff --git a/src/tye/Program.PushCommand.cs b/src/tye/Program.PushCommand.cs index f17507a8..8f85146c 100644 --- a/src/tye/Program.PushCommand.cs +++ b/src/tye/Program.PushCommand.cs @@ -64,6 +64,10 @@ namespace Microsoft.Tye new BuildDockerImageStep() { Environment = environment, }, new PushDockerImageStep() { Environment = environment, }, }, + ApplicationSteps = + { + new PublishPorterStep() + } }; await executor.ExecuteAsync(application);