From 6cdf2cc73c556bc69e32c743560adc7ac76a917b Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Sun, 8 Dec 2019 15:21:53 +0200 Subject: [PATCH] Improve the Docker samples (#1051) --- build.cake | 71 +++-- cake/UpdateDocs.cake | 8 +- cake/UtilsManaged.cake | 296 ++++-------------- cake/msbuild.cake | 11 +- cake/samples.cake | 169 ++++++++++ native/tizen/build.cake | 2 +- samples/Basic/Docker/Console/.dockerignore | 3 + samples/Basic/Docker/Console/Dockerfile | 25 ++ .../Basic/Docker/Console/SkiaSharpSample.sln | 22 ++ .../Docker/Console/SkiaSharpSample/Program.cs | 14 + .../SkiaSharpSample/SkiaSharpSample.csproj | 14 + samples/Basic/Docker/Console/nuget.config | 6 + samples/Basic/Docker/Console/run.ps1 | 2 + .../Basic/Docker/{ => WebApi}/.dockerignore | 0 .../{ => WebApi}/SkiaSharpSample.Docker.sln | 0 .../SkiaSharpSample/Controllers/Images.cs | 0 .../{ => WebApi}/SkiaSharpSample/Program.cs | 0 .../Properties/launchSettings.json | 0 .../SkiaSharpSample/SkiaSharpSample.csproj | 7 +- .../{ => WebApi}/SkiaSharpSample/Startup.cs | 0 .../appsettings.Development.json | 0 .../SkiaSharpSample/appsettings.json | 0 samples/Basic/Docker/WebApi/linux.Dockerfile | 33 ++ samples/Basic/Docker/WebApi/nuget.config | 6 + .../{sample-base.ps1 => WebApi/run.ps1} | 26 +- .../Basic/Docker/WebApi/windows.Dockerfile | 38 +++ samples/Basic/Docker/linux.Dockerfile | 51 --- samples/Basic/Docker/linux.run-sample.ps1 | 1 - samples/Basic/Docker/windows.Dockerfile | 111 ------- samples/Basic/Docker/windows.run-sample.ps1 | 1 - 30 files changed, 489 insertions(+), 428 deletions(-) create mode 100644 cake/samples.cake create mode 100644 samples/Basic/Docker/Console/.dockerignore create mode 100644 samples/Basic/Docker/Console/Dockerfile create mode 100644 samples/Basic/Docker/Console/SkiaSharpSample.sln create mode 100644 samples/Basic/Docker/Console/SkiaSharpSample/Program.cs create mode 100644 samples/Basic/Docker/Console/SkiaSharpSample/SkiaSharpSample.csproj create mode 100644 samples/Basic/Docker/Console/nuget.config create mode 100644 samples/Basic/Docker/Console/run.ps1 rename samples/Basic/Docker/{ => WebApi}/.dockerignore (100%) rename samples/Basic/Docker/{ => WebApi}/SkiaSharpSample.Docker.sln (100%) rename samples/Basic/Docker/{ => WebApi}/SkiaSharpSample/Controllers/Images.cs (100%) rename samples/Basic/Docker/{ => WebApi}/SkiaSharpSample/Program.cs (100%) rename samples/Basic/Docker/{ => WebApi}/SkiaSharpSample/Properties/launchSettings.json (100%) rename samples/Basic/Docker/{ => WebApi}/SkiaSharpSample/SkiaSharpSample.csproj (70%) rename samples/Basic/Docker/{ => WebApi}/SkiaSharpSample/Startup.cs (100%) rename samples/Basic/Docker/{ => WebApi}/SkiaSharpSample/appsettings.Development.json (100%) rename samples/Basic/Docker/{ => WebApi}/SkiaSharpSample/appsettings.json (100%) create mode 100644 samples/Basic/Docker/WebApi/linux.Dockerfile create mode 100644 samples/Basic/Docker/WebApi/nuget.config rename samples/Basic/Docker/{sample-base.ps1 => WebApi/run.ps1} (65%) create mode 100644 samples/Basic/Docker/WebApi/windows.Dockerfile delete mode 100644 samples/Basic/Docker/linux.Dockerfile delete mode 100644 samples/Basic/Docker/linux.run-sample.ps1 delete mode 100644 samples/Basic/Docker/windows.Dockerfile delete mode 100644 samples/Basic/Docker/windows.run-sample.ps1 diff --git a/build.cake b/build.cake index 07263fa1..bb5a6965 100644 --- a/build.cake +++ b/build.cake @@ -1,9 +1,9 @@ #addin nuget:?package=Cake.Xamarin&version=3.0.2 #addin nuget:?package=Cake.XCode&version=4.2.0 #addin nuget:?package=Cake.FileHelpers&version=3.2.1 -#addin nuget:?package=Cake.Json&version=4.0.0&loaddependencies=true +#addin nuget:?package=Cake.Json&version=4.0.0 #addin nuget:?package=SharpCompress&version=0.24.0 -#addin nuget:?package=Mono.ApiTools.NuGetDiff&version=1.1.0-preview.1&prerelease&loaddependencies=true +#addin nuget:?package=Mono.ApiTools.NuGetDiff&version=1.3.0&loaddependencies=true #addin nuget:?package=Xamarin.Nuget.Validator&version=1.1.1 #tool nuget:?package=mdoc&version=5.7.4.10 @@ -70,6 +70,7 @@ var TRACKED_NUGETS = new Dictionary { #load "cake/UtilsManaged.cake" #load "cake/externals.cake" #load "cake/UpdateDocs.cake" +#load "cake/samples.cake" Task ("determine-last-successful-build") .WithCriteria (string.IsNullOrEmpty (AZURE_BUILD_ID)) @@ -136,10 +137,17 @@ Task ("tests") .IsDependentOn ("externals") .Does (() => { - var RunDesktopTest = new Action (arch => { + var failedTests = 0; + + void RunDesktopTest (string arch) + { RunMSBuild ("./tests/SkiaSharp.Desktop.Tests/SkiaSharp.Desktop.Tests.sln", platform: arch == "AnyCPU" ? "Any CPU" : arch); - RunTests ($"./tests/SkiaSharp.Desktop.Tests/bin/{arch}/{CONFIGURATION}/SkiaSharp.Tests.dll", arch == "x86"); - }); + try { + RunTests ($"./tests/SkiaSharp.Desktop.Tests/bin/{arch}/{CONFIGURATION}/SkiaSharp.Tests.dll", arch == "x86"); + } catch { + failedTests++; + } + } CleanDirectories ($"{PACKAGE_CACHE_PATH}/skiasharp*"); CleanDirectories ($"{PACKAGE_CACHE_PATH}/harfbuzzsharp*"); @@ -156,7 +164,14 @@ Task ("tests") // .NET Core RunMSBuild ("./tests/SkiaSharp.NetCore.Tests/SkiaSharp.NetCore.Tests.sln"); - RunNetCoreTests ("./tests/SkiaSharp.NetCore.Tests/SkiaSharp.NetCore.Tests.csproj"); + try { + RunNetCoreTests ("./tests/SkiaSharp.NetCore.Tests/SkiaSharp.NetCore.Tests.csproj"); + } catch { + failedTests++; + } + + if (failedTests > 0) + throw new Exception ($"There were {failedTests} failed tests."); }); //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -235,12 +250,30 @@ Task ("samples") RunMSBuild (sln, platform: buildPlatform); } - }; + } // build the newly migrated samples CleanDirectories ($"{PACKAGE_CACHE_PATH}/skiasharp*"); CleanDirectories ($"{PACKAGE_CACHE_PATH}/harfbuzzsharp*"); + // TODO: Docker seems to be having issues on the old DevOps agents + + // // copy all the packages next to the Dockerfile files + // var dockerfiles = GetFiles ("./output/samples/**/Dockerfile"); + // foreach (var dockerfile in dockerfiles) { + // CopyDirectory (OUTPUT_NUGETS_PATH, dockerfile.GetDirectory ().Combine ("packages")); + // } + + // // build the run.ps1 (typically for Dockerfiles) + // var runs = GetFiles ("./output/samples/**/run.ps1"); + // foreach (var run in runs) { + // RunProcess ("pwsh", new ProcessSettings { + // Arguments = run.FullPath, + // WorkingDirectory = run.GetDirectory (), + // }); + // } + + // build solutions locally var solutions = GetFiles ("./output/samples/**/*.sln"); foreach (var sln in solutions) { var name = sln.GetFilenameWithoutExtension (); @@ -296,7 +329,8 @@ Task ("nuget") } } - var removePlatforms = new Action ((xdoc) => { + void RemovePlatforms (XDocument xdoc) + { var files = xdoc.Root .Elements ("files") .Elements ("file"); @@ -317,9 +351,10 @@ Task ("nuget") file.Add (new XAttribute ("target", file.Attribute ("src").Value)); } } - }); + } - var setVersion = new Action ((xdoc, suffix) => { + void SetVersion (XDocument xdoc, string suffix) + { var metadata = xdoc.Root.Element ("metadata"); var id = metadata.Element ("id"); var version = metadata.Element ("version"); @@ -351,7 +386,7 @@ Task ("nuget") } } } - }); + } DeleteFiles ("./output/*/nuget/*.nuspec"); foreach (var nuspec in GetFiles ("./nuget/*.nuspec")) { @@ -373,15 +408,15 @@ Task ("nuget") preview += $".{BUILD_NUMBER}"; } - removePlatforms (xdoc); + RemovePlatforms (xdoc); var outDir = $"./output/{dir}/nuget"; EnsureDirectoryExists (outDir); - setVersion (xdoc, ""); + SetVersion (xdoc, ""); xdoc.Save ($"{outDir}/{id}.nuspec"); - setVersion (xdoc, $"{preview}"); + SetVersion (xdoc, $"{preview}"); xdoc.Save ($"{outDir}/{id}.prerelease.nuspec"); // the placeholders @@ -392,9 +427,9 @@ Task ("nuget") CopyFile ("./External-Dependency-Info.txt", $"{outDir}/THIRD-PARTY-NOTICES.txt"); } - DeleteFiles ("output/nugets/*.nupkg"); + DeleteFiles ($"{OUTPUT_NUGETS_PATH}/*.nupkg"); foreach (var nuspec in GetFiles ("./output/*/nuget/*.nuspec")) { - PackageNuGet (nuspec, "./output/nugets/"); + PackageNuGet (nuspec, OUTPUT_NUGETS_PATH); } // setup validation options @@ -408,12 +443,12 @@ Task ("nuget") ValidPackageNamespace = new [] { "SkiaSharp", "HarfBuzzSharp" }, }; - var nupkgFiles = GetFiles ("./output/**/*.nupkg"); + var nupkgFiles = GetFiles ($"{OUTPUT_NUGETS_PATH}/*.nupkg"); Information ("Found ({0}) Nuget's to validate", nupkgFiles.Count ()); foreach (var nupkgFile in nupkgFiles) { - Information ("Verifiying Metadata of {0}", nupkgFile.GetFilename ()); + Verbose ("Verifiying Metadata of {0}", nupkgFile.GetFilename ()); var result = Xamarin.Nuget.Validator.NugetValidator.Validate(MakeAbsolute(nupkgFile).FullPath, options); if (!result.Success) { diff --git a/cake/UpdateDocs.cake b/cake/UpdateDocs.cake index 17dde5cc..be5e17c3 100644 --- a/cake/UpdateDocs.cake +++ b/cake/UpdateDocs.cake @@ -51,13 +51,13 @@ Task ("docs-expand-build-artifact") .Does (() => { Unzip ("./output/nuget.zip", "./output"); - MoveDirectory ("./output/nuget", "./output/nugets"); + MoveDirectory ("./output/nuget", OUTPUT_NUGETS_PATH); foreach (var id in TRACKED_NUGETS.Keys) { var version = GetVersion (id); var name = $"{id}.{version}.nupkg"; CleanDirectories ($"./output/{id}"); - Unzip ($"./output/nugets/{name}", $"./output/{id}/nuget"); + Unzip ($"{OUTPUT_NUGETS_PATH}/{name}", $"./output/{id}/nuget"); } }); @@ -68,7 +68,7 @@ Task ("docs-download-output") Task ("docs-api-diff") .Does (async () => { - var baseDir = "./output/nugets/api-diff"; + var baseDir = "{OUTPUT_NUGETS_PATH}/api-diff"; CleanDirectories (baseDir); var comparer = await CreateNuGetDiffAsync (); @@ -91,7 +91,7 @@ Task ("docs-api-diff") // generate the diff and copy to the changelogs Debug ($"Running a diff on '{latestVersion}' vs '{version}' of '{id}'..."); var diffRoot = $"{baseDir}/{id}"; - using (var reader = new PackageArchiveReader ($"./output/nugets/{id.ToLower ()}.{version}.nupkg")) { + using (var reader = new PackageArchiveReader ($"{OUTPUT_NUGETS_PATH}/{id.ToLower ()}.{version}.nupkg")) { // run the diff with just the breaking changes comparer.MarkdownDiffFileExtension = ".breaking.md"; comparer.IgnoreNonBreakingChanges = true; diff --git a/cake/UtilsManaged.cake b/cake/UtilsManaged.cake index 9be1564a..2977cb44 100644 --- a/cake/UtilsManaged.cake +++ b/cake/UtilsManaged.cake @@ -1,20 +1,16 @@ - -var MSBuildNS = (XNamespace) "http://schemas.microsoft.com/developer/msbuild/2003"; - -var PackageNuGet = new Action ((nuspecPath, outputPath) => +void PackageNuGet(FilePath nuspecPath, DirectoryPath outputPath) { - EnsureDirectoryExists (outputPath); - - NuGetPack (nuspecPath, new NuGetPackSettings { - OutputDirectory = outputPath, - BasePath = nuspecPath.GetDirectory (), + EnsureDirectoryExists(outputPath); + NuGetPack(nuspecPath, new NuGetPackSettings { + OutputDirectory = MakeAbsolute(outputPath), + BasePath = nuspecPath.GetDirectory(), ToolPath = NuGetToolPath, }); -}); +} -void RunTests (FilePath testAssembly, bool is32) +void RunTests(FilePath testAssembly, bool is32) { - var dir = testAssembly.GetDirectory (); + var dir = testAssembly.GetDirectory(); var settings = new XUnit2Settings { ReportName = "TestResults", XmlReport = true, @@ -23,18 +19,18 @@ void RunTests (FilePath testAssembly, bool is32) Parallelism = ParallelismOption.All, OutputDirectory = dir, WorkingDirectory = dir, - ArgumentCustomization = args => args.Append ("-verbose"), + ArgumentCustomization = args => args.Append("-verbose"), }; var traits = CreateTraitsDictionary(UNSUPPORTED_TESTS); foreach (var trait in traits) { settings.ExcludeTrait(trait.Name, trait.Value); } - XUnit2 (new [] { testAssembly }, settings); + XUnit2(new [] { testAssembly }, settings); } -void RunNetCoreTests (FilePath testAssembly) +void RunNetCoreTests(FilePath testAssembly) { - var dir = testAssembly.GetDirectory (); + var dir = testAssembly.GetDirectory(); var buildSettings = new DotNetCoreBuildSettings { Configuration = CONFIGURATION, WorkingDirectory = dir, @@ -56,7 +52,7 @@ void RunNetCoreTests (FilePath testAssembly) DotNetCoreTest(testAssembly.GetFilename().ToString(), settings); } -IEnumerable<(string Name, string Value)> CreateTraitsDictionary (string args) +IEnumerable<(string Name, string Value)> CreateTraitsDictionary(string args) { if (!string.IsNullOrEmpty(args)) { var traits = args.Split(';'); @@ -69,183 +65,29 @@ IEnumerable<(string Name, string Value)> CreateTraitsDictionary (string args) } } -var DecompressArchive = new Action ((archive, outputDir) => { - using (var stream = System.IO.File.OpenRead (archive.FullPath)) - using (var reader = ReaderFactory.Open (stream)) { - while (reader.MoveToNextEntry ()) { +void DecompressArchive(FilePath archive, DirectoryPath outputDir) +{ + using (var stream = System.IO.File.OpenRead(archive.FullPath)) + using (var reader = ReaderFactory.Open(stream)) { + while(reader.MoveToNextEntry()) { if (!reader.Entry.IsDirectory) { - reader.WriteEntryToDirectory (outputDir.FullPath, new ExtractionOptions { + reader.WriteEntryToDirectory(outputDir.FullPath, new ExtractionOptions { ExtractFullPath = true, Overwrite = true }); } } } -}); - -void CreateSamplesDirectory (DirectoryPath samplesDirPath, DirectoryPath outputDirPath, string versionSuffix = "") -{ - samplesDirPath = MakeAbsolute (samplesDirPath); - outputDirPath = MakeAbsolute (outputDirPath); - - var solutionProjectRegex = new Regex(@",\s*""(.*?\.\w{2}proj)"", ""(\{.*?\})"""); - - EnsureDirectoryExists (outputDirPath); - CleanDirectory (outputDirPath); - - var ignoreBinObj = new GlobberSettings { - Predicate = fileSystemInfo => { - var segments = fileSystemInfo.Path.Segments; - var keep = segments.All (s => - !s.Equals ("bin", StringComparison.OrdinalIgnoreCase) && - !s.Equals ("obj", StringComparison.OrdinalIgnoreCase) && - !s.Equals ("AppPackages", StringComparison.OrdinalIgnoreCase) && - !s.Equals (".vs", StringComparison.OrdinalIgnoreCase)); - return keep; - } - }; - - var files = GetFiles ($"{samplesDirPath}/**/*", ignoreBinObj); - foreach (var file in files) { - var rel = samplesDirPath.GetRelativePath (file); - var dest = outputDirPath.CombineWithFilePath (rel); - var ext = file.GetExtension () ?? ""; - - if (ext.Equals (".sln", StringComparison.OrdinalIgnoreCase)) { - var lines = FileReadLines (file.FullPath).ToList (); - var guids = new List (); - - // remove projects that aren't samples - for (var i = 0; i < lines.Count; i++) { - var line = lines [i]; - var m = solutionProjectRegex.Match (line); - if (!m.Success) - continue; - - // get the path of the project relative to the samples directory - var relProjectPath = (FilePath) m.Groups [1].Value; - var absProjectPath = GetFullPath (file, relProjectPath); - var relSamplesPath = samplesDirPath.GetRelativePath (absProjectPath); - if (!relSamplesPath.FullPath.StartsWith ("..")) - continue; - - Debug ($"Removing the project '{relProjectPath}' for solution '{rel}'."); - - // skip the next line as it is the "EndProject" line - guids.Add (m.Groups [2].Value.ToLower ()); - lines.RemoveAt (i--); - lines.RemoveAt (i--); - } - - // remove all the other references to this guid - if (guids.Count > 0) { - for (var i = 0; i < lines.Count; i++) { - var line = lines [i]; - foreach (var guid in guids) { - if (line.ToLower ().Contains (guid)) { - lines.RemoveAt (i--); - } - } - } - } - - // save the solution - EnsureDirectoryExists (dest.GetDirectory ()); - FileWriteLines (dest, lines.ToArray ()); - } else if (ext.Equals (".csproj", StringComparison.OrdinalIgnoreCase)) { - var xdoc = XDocument.Load (file.FullPath); - - // process all the files and project references - var projItems = xdoc.Root - .Elements ().Where (e => e.Name.LocalName == "ItemGroup") - .Elements ().Where (e => !string.IsNullOrWhiteSpace (e.Attribute ("Include")?.Value)) - .ToArray (); - foreach (var projItem in projItems) { - // get files in the include - var relFilePath = (FilePath) projItem.Attribute ("Include").Value; - var absFilePath = GetFullPath (file, relFilePath); - - // ignore files in the samples directory - var relSamplesPath = samplesDirPath.GetRelativePath (absFilePath); - if (!relSamplesPath.FullPath.StartsWith ("..")) - continue; - - // substitute with - if (projItem.Name.LocalName == "ProjectReference" && FileExists (absFilePath)) { - var xReference = XDocument.Load (absFilePath.FullPath); - var packagingGroup = xReference.Root - .Elements ().Where (e => e.Name.LocalName == "PropertyGroup") - .Elements ().Where (e => e.Name.LocalName == "PackagingGroup") - .FirstOrDefault ()?.Value; - var version = GetVersion (packagingGroup); - if (!string.IsNullOrWhiteSpace (version)) { - Debug ($"Substituting project reference {relFilePath} for project {rel}."); - var name = projItem.Name.Namespace + "PackageReference"; - var suffix = string.IsNullOrEmpty (versionSuffix) ? "" : $"-{versionSuffix}"; - projItem.AddAfterSelf (new XElement (name, new object[] { - new XAttribute("Include", packagingGroup), - new XAttribute("Version", version + suffix), - })); - } else { - Warning ($"Unable to find version information for package '{packagingGroup}'."); - } - } else { - Debug ($"Removing the file '{relFilePath}' for project '{rel}'."); - } - - // remove the element as it will be outside the sample directory - projItem.Remove (); - } - - // process all the imports - var imports = xdoc.Root - .Elements ().Where (e => - e.Name.LocalName == "Import" && - !string.IsNullOrWhiteSpace (e.Attribute ("Project")?.Value)) - .ToArray (); - foreach (var import in imports) { - var project = import.Attribute ("Project").Value; - - // skip files inside the samples directory or do not exist - var absProject = GetFullPath (file, project); - var relSamplesPath = samplesDirPath.GetRelativePath (absProject); - if (!relSamplesPath.FullPath.StartsWith ("..")) - continue; - - Debug ($"Removing import '{project}' for project '{rel}'."); - - // not inside the samples directory, so needs to be removed - import.Remove (); - } - - // save the project - EnsureDirectoryExists (dest.GetDirectory ()); - xdoc.Save (dest.FullPath); - } else { - EnsureDirectoryExists (dest.GetDirectory ()); - CopyFile (file, dest); - } - } - - DeleteFiles ($"{outputDirPath}/README.md"); - MoveFile ($"{outputDirPath}/README.zip.md", $"{outputDirPath}/README.md"); } -FilePath GetFullPath (FilePath root, FilePath path) +IEnumerable<(DirectoryPath path, string platform)> GetPlatformDirectories(DirectoryPath rootDir) { - path = path.FullPath.Replace ("*", "_"); - path = root.GetDirectory ().CombineWithFilePath (path); - return (FilePath) System.IO.Path.GetFullPath (path.FullPath); -} - -IEnumerable<(DirectoryPath path, string platform)> GetPlatformDirectories (DirectoryPath rootDir) -{ - var platformDirs = GetDirectories ($"{rootDir}/*"); + var platformDirs = GetDirectories($"{rootDir}/*"); // try find any cross-platform frameworks foreach (var dir in platformDirs) { - var d = dir.GetDirectoryName ().ToLower (); - if (d.StartsWith ("netstandard") || d.StartsWith ("portable")) { + var d = dir.GetDirectoryName().ToLower(); + if (d.StartsWith("netstandard") || d.StartsWith("portable")) { // we just want this single platform yield return (dir, null); yield break; @@ -254,83 +96,83 @@ IEnumerable<(DirectoryPath path, string platform)> GetPlatformDirectories (Direc // there were no cross-platform libraries, so process each platform foreach (var dir in platformDirs) { - var d = dir.GetDirectoryName ().ToLower (); - if (d.StartsWith ("monoandroid")) + var d = dir.GetDirectoryName().ToLower(); + if (d.StartsWith("monoandroid")) yield return (dir, "android"); - else if (d.StartsWith ("net4")) + else if (d.StartsWith("net4")) yield return (dir, "net"); - else if (d.StartsWith ("uap")) + else if (d.StartsWith("uap")) yield return (dir, "uwp"); - else if (d.StartsWith ("xamarinios") || d.StartsWith ("xamarin.ios")) + else if (d.StartsWith("xamarinios") || d.StartsWith("xamarin.ios")) yield return (dir, "ios"); - else if (d.StartsWith ("xamarinmac") || d.StartsWith ("xamarin.mac")) + else if (d.StartsWith("xamarinmac") || d.StartsWith("xamarin.mac")) yield return (dir, "macos"); - else if (d.StartsWith ("xamarintvos") || d.StartsWith ("xamarin.tvos")) + else if (d.StartsWith("xamarintvos") || d.StartsWith("xamarin.tvos")) yield return (dir, "tvos"); - else if (d.StartsWith ("xamarinwatchos") || d.StartsWith ("xamarin.watchos")) + else if (d.StartsWith("xamarinwatchos") || d.StartsWith("xamarin.watchos")) yield return (dir, "watchos"); - else if (d.StartsWith ("tizen")) + else if (d.StartsWith("tizen")) yield return (dir, "tizen"); else - throw new Exception ($"Unknown platform '{d}' found at '{dir}'."); + throw new Exception($"Unknown platform '{d}' found at '{dir}'."); } } -string[] GetReferenceSearchPaths () +string[] GetReferenceSearchPaths() { - var refs = new List (); + var refs = new List(); - if (IsRunningOnWindows ()) { - var vs = VSWhereLatest (new VSWhereLatestSettings { Requires = "Component.Xamarin" }); + if (IsRunningOnWindows()) { + var vs = VSWhereLatest(new VSWhereLatestSettings { Requires = "Component.Xamarin" }); var referenceAssemblies = $"{vs}/Common7/IDE/ReferenceAssemblies/Microsoft/Framework"; var pf = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86); - refs.AddRange (GetDirectories ("./output/docs/temp/*").Select (d => d.FullPath)); - refs.Add ($"{referenceAssemblies}/MonoTouch/v1.0"); - refs.Add ($"{referenceAssemblies}/MonoAndroid/v1.0"); - refs.Add ($"{referenceAssemblies}/MonoAndroid/v9.0"); - refs.Add ($"{referenceAssemblies}/Xamarin.iOS/v1.0"); - refs.Add ($"{referenceAssemblies}/Xamarin.TVOS/v1.0"); - refs.Add ($"{referenceAssemblies}/Xamarin.WatchOS/v1.0"); - refs.Add ($"{referenceAssemblies}/Xamarin.Mac/v2.0"); - refs.Add ($"{pf}/Windows Kits/10/UnionMetadata/Facade"); - refs.Add ($"{pf}/Windows Kits/10/References/Windows.Foundation.UniversalApiContract/1.0.0.0"); - refs.Add ($"{pf}/Windows Kits/10/References/Windows.Foundation.FoundationContract/1.0.0.0"); - refs.Add ($"{pf}/GtkSharp/2.12/lib"); - refs.Add ($"{vs}/Common7/IDE/PublicAssemblies"); + refs.AddRange(GetDirectories("./output/docs/temp/*").Select(d => d.FullPath)); + refs.Add($"{referenceAssemblies}/MonoTouch/v1.0"); + refs.Add($"{referenceAssemblies}/MonoAndroid/v1.0"); + refs.Add($"{referenceAssemblies}/MonoAndroid/v9.0"); + refs.Add($"{referenceAssemblies}/Xamarin.iOS/v1.0"); + refs.Add($"{referenceAssemblies}/Xamarin.TVOS/v1.0"); + refs.Add($"{referenceAssemblies}/Xamarin.WatchOS/v1.0"); + refs.Add($"{referenceAssemblies}/Xamarin.Mac/v2.0"); + refs.Add($"{pf}/Windows Kits/10/UnionMetadata/Facade"); + refs.Add($"{pf}/Windows Kits/10/References/Windows.Foundation.UniversalApiContract/1.0.0.0"); + refs.Add($"{pf}/Windows Kits/10/References/Windows.Foundation.FoundationContract/1.0.0.0"); + refs.Add($"{pf}/GtkSharp/2.12/lib"); + refs.Add($"{vs}/Common7/IDE/PublicAssemblies"); } else { // TODO } - return refs.ToArray (); + return refs.ToArray(); } -async Task CreateNuGetDiffAsync () +async Task CreateNuGetDiffAsync() { - var comparer = new NuGetDiff (); - comparer.SearchPaths.AddRange (GetReferenceSearchPaths ()); + var comparer = new NuGetDiff(); + comparer.SearchPaths.AddRange(GetReferenceSearchPaths()); comparer.PackageCache = PACKAGE_CACHE_PATH.FullPath; - await AddDep ("OpenTK.GLControl", "NET40", "reference"); - await AddDep ("OpenTK.GLControl", "NET40"); - await AddDep ("Tizen.NET", "netstandard2.0"); - await AddDep ("Xamarin.Forms", "netstandard2.0"); - await AddDep ("Xamarin.Forms", "MonoAndroid90"); - await AddDep ("Xamarin.Forms", "Xamarin.iOS10"); - await AddDep ("Xamarin.Forms", "Xamarin.Mac"); - await AddDep ("Xamarin.Forms", "tizen40"); - await AddDep ("Xamarin.Forms", "uap10.0"); - await AddDep ("Xamarin.Forms.Platform.WPF", "net45"); - await AddDep ("GtkSharp", "netstandard2.0"); - await AddDep ("GLibSharp", "netstandard2.0"); - await AddDep ("AtkSharp", "netstandard2.0"); - await AddDep ("System.Memory", "netstandard2.0"); + await AddDep("OpenTK.GLControl", "NET40", "reference"); + await AddDep("OpenTK.GLControl", "NET40"); + await AddDep("Tizen.NET", "netstandard2.0"); + await AddDep("Xamarin.Forms", "netstandard2.0"); + await AddDep("Xamarin.Forms", "MonoAndroid90"); + await AddDep("Xamarin.Forms", "Xamarin.iOS10"); + await AddDep("Xamarin.Forms", "Xamarin.Mac"); + await AddDep("Xamarin.Forms", "tizen40"); + await AddDep("Xamarin.Forms", "uap10.0"); + await AddDep("Xamarin.Forms.Platform.WPF", "net45"); + await AddDep("GtkSharp", "netstandard2.0"); + await AddDep("GLibSharp", "netstandard2.0"); + await AddDep("AtkSharp", "netstandard2.0"); + await AddDep("System.Memory", "netstandard2.0"); return comparer; async Task AddDep(string id, string platform, string type = "release") { - var version = GetVersion (id, type); + var version = GetVersion(id, type); var root = await comparer.ExtractCachedPackageAsync(id, version); comparer.SearchPaths.Add(System.IO.Path.Combine(root, "lib", platform)); } diff --git a/cake/msbuild.cake b/cake/msbuild.cake index daa77857..3dff2130 100644 --- a/cake/msbuild.cake +++ b/cake/msbuild.cake @@ -1,4 +1,5 @@ DirectoryPath PACKAGE_CACHE_PATH = MakeAbsolute(ROOT_PATH.Combine("externals/package_cache")); +DirectoryPath OUTPUT_NUGETS_PATH = MakeAbsolute(ROOT_PATH.Combine("output/nugets")); void RunMSBuild( FilePath solution, @@ -7,14 +8,14 @@ void RunMSBuild( bool restore = true, bool restoreOnly = false) { - var nugets = MakeAbsolute(ROOT_PATH.Combine("output/nugets")); - var nugetSources = new [] { nugets.FullPath, "https://api.nuget.org/v3/index.json" }; + var nugetSources = new [] { OUTPUT_NUGETS_PATH.FullPath, "https://api.nuget.org/v3/index.json" }; - EnsureDirectoryExists(nugets); + EnsureDirectoryExists(OUTPUT_NUGETS_PATH); MSBuild(solution, c => { c.Configuration = CONFIGURATION; c.Verbosity = VERBOSITY; + c.MaxCpuCount = 0; c.ToolVersion = MSBuildToolVersion.VS2017; c.NoLogo = VERBOSITY == Verbosity.Minimal; @@ -41,7 +42,7 @@ void RunMSBuild( c.Properties ["RestoreNoCache"] = new [] { "true" }; c.Properties ["RestorePackagesPath"] = new [] { PACKAGE_CACHE_PATH.FullPath }; // c.Properties ["RestoreSources"] = nugetSources; - var sep = IsRunningOnWindows () ? ";" : "%3B"; - c.ArgumentCustomization = args => args.Append ($"/p:RestoreSources=\"{string.Join (sep, nugetSources)}\""); + var sep = IsRunningOnWindows() ? ";" : "%3B"; + c.ArgumentCustomization = args => args.Append($"/p:RestoreSources=\"{string.Join(sep, nugetSources)}\""); }); } diff --git a/cake/samples.cake b/cake/samples.cake new file mode 100644 index 00000000..e0c3c33b --- /dev/null +++ b/cake/samples.cake @@ -0,0 +1,169 @@ +void CreateSamplesDirectory(DirectoryPath samplesDirPath, DirectoryPath outputDirPath, string versionSuffix = "") +{ + samplesDirPath = MakeAbsolute(samplesDirPath); + outputDirPath = MakeAbsolute(outputDirPath); + + var solutionProjectRegex = new Regex(@",\s*""(.*?\.\w{2}proj)"", ""(\{.*?\})"""); + + EnsureDirectoryExists(outputDirPath); + CleanDirectory(outputDirPath); + + var ignoreBinObj = new GlobberSettings { + Predicate = fileSystemInfo => { + var segments = fileSystemInfo.Path.Segments; + var keep = segments.All(s => + !s.Equals("bin", StringComparison.OrdinalIgnoreCase) && + !s.Equals("obj", StringComparison.OrdinalIgnoreCase) && + !s.Equals("AppPackages", StringComparison.OrdinalIgnoreCase) && + !s.Equals(".vs", StringComparison.OrdinalIgnoreCase)); + return keep; + } + }; + + var files = GetFiles($"{samplesDirPath}/**/*", ignoreBinObj); + foreach (var file in files) { + var rel = samplesDirPath.GetRelativePath(file); + var dest = outputDirPath.CombineWithFilePath(rel); + var ext = file.GetExtension() ?? ""; + + if (ext.Equals(".sln", StringComparison.OrdinalIgnoreCase)) { + var lines = FileReadLines(file.FullPath).ToList(); + var guids = new List(); + + // remove projects that aren't samples + for(var i = 0; i < lines.Count; i++) { + var line = lines [i]; + var m = solutionProjectRegex.Match(line); + if (!m.Success) + continue; + + // get the path of the project relative to the samples directory + var relProjectPath = (FilePath) m.Groups [1].Value; + var absProjectPath = GetFullPath(file, relProjectPath); + var relSamplesPath = samplesDirPath.GetRelativePath(absProjectPath); + if (!relSamplesPath.FullPath.StartsWith("..")) + continue; + + Debug($"Removing the project '{relProjectPath}' for solution '{rel}'."); + + // skip the next line as it is the "EndProject" line + guids.Add(m.Groups [2].Value.ToLower()); + lines.RemoveAt(i--); + lines.RemoveAt(i--); + } + + // remove all the other references to this guid + if (guids.Count > 0) { + for(var i = 0; i < lines.Count; i++) { + var line = lines [i]; + foreach (var guid in guids) { + if (line.ToLower().Contains(guid)) { + lines.RemoveAt(i--); + } + } + } + } + + // save the solution + EnsureDirectoryExists(dest.GetDirectory()); + FileWriteLines(dest, lines.ToArray()); + } else if (ext.Equals(".csproj", StringComparison.OrdinalIgnoreCase)) { + var xdoc = XDocument.Load(file.FullPath); + + // process all the files and project references + var projItems = xdoc.Root + .Elements().Where(e => e.Name.LocalName == "ItemGroup") + .Elements().Where(e => !string.IsNullOrWhiteSpace(e.Attribute("Include")?.Value)) + .ToArray(); + foreach (var projItem in projItems) { + var suffix = string.IsNullOrEmpty(versionSuffix) ? "" : $"-{versionSuffix}"; + + // update the versions + if (projItem.Name.LocalName == "PackageReference") { + var packageId = projItem.Attribute("Include").Value; + var version = GetVersion(packageId); + if (!string.IsNullOrWhiteSpace(version)) { + version += suffix; + Debug($"Substituting package version {packageId} for {version}."); + projItem.Attribute("Version").Value = version; + } else if (packageId.StartsWith("SkiaSharp") || packageId.StartsWith("HarfBuzzSharp")) { + Warning($"Unable to find version information for package '{packageId}'."); + } + continue; + } + + // get files in the include + var relFilePath = (FilePath) projItem.Attribute("Include").Value; + var absFilePath = GetFullPath(file, relFilePath); + + // ignore files in the samples directory + var relSamplesPath = samplesDirPath.GetRelativePath(absFilePath); + if (!relSamplesPath.FullPath.StartsWith("..")) + continue; + + // substitute with + if (projItem.Name.LocalName == "ProjectReference" && FileExists(absFilePath)) { + var xReference = XDocument.Load(absFilePath.FullPath); + var packagingGroup = xReference.Root + .Elements().Where(e => e.Name.LocalName == "PropertyGroup") + .Elements().Where(e => e.Name.LocalName == "PackagingGroup") + .FirstOrDefault()?.Value; + var version = GetVersion(packagingGroup); + if (!string.IsNullOrWhiteSpace(version)) { + Debug($"Substituting project reference {relFilePath} for project {rel}."); + var name = projItem.Name.Namespace + "PackageReference"; + projItem.AddAfterSelf(new XElement(name, new object[] { + new XAttribute("Include", packagingGroup), + new XAttribute("Version", version + suffix), + })); + } else { + Warning($"Unable to find version information for package '{packagingGroup}'."); + } + } else { + Debug($"Removing the file '{relFilePath}' for project '{rel}'."); + } + + // remove files that are outside + projItem.Remove(); + } + + // process all the imports + var imports = xdoc.Root + .Elements().Where(e => + e.Name.LocalName == "Import" && + !string.IsNullOrWhiteSpace(e.Attribute("Project")?.Value)) + .ToArray(); + foreach (var import in imports) { + var project = import.Attribute("Project").Value; + + // skip files inside the samples directory or do not exist + var absProject = GetFullPath(file, project); + var relSamplesPath = samplesDirPath.GetRelativePath(absProject); + if (!relSamplesPath.FullPath.StartsWith("..")) + continue; + + Debug($"Removing import '{project}' for project '{rel}'."); + + // not inside the samples directory, so needs to be removed + import.Remove(); + } + + // save the project + EnsureDirectoryExists(dest.GetDirectory()); + xdoc.Save(dest.FullPath); + } else { + EnsureDirectoryExists(dest.GetDirectory()); + CopyFile(file, dest); + } + } + + DeleteFiles($"{outputDirPath}/README.md"); + MoveFile($"{outputDirPath}/README.zip.md", $"{outputDirPath}/README.md"); +} + +FilePath GetFullPath(FilePath root, FilePath path) +{ + path = path.FullPath.Replace("*", "_"); + path = root.GetDirectory().CombineWithFilePath(path); + return (FilePath) System.IO.Path.GetFullPath(path.FullPath); +} diff --git a/native/tizen/build.cake b/native/tizen/build.cake index 81e44a61..cdb6095d 100644 --- a/native/tizen/build.cake +++ b/native/tizen/build.cake @@ -3,7 +3,7 @@ DirectoryPath OUTPUT_PATH = MakeAbsolute(ROOT_PATH.Combine("output/native/tizen" #load "../../cake/native-shared.cake" -DirectoryPath TIZEN_STUDIO_HOME = EnvironmentVariable ("TIZEN_STUDIO_HOME") ?? PROFILE_PATH.Combine ("tizen-studio"); +DirectoryPath TIZEN_STUDIO_HOME = EnvironmentVariable("TIZEN_STUDIO_HOME") ?? PROFILE_PATH.Combine("tizen-studio"); var bat = IsRunningOnWindows() ? ".bat" : ""; var tizen = TIZEN_STUDIO_HOME.CombineWithFilePath($"tools/ide/bin/tizen{bat}").FullPath; diff --git a/samples/Basic/Docker/Console/.dockerignore b/samples/Basic/Docker/Console/.dockerignore new file mode 100644 index 00000000..22c6fd51 --- /dev/null +++ b/samples/Basic/Docker/Console/.dockerignore @@ -0,0 +1,3 @@ +.dockerignore +bin +obj diff --git a/samples/Basic/Docker/Console/Dockerfile b/samples/Basic/Docker/Console/Dockerfile new file mode 100644 index 00000000..d506563a --- /dev/null +++ b/samples/Basic/Docker/Console/Dockerfile @@ -0,0 +1,25 @@ +################################################################################ +# Build Environment +################################################################################ +FROM mcr.microsoft.com/dotnet/core/sdk:2.1 AS build-env +WORKDIR /app + +# set up the contents +RUN mkdir packages +COPY . ./ + +# build and publish +RUN dotnet publish -c Release -o /app/out + + +################################################################################ +# Run Environment +################################################################################ +FROM mcr.microsoft.com/dotnet/core/runtime:2.1 +WORKDIR /app + +# copy from the build environment +COPY --from=build-env /app/out . + +# run +ENTRYPOINT [ "dotnet", "SkiaSharpSample.dll" ] diff --git a/samples/Basic/Docker/Console/SkiaSharpSample.sln b/samples/Basic/Docker/Console/SkiaSharpSample.sln new file mode 100644 index 00000000..7c808740 --- /dev/null +++ b/samples/Basic/Docker/Console/SkiaSharpSample.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkiaSharpSample", "SkiaSharpSample\SkiaSharpSample.csproj", "{F44BD813-7374-4A11-AEBD-C286AF97497F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F44BD813-7374-4A11-AEBD-C286AF97497F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F44BD813-7374-4A11-AEBD-C286AF97497F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F44BD813-7374-4A11-AEBD-C286AF97497F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F44BD813-7374-4A11-AEBD-C286AF97497F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/samples/Basic/Docker/Console/SkiaSharpSample/Program.cs b/samples/Basic/Docker/Console/SkiaSharpSample/Program.cs new file mode 100644 index 00000000..a4ad9a10 --- /dev/null +++ b/samples/Basic/Docker/Console/SkiaSharpSample/Program.cs @@ -0,0 +1,14 @@ +using System; + +using SkiaSharp; + +namespace SkiaSharpSample +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Platform Color Type: " + SKImageInfo.PlatformColorType); + } + } +} diff --git a/samples/Basic/Docker/Console/SkiaSharpSample/SkiaSharpSample.csproj b/samples/Basic/Docker/Console/SkiaSharpSample/SkiaSharpSample.csproj new file mode 100644 index 00000000..bb4a1914 --- /dev/null +++ b/samples/Basic/Docker/Console/SkiaSharpSample/SkiaSharpSample.csproj @@ -0,0 +1,14 @@ + + + + Exe + netcoreapp2.1 + + + + + + + + + \ No newline at end of file diff --git a/samples/Basic/Docker/Console/nuget.config b/samples/Basic/Docker/Console/nuget.config new file mode 100644 index 00000000..1f5722a5 --- /dev/null +++ b/samples/Basic/Docker/Console/nuget.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/samples/Basic/Docker/Console/run.ps1 b/samples/Basic/Docker/Console/run.ps1 new file mode 100644 index 00000000..4c65962b --- /dev/null +++ b/samples/Basic/Docker/Console/run.ps1 @@ -0,0 +1,2 @@ +docker build --tag skiasharp/console . +docker run --rm skiasharp/console diff --git a/samples/Basic/Docker/.dockerignore b/samples/Basic/Docker/WebApi/.dockerignore similarity index 100% rename from samples/Basic/Docker/.dockerignore rename to samples/Basic/Docker/WebApi/.dockerignore diff --git a/samples/Basic/Docker/SkiaSharpSample.Docker.sln b/samples/Basic/Docker/WebApi/SkiaSharpSample.Docker.sln similarity index 100% rename from samples/Basic/Docker/SkiaSharpSample.Docker.sln rename to samples/Basic/Docker/WebApi/SkiaSharpSample.Docker.sln diff --git a/samples/Basic/Docker/SkiaSharpSample/Controllers/Images.cs b/samples/Basic/Docker/WebApi/SkiaSharpSample/Controllers/Images.cs similarity index 100% rename from samples/Basic/Docker/SkiaSharpSample/Controllers/Images.cs rename to samples/Basic/Docker/WebApi/SkiaSharpSample/Controllers/Images.cs diff --git a/samples/Basic/Docker/SkiaSharpSample/Program.cs b/samples/Basic/Docker/WebApi/SkiaSharpSample/Program.cs similarity index 100% rename from samples/Basic/Docker/SkiaSharpSample/Program.cs rename to samples/Basic/Docker/WebApi/SkiaSharpSample/Program.cs diff --git a/samples/Basic/Docker/SkiaSharpSample/Properties/launchSettings.json b/samples/Basic/Docker/WebApi/SkiaSharpSample/Properties/launchSettings.json similarity index 100% rename from samples/Basic/Docker/SkiaSharpSample/Properties/launchSettings.json rename to samples/Basic/Docker/WebApi/SkiaSharpSample/Properties/launchSettings.json diff --git a/samples/Basic/Docker/SkiaSharpSample/SkiaSharpSample.csproj b/samples/Basic/Docker/WebApi/SkiaSharpSample/SkiaSharpSample.csproj similarity index 70% rename from samples/Basic/Docker/SkiaSharpSample/SkiaSharpSample.csproj rename to samples/Basic/Docker/WebApi/SkiaSharpSample/SkiaSharpSample.csproj index 3298aa0e..84347e5d 100644 --- a/samples/Basic/Docker/SkiaSharpSample/SkiaSharpSample.csproj +++ b/samples/Basic/Docker/WebApi/SkiaSharpSample/SkiaSharpSample.csproj @@ -2,7 +2,6 @@ netcoreapp2.1 - Windows @@ -12,9 +11,9 @@ - - - + + + \ No newline at end of file diff --git a/samples/Basic/Docker/SkiaSharpSample/Startup.cs b/samples/Basic/Docker/WebApi/SkiaSharpSample/Startup.cs similarity index 100% rename from samples/Basic/Docker/SkiaSharpSample/Startup.cs rename to samples/Basic/Docker/WebApi/SkiaSharpSample/Startup.cs diff --git a/samples/Basic/Docker/SkiaSharpSample/appsettings.Development.json b/samples/Basic/Docker/WebApi/SkiaSharpSample/appsettings.Development.json similarity index 100% rename from samples/Basic/Docker/SkiaSharpSample/appsettings.Development.json rename to samples/Basic/Docker/WebApi/SkiaSharpSample/appsettings.Development.json diff --git a/samples/Basic/Docker/SkiaSharpSample/appsettings.json b/samples/Basic/Docker/WebApi/SkiaSharpSample/appsettings.json similarity index 100% rename from samples/Basic/Docker/SkiaSharpSample/appsettings.json rename to samples/Basic/Docker/WebApi/SkiaSharpSample/appsettings.json diff --git a/samples/Basic/Docker/WebApi/linux.Dockerfile b/samples/Basic/Docker/WebApi/linux.Dockerfile new file mode 100644 index 00000000..09dcbe9f --- /dev/null +++ b/samples/Basic/Docker/WebApi/linux.Dockerfile @@ -0,0 +1,33 @@ +################################################################################ +# Build Environment +################################################################################ +FROM mcr.microsoft.com/dotnet/core/sdk:2.1 AS build-env +WORKDIR /app + +# set up the contents +RUN mkdir packages +COPY . ./ + +# build and publish +RUN dotnet publish -c Release -o /app/out + + +################################################################################ +# Run Environment +################################################################################ +FROM microsoft/dotnet:2.1-aspnetcore-runtime AS runtime + +# install Fontconfig +RUN apt-get update \ + && apt-get install -y --no-install-recommends libfontconfig1 \ + && rm -rf /var/lib/apt/lists/* + +# prepare the container for launch +WORKDIR /app +EXPOSE 80 + +# copy from the build environment +COPY --from=build-env /app/out . + +# run +ENTRYPOINT [ "dotnet", "SkiaSharpSample.dll" ] diff --git a/samples/Basic/Docker/WebApi/nuget.config b/samples/Basic/Docker/WebApi/nuget.config new file mode 100644 index 00000000..1f5722a5 --- /dev/null +++ b/samples/Basic/Docker/WebApi/nuget.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/samples/Basic/Docker/sample-base.ps1 b/samples/Basic/Docker/WebApi/run.ps1 similarity index 65% rename from samples/Basic/Docker/sample-base.ps1 rename to samples/Basic/Docker/WebApi/run.ps1 index df2d5703..fc0001b0 100644 --- a/samples/Basic/Docker/sample-base.ps1 +++ b/samples/Basic/Docker/WebApi/run.ps1 @@ -1,21 +1,36 @@ param( - [ValidateSet("linux", "windows")] - [string]$Platform = "linux" + [ValidateSet("linux", "windows", "")] + [string]$Platform = "" ) -$name = "skiasharp-basic-$Platform-sample" +if ($Platform -eq "") { + $Platform = if ($IsLinux -or $IsMacOS) { "linux" } else { "windows" } +} + +$name = "skiasharp_webapi" + +# we can only do --platform with Experimental=true +$buildPlatform = "" +$isExperimental = docker info -f "{{ json .ExperimentalBuild }}" +if ($isExperimental -eq "true") { + $buildPlatform = "--platform=$Platform" +} # build the container docker stop $name docker rm $name -New-Item "packages" -ItemType Directory -Force | Out-Null -docker build --platform $Platform --tag $name --file "$Platform.Dockerfile" . +docker build $buildPlatform --tag $name --file "$Platform.Dockerfile" . # run docker stop $name docker rm $name docker run --detach --name $name --publish "80:80" $name + +# get the IP so we can talk $ip = docker inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}" $name +if (-not $ip) { + $ip = docker inspect -f "{{ .NetworkSettings.IPAddress }}" $name +} # get a response (retry on 404 as the server may take a second to start up) try { @@ -26,6 +41,7 @@ try { # we were successful on 200 and > 0 content if ($imageResponse.StatusCode -eq 200) { if ($imageResponse.Content.Length -gt 0) { + Write-Host "Success!" break } else { throw "Empty response." diff --git a/samples/Basic/Docker/WebApi/windows.Dockerfile b/samples/Basic/Docker/WebApi/windows.Dockerfile new file mode 100644 index 00000000..9478f23c --- /dev/null +++ b/samples/Basic/Docker/WebApi/windows.Dockerfile @@ -0,0 +1,38 @@ +################################################################################ +# Build Environment +################################################################################ +FROM mcr.microsoft.com/dotnet/core/sdk:2.1 AS build-env +WORKDIR /app + +# set up the contents +RUN mkdir packages +COPY . ./ + +# build and publish +RUN dotnet publish -c Release -o /app/out + + +################################################################################ +# Run Environment +################################################################################ +FROM microsoft/windowsservercore:1803 AS runtime +SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] + +# install and setup ASP.NET Core Runtime +ENV ASPNETCORE_VERSION 2.1.5 +RUN Invoke-WebRequest -OutFile aspnetcore.zip https://dotnetcli.blob.core.windows.net/dotnet/aspnetcore/Runtime/$env:ASPNETCORE_VERSION/aspnetcore-runtime-$env:ASPNETCORE_VERSION-win-x64.zip; \ + Expand-Archive aspnetcore.zip -DestinationPath $env:ProgramFiles\dotnet; \ + Remove-Item -Force aspnetcore.zip +RUN setx /M PATH $($env:PATH + ';' + $env:ProgramFiles + '\dotnet') +ENV ASPNETCORE_URLS=http://+:80 \ + DOTNET_RUNNING_IN_CONTAINERS=true + +# prepare the container for launch +WORKDIR /app +EXPOSE 80 + +# copy from the build environment +COPY --from=build-env /app/out . + +# run +ENTRYPOINT [ "dotnet", "SkiaSharpSample.dll" ] diff --git a/samples/Basic/Docker/linux.Dockerfile b/samples/Basic/Docker/linux.Dockerfile deleted file mode 100644 index 980b9de8..00000000 --- a/samples/Basic/Docker/linux.Dockerfile +++ /dev/null @@ -1,51 +0,0 @@ - -################################################################################ -# runtime -# -# Downloads the files that are needed for running an ASP.NET Core app. -################################################################################ - -FROM microsoft/dotnet:2.1-aspnetcore-runtime AS runtime -RUN apt-get update \ - && apt-get install -y --no-install-recommends libfontconfig1 \ - && rm -rf /var/lib/apt/lists/* - - -################################################################################ -# build -# -# Builds the app. -################################################################################ - -FROM microsoft/dotnet:2.1-sdk AS build -WORKDIR /src -COPY SkiaSharpSample/SkiaSharpSample.csproj SkiaSharpSample/ -COPY packages/ packages/ -RUN dotnet restore SkiaSharpSample/SkiaSharpSample.csproj -s "/src/packages" -s "https://api.nuget.org/v3/index.json" - -COPY . . -WORKDIR /src/SkiaSharpSample -RUN dotnet build SkiaSharpSample.csproj -c Release -o /app - - -################################################################################ -# publish -# -# Publishes the app. -################################################################################ - -FROM build AS publish -RUN dotnet publish SkiaSharpSample.csproj -c Release -o /app - - -################################################################################ -# final -# -# Copies and runs the app. -################################################################################ - -FROM runtime AS final -WORKDIR /app -EXPOSE 80 -COPY --from=publish /app . -ENTRYPOINT dotnet SkiaSharpSample.dll diff --git a/samples/Basic/Docker/linux.run-sample.ps1 b/samples/Basic/Docker/linux.run-sample.ps1 deleted file mode 100644 index e8a9667f..00000000 --- a/samples/Basic/Docker/linux.run-sample.ps1 +++ /dev/null @@ -1 +0,0 @@ -. .\sample-base.ps1 -Platform "linux" \ No newline at end of file diff --git a/samples/Basic/Docker/windows.Dockerfile b/samples/Basic/Docker/windows.Dockerfile deleted file mode 100644 index 56bd38fc..00000000 --- a/samples/Basic/Docker/windows.Dockerfile +++ /dev/null @@ -1,111 +0,0 @@ -# escape=` - -################################################################################ -# sdk -# -# Downloads the files that are needed for building an ASP.NET Core app. -################################################################################ - -FROM microsoft/windowsservercore:1803 AS sdk -SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] - -# install .NET Core SDK -ENV DOTNET_SDK_VERSION 2.1.403 -RUN Invoke-WebRequest -OutFile dotnet.zip https://dotnetcli.blob.core.windows.net/dotnet/Sdk/$Env:DOTNET_SDK_VERSION/dotnet-sdk-$Env:DOTNET_SDK_VERSION-win-x64.zip; ` - $dotnet_sha512 = '52bb1117f170587eaceec1f78cdc41a41d4272154b5535bf61c86bfb75287323cac248434b05eabe4bc7716facabdb0f6475015cbb63f38d91af662618a06720'; ` - if ((Get-FileHash dotnet.zip -Algorithm sha512).Hash -ne $dotnet_sha512) { ` - Write-Host 'CHECKSUM VERIFICATION FAILED!'; ` - exit 1; ` - }; ` - ` - Expand-Archive dotnet.zip -DestinationPath $Env:ProgramFiles\dotnet; ` - Remove-Item -Force dotnet.zip - -# set PATH -RUN setx /M PATH $($Env:PATH + ';' + $Env:ProgramFiles + '\dotnet') - -# Configure Kestrel web server to bind to port 80 when present -ENV ASPNETCORE_URLS=http://+:80 ` - # Enable detection of running in a container - DOTNET_RUNNING_IN_CONTAINER=true ` - # Enable correct mode for dotnet watch (only mode supported in a container) - DOTNET_USE_POLLING_FILE_WATCHER=true ` - # Skip extraction of XML docs - generally not useful within an image/container - helps performance - NUGET_XMLDOC_MODE=skip - -# Trigger first run experience by running arbitrary cmd to populate local package cache -RUN dotnet help - - -################################################################################ -# runtime -# -# Downloads the files that are needed for running an ASP.NET Core app. -################################################################################ - -FROM microsoft/windowsservercore:1803 AS runtime -SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] - -# install ASP.NET Core Runtime -ENV ASPNETCORE_VERSION 2.1.5 -RUN Invoke-WebRequest -OutFile aspnetcore.zip https://dotnetcli.blob.core.windows.net/dotnet/aspnetcore/Runtime/$Env:ASPNETCORE_VERSION/aspnetcore-runtime-$Env:ASPNETCORE_VERSION-win-x64.zip; ` - $aspnetcore_sha512 = '98224c8646b7eab234b97f52735905bb0219ea2290490e408ff469459ea82116068854e7b9c5869bccef780b4ceac17477f34f23e06a0a6bedca445a3866d73e'; ` - if ((Get-FileHash aspnetcore.zip -Algorithm sha512).Hash -ne $aspnetcore_sha512) { ` - Write-Host 'CHECKSUM VERIFICATION FAILED!'; ` - exit 1; ` - }; ` - ` - Expand-Archive aspnetcore.zip -DestinationPath $Env:ProgramFiles\dotnet; ` - Remove-Item -Force aspnetcore.zip - -RUN setx /M PATH $($Env:PATH + ';' + $Env:ProgramFiles + '\dotnet') - -# install Visual C++ Redistributable -RUN Invoke-WebRequest -OutFile vc_redist.x64.exe https://aka.ms/vs/15/release/vc_redist.x64.exe; ` - Start-Process vc_redist.x64.exe -ArgumentList '/install /passive /norestart' -Wait; ` - Remove-Item -Force vc_redist.x64.exe - -# Configure web servers to bind to port 80 when present -ENV ASPNETCORE_URLS=http://+:80 ` - # Enable detection of running in a container - DOTNET_RUNNING_IN_CONTAINERS=true - - -################################################################################ -# build -# -# Builds the app. -################################################################################ - -FROM sdk AS build -WORKDIR /src -COPY SkiaSharpSample/SkiaSharpSample.csproj SkiaSharpSample/ -COPY packages/ packages/ -RUN dotnet restore SkiaSharpSample/SkiaSharpSample.csproj -s "/src/packages" -s "https://api.nuget.org/v3/index.json" - -COPY . . -WORKDIR /src/SkiaSharpSample -RUN dotnet build SkiaSharpSample.csproj -c Release -o /app - - -################################################################################ -# publish -# -# Publishes the app. -################################################################################ - -FROM build AS publish -RUN dotnet publish SkiaSharpSample.csproj -c Release -o /app - - -################################################################################ -# final -# -# Copies and runs the app. -################################################################################ - -FROM runtime AS final -WORKDIR /app -EXPOSE 80 -COPY --from=publish /app . -ENTRYPOINT dotnet SkiaSharpSample.dll diff --git a/samples/Basic/Docker/windows.run-sample.ps1 b/samples/Basic/Docker/windows.run-sample.ps1 deleted file mode 100644 index f6bc216b..00000000 --- a/samples/Basic/Docker/windows.run-sample.ps1 +++ /dev/null @@ -1 +0,0 @@ -. .\sample-base.ps1 -Platform "windows" \ No newline at end of file