diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
new file mode 100644
index 0000000..727dfd7
--- /dev/null
+++ b/.config/dotnet-tools.json
@@ -0,0 +1,12 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "cake.tool": {
+ "version": "0.38.5",
+ "commands": [
+ "dotnet-cake"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..1172014
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,23 @@
+; This file is for unifying the coding style for different editors and IDEs.
+; More information at http://EditorConfig.org
+
+root = true
+
+[*]
+end_of_line = CRLF
+
+[*.ps1]
+indent_style = space
+indent_size = 4
+
+[*.cs]
+indent_style = space
+indent_size = 4
+
+[*.cake]
+indent_style = space
+indent_size = 4
+
+[*.js]
+indent_style = tab
+indent_size = 2
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..bdb0cab
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,17 @@
+# Auto detect text files and perform LF normalization
+* text=auto
+
+# Custom for Visual Studio
+*.cs diff=csharp
+
+# Standard to msysgit
+*.doc diff=astextplain
+*.DOC diff=astextplain
+*.docx diff=astextplain
+*.DOCX diff=astextplain
+*.dot diff=astextplain
+*.DOT diff=astextplain
+*.pdf diff=astextplain
+*.PDF diff=astextplain
+*.rtf diff=astextplain
+*.RTF diff=astextplain
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e68a11b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,272 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignoreable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# Build related
+tools/*
+!tools/packages.config
+
+BuildArtifacts/
+*.temp.nuspec
+tests/integration/repos/
+Chocolatey.Docs.Cake.Recipe/Content/version.cake
+
+# Cake.Graph related
+docs/input/tasks/*
+
+# Wyam related
+docs/config.wyam.dll
+docs/config.wyam.hash
+docs/config.wyam.packages.xml
+
+*.orig
+.DS_Store
\ No newline at end of file
diff --git a/.teamcity/pom.xml b/.teamcity/pom.xml
new file mode 100644
index 0000000..c7aa014
--- /dev/null
+++ b/.teamcity/pom.xml
@@ -0,0 +1,104 @@
+
+
+ 4.0.0
+ Chocolatey.Docs.Cake.Recipe Config DSL Script
+ ChocolateyDocsCakeRecipe
+ ChocolateyDocsCakeRecipe
+ 1.0-SNAPSHOT
+
+
+ org.jetbrains.teamcity
+ configs-dsl-kotlin-parent
+ 1.0-SNAPSHOT
+
+
+
+
+ jetbrains-all
+ https://download.jetbrains.com/teamcity-repository
+
+ true
+
+
+
+ teamcity-server
+ https://teamcityserver/app/dsl-plugins-repository
+
+ true
+
+
+
+
+
+
+ JetBrains
+ https://download.jetbrains.com/teamcity-repository
+
+
+
+
+ ${basedir}
+
+
+ kotlin-maven-plugin
+ org.jetbrains.kotlin
+ ${kotlin.version}
+
+
+
+
+ compile
+ process-sources
+
+ compile
+
+
+
+ test-compile
+ process-test-sources
+
+ test-compile
+
+
+
+
+
+ org.jetbrains.teamcity
+ teamcity-configs-maven-plugin
+ ${teamcity.dsl.version}
+
+ kotlin
+ target/generated-configs
+
+
+
+
+
+
+
+ org.jetbrains.teamcity
+ configs-dsl-kotlin
+ ${teamcity.dsl.version}
+ compile
+
+
+ org.jetbrains.teamcity
+ configs-dsl-kotlin-plugins
+ 1.0-SNAPSHOT
+ pom
+ compile
+
+
+ org.jetbrains.kotlin
+ kotlin-stdlib-jdk8
+ ${kotlin.version}
+ compile
+
+
+ org.jetbrains.kotlin
+ kotlin-script-runtime
+ ${kotlin.version}
+ compile
+
+
+
\ No newline at end of file
diff --git a/.teamcity/settings.kts b/.teamcity/settings.kts
new file mode 100644
index 0000000..7ecd331
--- /dev/null
+++ b/.teamcity/settings.kts
@@ -0,0 +1,59 @@
+import jetbrains.buildServer.configs.kotlin.v2019_2.*
+import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.script
+import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.powerShell
+import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.pullRequests
+import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
+import jetbrains.buildServer.configs.kotlin.v2019_2.vcs.GitVcsRoot
+
+project {
+ buildType(ChocoDocsCakeRecipe)
+}
+
+object ChocoDocsCakeRecipe : BuildType({
+ id = AbsoluteId("ChocolateyDocsCakeRecipe")
+ name = "Build"
+
+ artifactRules = """
+ """.trimIndent()
+
+ params {
+ param("env.vcsroot.branch", "%vcsroot.branch%")
+ param("env.Git_Branch", "%teamcity.build.vcs.branch.ChocolateyDocsCakeRecipe_ChocoDocsCakeVcsRoot%")
+ param("teamcity.git.fetchAllHeads", "true")
+ password("env.GITHUB_PAT", "%system.GitHubPAT%", display = ParameterDisplay.HIDDEN, readOnly = true)
+ }
+
+ vcs {
+ root(DslContext.settingsRoot)
+
+ branchFilter = """
+ +:*
+ """.trimIndent()
+ }
+
+ steps {
+ powerShell {
+ name = "Cake Build"
+ scriptMode = file {
+ path = "build.ps1"
+ }
+ scriptArgs = "--target=CI --verbosity=Diagnostic"
+ }
+ }
+
+ triggers {
+ vcs {
+ branchFilter = ""
+ }
+ }
+
+ features {
+ pullRequests {
+ provider = github {
+ authType = token {
+ token = "%system.GitHubPAT%"
+ }
+ }
+ }
+ }
+})
diff --git a/.templates/default/create/footer.sbn b/.templates/default/create/footer.sbn
new file mode 100644
index 0000000..b1b0830
--- /dev/null
+++ b/.templates/default/create/footer.sbn
@@ -0,0 +1,10 @@
+{{ if config.create.include_footer }}
+
+### {{ config.create.footer_heading }}
+
+{{ if config.create.milestone_replace_text
+ replace_milestone_title config.create.footer_content config.create.milestone_replace_text milestone.target.title
+ else
+ config.create.footer_content
+ end
+end }}
diff --git a/.templates/default/index.sbn b/.templates/default/index.sbn
new file mode 100644
index 0000000..1a3856e
--- /dev/null
+++ b/.templates/default/index.sbn
@@ -0,0 +1,10 @@
+{{-
+ include 'release-info'
+ if milestone.target.description
+ include 'milestone'
+ end
+ include 'issues' | string.rstrip
+ if template_kind == "CREATE"
+ include 'create/footer'
+ end
+~}}
diff --git a/.templates/default/issue-details.sbn b/.templates/default/issue-details.sbn
new file mode 100644
index 0000000..73d5c28
--- /dev/null
+++ b/.templates/default/issue-details.sbn
@@ -0,0 +1,5 @@
+### {{ issue_label }}
+
+{{ for issue in issues.items[issue_label]
+ include 'issue-note'
+end }}
diff --git a/.templates/default/issue-note.sbn b/.templates/default/issue-note.sbn
new file mode 100644
index 0000000..0bcf3a8
--- /dev/null
+++ b/.templates/default/issue-note.sbn
@@ -0,0 +1 @@
+- {{ issue.title }} - see [#{{ issue.number }}]({{ issue.html_url }})
diff --git a/.templates/default/issues.sbn b/.templates/default/issues.sbn
new file mode 100644
index 0000000..307b608
--- /dev/null
+++ b/.templates/default/issues.sbn
@@ -0,0 +1,4 @@
+
+{{ for issue_label in issue_labels
+ include 'issue-details'
+end }}
diff --git a/.templates/default/milestone.sbn b/.templates/default/milestone.sbn
new file mode 100644
index 0000000..b345968
--- /dev/null
+++ b/.templates/default/milestone.sbn
@@ -0,0 +1,2 @@
+
+{{ milestone.target.description }}
diff --git a/.templates/default/release-info.sbn b/.templates/default/release-info.sbn
new file mode 100644
index 0000000..6a1084a
--- /dev/null
+++ b/.templates/default/release-info.sbn
@@ -0,0 +1,10 @@
+{{
+ if issues.count > 0
+ if commits.count > 0
+}}As part of this release we had [{{ commits.count }} {{ commits.count | string.pluralize "commit" "commits" }}]({{ commits.html_url }}) which resulted in [{{ issues.count }} {{ issues.count | string.pluralize "issue" "issues" }}]({{ milestone.target.html_url }}?closed=1) being closed.
+{{ else
+}}As part of this release we had [{{ issues.count }} {{ issues.count | string.pluralize "issue" "issues" }}]({{ milestone.target.html_url }}?closed=1) closed.
+{{ end
+ else if commits.count > 0
+}}As part of this release we had [{{ commits.count }} {{ commits.count | string.pluralize "commit" "commits" }}]({{ commits.html_url }}).
+{{ end -}}
diff --git a/Chocolatey.Docs.Cake.Recipe/Chocolatey.Docs.Cake.Recipe.nuspec b/Chocolatey.Docs.Cake.Recipe/Chocolatey.Docs.Cake.Recipe.nuspec
new file mode 100644
index 0000000..76b7e69
--- /dev/null
+++ b/Chocolatey.Docs.Cake.Recipe/Chocolatey.Docs.Cake.Recipe.nuspec
@@ -0,0 +1,19 @@
+
+
+
+ Chocolatey.Docs.Cake.Recipe
+ 0.1.0
+ Chocolatey
+ Chocolatey Software, Inc.
+ Opinionated set of scripts for use with Cake Builds for the various Chocolatey documentation sites.
+
+This NuGet package contains a set of re-usable scripts that is intended for use to build the various Chocolatey documentation sites, by adding a single load pre-processor directive to your main Cake Script. As a result, it is possible to use the same set of build scripts across multiple projects, without having to duplicate the scripts. All that is required is a small recipe build script, which sets the project specific information. It is not intended that the scripts within this package will be usable by everyone, as there will be decisions/conventions that are specific to how we build things at Chocolatey Software, Inc.
+
+ 2022-Present Chocolatey Software, Inc.
+ https://chocolatey.org/assets/images/nupkg/chocolateyicon.png
+ https://github.com/chocolatey/Chocolatey.Docs.Cake.Recipe
+
+ false
+ Chocolatey, Cake, Build, Automation, Recipe
+
+
diff --git a/Chocolatey.Docs.Cake.Recipe/Content/addins.cake b/Chocolatey.Docs.Cake.Recipe/Content/addins.cake
new file mode 100644
index 0000000..2300095
--- /dev/null
+++ b/Chocolatey.Docs.Cake.Recipe/Content/addins.cake
@@ -0,0 +1,39 @@
+///////////////////////////////////////////////////////////////////////////////
+// ADDINS
+///////////////////////////////////////////////////////////////////////////////
+
+#addin nuget:?package=Cake.Git&version=2.0.0
+#addin nuget:?package=Cake.Kudu&version=2.0.0
+#addin nuget:?package=Cake.Gulp&version=2.0.0
+#addin nuget:?package=Cake.Yarn&version=0.4.8
+
+Action> RequireAddin = (code, envVars) => {
+ var script = MakeAbsolute(File(string.Format("./{0}.cake", Guid.NewGuid())));
+ try
+ {
+ System.IO.File.WriteAllText(script.FullPath, code);
+ var arguments = new Dictionary();
+
+ if (BuildParameters.CakeConfiguration.GetValue("NuGet_UseInProcessClient") != null) {
+ arguments.Add("nuget_useinprocessclient", BuildParameters.CakeConfiguration.GetValue("NuGet_UseInProcessClient"));
+ }
+
+ if (BuildParameters.CakeConfiguration.GetValue("Settings_SkipVerification") != null) {
+ arguments.Add("settings_skipverification", BuildParameters.CakeConfiguration.GetValue("Settings_SkipVerification"));
+ }
+
+ CakeExecuteScript(script,
+ new CakeSettings
+ {
+ EnvironmentVariables = envVars,
+ Arguments = arguments
+ });
+ }
+ finally
+ {
+ if (FileExists(script))
+ {
+ DeleteFile(script);
+ }
+ }
+};
diff --git a/Chocolatey.Docs.Cake.Recipe/Content/build.cake b/Chocolatey.Docs.Cake.Recipe/Content/build.cake
new file mode 100644
index 0000000..a84840a
--- /dev/null
+++ b/Chocolatey.Docs.Cake.Recipe/Content/build.cake
@@ -0,0 +1,189 @@
+///////////////////////////////////////////////////////////////////////////////
+// SETUP / TEARDOWN
+///////////////////////////////////////////////////////////////////////////////
+
+Setup(context =>
+{
+ Information("Setting up BuildData...");
+
+ var buildData = new BuildData(context, BuildParameters.ProjectFilePath, BuildParameters.PublishDirectory, BuildParameters.OutputDirectory, BuildParameters.VirtualDirectory);
+
+ return buildData;
+});
+
+///////////////////////////////////////////////////////////////////////////////
+// TASK DEFINITIONS
+///////////////////////////////////////////////////////////////////////////////
+
+BuildParameters.Tasks.CleanTask = Task("Clean")
+ .Does((context, buildData) =>
+{
+ var directoriesToClean = new []{
+ buildData.PublishDirectory,
+ buildData.OutputDirectory,
+ "./bin",
+ "./obj",
+ "./temp",
+ "./wwwroot"
+ };
+
+ CleanDirectories(directoriesToClean);
+});
+
+BuildParameters.Tasks.YarnInstallTask = Task("Yarn-Install")
+ .WithCriteria(() => FileExists("./package.json"), "package.json file not found in repository")
+ .IsDependentOn("Clean")
+ .Does(() =>
+{
+ if (BuildSystem.IsLocalBuild)
+ {
+ Information("Running yarn install...");
+ Yarn.Install();
+ }
+ else
+ {
+ Information("Running yarn install --immutable...");
+ Yarn.Install(settings => settings.ArgumentCustomization = args => args.Append("--immutable"));
+ }
+});
+
+BuildParameters.Tasks.RunGulpTask = Task("Run-Gulp")
+ .WithCriteria(() => FileExists("./gulpfile.js"), "gulpfile.js file not found in repository")
+ .IsDependentOn("Yarn-Install")
+ .Does(() =>
+{
+ Gulp.Local.Execute();
+});
+
+
+BuildParameters.Tasks.StatiqPreviewTask = Task("Statiq-Preview")
+ .IsDependentOn("Run-Gulp")
+ .Does((context, buildData) =>
+{
+ var settings = new DotNetRunSettings {
+ Configuration = buildData.Configuration
+ };
+
+ var argumentBuilder = new ProcessArgumentBuilder().Append(string.Format("preview --output \"{0}\"", buildData.OutputDirectory));
+
+ if (buildData.VirtualDirectory != null)
+ {
+ argumentBuilder = argumentBuilder.Append(string.Format(" --virtual-dir \"{0}\"", buildData.VirtualDirectory));
+ }
+
+ DotNetRun(buildData.ProjectFilePath.FullPath, argumentBuilder, settings);
+});
+
+BuildParameters.Tasks.StatiqBuildTask = Task("Statiq-Build")
+ .IsDependentOn("Run-Gulp")
+ .Does((context, buildData) =>
+{
+ var settings = new DotNetRunSettings {
+ Configuration = buildData.Configuration
+ };
+
+ DotNetRun(buildData.ProjectFilePath.FullPath, new ProcessArgumentBuilder().Append(string.Format("--output \"{0}\"", buildData.OutputDirectory)), settings);
+});
+
+BuildParameters.Tasks.StatiqLinkValidationTask = Task("Statiq-LinkValidation")
+ .IsDependentOn("Run-Gulp")
+ .Does((context, buildData) =>
+{
+ var settings = new DotNetRunSettings {
+ Configuration = buildData.Configuration,
+ ArgumentCustomization = args => args.Append("-a ValidateRelativeLinks=Error -a ValidateAbsoluteLinks=Error")
+ };
+
+ DotNetRun(buildData.ProjectFilePath.FullPath, new ProcessArgumentBuilder().Append(string.Format("--output \"{0}\"", buildData.OutputDirectory)), settings);
+});
+
+BuildParameters.Tasks.PublishDocumentationTask = Task("Publish-Documentation")
+ .IsDependentOn("Statiq-Build")
+ .Does((context, buildData) =>
+{
+ var sourceCommit = GitLogTip("./");
+
+ CleanDirectory(buildData.PublishDirectory);
+ var publishFolder = buildData.PublishDirectory.Combine(DateTime.Now.ToString("yyyyMMdd_HHmmss"));
+
+ Information("Publishing Folder: {0}", publishFolder);
+ Information("Getting publish branch...");
+
+ if (!string.IsNullOrWhiteSpace(buildData.GitHubToken))
+ {
+ Information("Cloning repository using token...");
+ GitClone(buildData.DeployRemote, publishFolder, buildData.GitHubToken, "x-oauth-basic", new GitCloneSettings{ BranchName = buildData.DeployBranch });
+ }
+ else
+ {
+ Information("Cloning repository anonymously...");
+ GitClone(buildData.DeployRemote, publishFolder, new GitCloneSettings{ BranchName = buildData.DeployBranch });
+ }
+
+ Information("Sync output files...");
+
+ RequireTool(ToolSettings.KuduSyncGlobalTool, () => {
+ Kudu.Sync(buildData.OutputDirectory, publishFolder, new KuduSyncSettings {
+ ArgumentCustomization = args=>args.Append("--ignore").AppendQuoted(".git;CNAME")
+ });
+ });
+
+ if (GitHasUncommitedChanges(publishFolder))
+ {
+ Information("Stage all changes...");
+ GitAddAll(publishFolder);
+
+ if (GitHasStagedChanges(publishFolder))
+ {
+ Information("Commit all changes...");
+ GitCommit(
+ publishFolder,
+ sourceCommit.Committer.Name,
+ sourceCommit.Committer.Email,
+ string.Format("Continuous Integration Publish: {0}\r\n{1}", sourceCommit.Sha, sourceCommit.Message)
+ );
+
+ Information("Pushing all changes...");
+
+ GitPush(publishFolder, buildData.GitHubToken, "x-oauth-basic", buildData.DeployBranch);
+ }
+ else
+ {
+ Information("There are no changes that need to be committed");
+ }
+ }
+ else
+ {
+ Information("There are no changes that need to be staged");
+ }
+});
+
+BuildParameters.Tasks.DefaultTask = Task("Default")
+ .IsDependentOn("Statiq-Preview");
+
+///////////////////////////////////////////////////////////////////////////////
+// EXECUTION
+///////////////////////////////////////////////////////////////////////////////
+
+public Builder Build
+{
+ get
+ {
+ return new Builder(target => RunTarget(target));
+ }
+}
+
+public class Builder
+{
+ private Action _action;
+
+ public Builder(Action action)
+ {
+ _action = action;
+ }
+
+ public void Run()
+ {
+ _action(BuildParameters.Target);
+ }
+}
\ No newline at end of file
diff --git a/Chocolatey.Docs.Cake.Recipe/Content/buildData.cake b/Chocolatey.Docs.Cake.Recipe/Content/buildData.cake
new file mode 100644
index 0000000..23edfa8
--- /dev/null
+++ b/Chocolatey.Docs.Cake.Recipe/Content/buildData.cake
@@ -0,0 +1,29 @@
+public class BuildData
+{
+ public string DeployRemote { get; set; }
+ public string DeployBranch { get; set; }
+ public string GitHubToken { get; set; }
+ public FilePath ProjectFilePath { get; set; }
+ public DirectoryPath PublishDirectory { get; set; }
+ public DirectoryPath OutputDirectory { get; set; }
+ public string VirtualDirectory { get; set; }
+ public string Target { get; private set; }
+ public string Configuration { get; private set; }
+
+ public BuildData(ICakeContext context, FilePath projectFilePath, DirectoryPath publishDirectory, DirectoryPath outputDirectory, string virtualDirectory)
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
+ DeployRemote = context.EnvironmentVariable(Environment.DeployRemoteVariable);
+ DeployBranch = context.EnvironmentVariable(Environment.DeployBranchVariable);
+ GitHubToken = context.EnvironmentVariable(Environment.GitHubTokenVariable);
+ ProjectFilePath = projectFilePath;
+ PublishDirectory = publishDirectory;
+ OutputDirectory = outputDirectory;
+ VirtualDirectory = virtualDirectory;
+ Configuration = context.Argument("configuration", "Release");
+ }
+}
\ No newline at end of file
diff --git a/Chocolatey.Docs.Cake.Recipe/Content/configuration.cake b/Chocolatey.Docs.Cake.Recipe/Content/configuration.cake
new file mode 100644
index 0000000..3c59f6e
--- /dev/null
+++ b/Chocolatey.Docs.Cake.Recipe/Content/configuration.cake
@@ -0,0 +1,13 @@
+public static Cake.Core.Configuration.ICakeConfiguration GetConfiguration(this ICakeContext context)
+{
+ var configProvider = new Cake.Core.Configuration.CakeConfigurationProvider(context.FileSystem, context.Environment);
+
+ // This is very much a hack until this issue is implemented:
+ // https://github.com/cake-build/cake/issues/2690
+ var arguments = (Dictionary>)context.Arguments.GetType().GetField("_arguments", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(context.Arguments);
+
+ return configProvider.CreateConfiguration(
+ context.Environment.WorkingDirectory,
+ arguments.ToDictionary(x => x.Key, y=>y.Value.LastOrDefault())
+ );
+}
\ No newline at end of file
diff --git a/Chocolatey.Docs.Cake.Recipe/Content/environment.cake b/Chocolatey.Docs.Cake.Recipe/Content/environment.cake
new file mode 100644
index 0000000..a2e1afe
--- /dev/null
+++ b/Chocolatey.Docs.Cake.Recipe/Content/environment.cake
@@ -0,0 +1,16 @@
+public static class Environment
+{
+ public static string DeployRemoteVariable { get; private set; }
+ public static string DeployBranchVariable { get; private set; }
+ public static string GitHubTokenVariable { get; private set; }
+
+ public static void SetVariableNames(
+ string deployRemoteVariable = null,
+ string deployBranchVariable = null,
+ string gitHubTokenVariable = null)
+ {
+ DeployRemoteVariable = deployRemoteVariable ?? "STATIQ_DEPLOY_REMOTE";
+ DeployBranchVariable = deployBranchVariable ?? "STATIQ_DEPLOY_BRANCH";
+ GitHubTokenVariable = gitHubTokenVariable ?? "STATIQ_GITHUB_TOKEN";
+ }
+}
\ No newline at end of file
diff --git a/Chocolatey.Docs.Cake.Recipe/Content/parameters.cake b/Chocolatey.Docs.Cake.Recipe/Content/parameters.cake
new file mode 100644
index 0000000..2dbd309
--- /dev/null
+++ b/Chocolatey.Docs.Cake.Recipe/Content/parameters.cake
@@ -0,0 +1,62 @@
+public static class BuildParameters
+{
+ public static FilePath ProjectFilePath { get; private set; }
+ public static DirectoryPath PublishDirectory { get; private set; }
+ public static DirectoryPath OutputDirectory { get; private set; }
+ public static string VirtualDirectory { get; private set;}
+ public static BuildTasks Tasks { get; set; }
+ public static Cake.Core.Configuration.ICakeConfiguration CakeConfiguration { get; private set; }
+ public static string Target { get; private set; }
+
+ static BuildParameters()
+ {
+ Tasks = new BuildTasks();
+ }
+
+ public static void PrintParameters(ICakeContext context)
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException("context");
+ }
+
+ context.Information("Printing Build Parameters...");
+ context.Information("------------------------------------------------------------------------------------------");
+ context.Information("ProjectFilePath: {0}", ProjectFilePath);
+ context.Information("PublishDirectory: {0}", PublishDirectory);
+ context.Information("OutputDirectory: {0}", OutputDirectory);
+ context.Information("VirtualDirectory: {0}", VirtualDirectory);
+ context.Information("Target: {0}", Target);
+ context.Information("------------------------------------------------------------------------------------------");
+ }
+
+ public static void SetParameters(
+ ICakeContext context,
+ FilePath projectFilePath,
+ DirectoryPath publishDirectory = null,
+ DirectoryPath outputDirectory = null,
+ string virtualDirectory = null)
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException("context");
+ }
+
+ if (publishDirectory == null)
+ {
+ publishDirectory = context.MakeAbsolute(context.Directory("publish"));;
+ }
+
+ if (outputDirectory == null)
+ {
+ outputDirectory = context.MakeAbsolute(context.Directory("output"));;
+ }
+
+ ProjectFilePath = projectFilePath;
+ PublishDirectory = publishDirectory;
+ OutputDirectory = outputDirectory;
+ VirtualDirectory = virtualDirectory;
+ CakeConfiguration = context.GetConfiguration();
+ Target = context.Argument("target", "Default");
+ }
+}
\ No newline at end of file
diff --git a/Chocolatey.Docs.Cake.Recipe/Content/tasks.cake b/Chocolatey.Docs.Cake.Recipe/Content/tasks.cake
new file mode 100644
index 0000000..4c56538
--- /dev/null
+++ b/Chocolatey.Docs.Cake.Recipe/Content/tasks.cake
@@ -0,0 +1,12 @@
+public class BuildTasks
+{
+ // Build Tasks
+ public CakeTaskBuilder CleanTask { get; set; }
+ public CakeTaskBuilder YarnInstallTask { get; set; }
+ public CakeTaskBuilder RunGulpTask { get; set; }
+ public CakeTaskBuilder StatiqPreviewTask { get; set; }
+ public CakeTaskBuilder StatiqBuildTask { get; set; }
+ public CakeTaskBuilder StatiqLinkValidationTask { get; set; }
+ public CakeTaskBuilder PublishDocumentationTask { get; set; }
+ public CakeTaskBuilder DefaultTask { get; set; }
+}
\ No newline at end of file
diff --git a/Chocolatey.Docs.Cake.Recipe/Content/tools.cake b/Chocolatey.Docs.Cake.Recipe/Content/tools.cake
new file mode 100644
index 0000000..43b7268
--- /dev/null
+++ b/Chocolatey.Docs.Cake.Recipe/Content/tools.cake
@@ -0,0 +1,35 @@
+///////////////////////////////////////////////////////////////////////////////
+// TOOLS
+///////////////////////////////////////////////////////////////////////////////
+
+Action RequireTool = (tool, action) => {
+ var script = MakeAbsolute(File(string.Format("./{0}.cake", Guid.NewGuid())));
+ try
+ {
+ var arguments = new Dictionary();
+
+ if (BuildParameters.CakeConfiguration.GetValue("NuGet_UseInProcessClient") != null) {
+ arguments.Add("nuget_useinprocessclient", BuildParameters.CakeConfiguration.GetValue("NuGet_UseInProcessClient"));
+ }
+
+ if (BuildParameters.CakeConfiguration.GetValue("Settings_SkipVerification") != null) {
+ arguments.Add("settings_skipverification", BuildParameters.CakeConfiguration.GetValue("Settings_SkipVerification"));
+ }
+
+ System.IO.File.WriteAllText(script.FullPath, tool);
+ CakeExecuteScript(script,
+ new CakeSettings
+ {
+ Arguments = arguments
+ });
+ }
+ finally
+ {
+ if (FileExists(script))
+ {
+ DeleteFile(script);
+ }
+ }
+
+ action();
+};
diff --git a/Chocolatey.Docs.Cake.Recipe/Content/toolsettings.cake b/Chocolatey.Docs.Cake.Recipe/Content/toolsettings.cake
new file mode 100644
index 0000000..a58920f
--- /dev/null
+++ b/Chocolatey.Docs.Cake.Recipe/Content/toolsettings.cake
@@ -0,0 +1,16 @@
+public static class ToolSettings
+{
+ static ToolSettings()
+ {
+ SetToolPreprocessorDirectives();
+ }
+
+ public static string KuduSyncGlobalTool { get; private set; }
+
+ public static void SetToolPreprocessorDirectives(
+ string kuduSyncGlobalTool = "#tool dotnet:https://www.myget.org/F/cake-contrib/api/v3/index.json?package=KuduSync.Tool&version=1.5.4-g12abb018f9"
+ )
+ {
+ KuduSyncGlobalTool = kuduSyncGlobalTool;
+ }
+}
\ No newline at end of file
diff --git a/GitReleaseManager.yaml b/GitReleaseManager.yaml
new file mode 100644
index 0000000..6bda728
--- /dev/null
+++ b/GitReleaseManager.yaml
@@ -0,0 +1,32 @@
+issue-labels-include:
+- Breaking Change
+- Feature
+- Bug
+- Improvement
+- Documentation
+issue-labels-exclude:
+- Build
+- Internal / Refactoring
+- NO RELEASE NOTES
+issue-labels-alias:
+ - name: Documentation
+ header: Documentation
+ plural: Documentation
+ - name: Bug
+ header: Bug Fix
+ plural: Bug Fixes
+create:
+ include-sha-section: true
+ sha-section-heading: "SHA256 Hashes of the release artifacts"
+ sha-section-line-format: "- `{1}\t{0}`"
+close:
+ use-issue-comments: true
+ issue-comment: |-
+ :tada: This issue has been resolved in version {milestone} :tada:
+
+ The release is available on:
+
+ - [GitHub Release](https://github.com/{owner}/{repository}/releases/tag/{milestone})
+ - [NuGet Package](https://www.nuget.org/packages/{repository}/{milestone})
+
+ Your **[GitReleaseManager](https://github.com/GitTools/GitReleaseManager)** bot :package::rocket:
\ No newline at end of file
diff --git a/README.md b/README.md
index 76f802f..ee3fbf6 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,9 @@
# Chocolatey.Docs.Cake.Recipe
-A set of convention based Cake scripts for building Chocolatey's various documentation sites
+
+This repository contains a set of opinionated Cake Scripts which are used to build some of the documentations sites for Chocolatey, for example:
+
+- https://blog.chocolatey.org/
+- https://docs.chocolatey.org/en-us/
+- https://chocolatey.org/
+- https://chocolateyfest.com/
+- https://boxstarter.org/
\ No newline at end of file
diff --git a/build.bat b/build.bat
new file mode 100644
index 0000000..66586a9
--- /dev/null
+++ b/build.bat
@@ -0,0 +1,12 @@
+@echo off
+setlocal enableextensions enabledelayedexpansion
+set psscript="./build.ps1"
+echo ==================================================
+echo ============= WRAP POWERSHELL SCRIPT =============
+echo ==================================================
+
+echo calling %psscript% with args %*
+PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '%psscript%' %*"
+
+echo ==================================================
+endlocal
diff --git a/build.debug.bat b/build.debug.bat
new file mode 100644
index 0000000..802056b
--- /dev/null
+++ b/build.debug.bat
@@ -0,0 +1,12 @@
+@echo off
+setlocal enableextensions enabledelayedexpansion
+set psscript="./build.ps1"
+echo ==================================================
+echo ============= WRAP POWERSHELL SCRIPT =============
+echo ==================================================
+
+echo calling %psscript% with args %*
+PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '%psscript%' -Configuration Debug %*"
+
+echo ==================================================
+endlocal
diff --git a/build.official.bat b/build.official.bat
new file mode 100644
index 0000000..9f89b23
--- /dev/null
+++ b/build.official.bat
@@ -0,0 +1,12 @@
+@echo off
+setlocal enableextensions enabledelayedexpansion
+set psscript="./build.ps1"
+echo ==================================================
+echo ============= WRAP POWERSHELL SCRIPT =============
+echo ==================================================
+
+echo calling %psscript% with args %*
+PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '%psscript%' -Configuration ReleaseOfficial %*"
+
+echo ==================================================
+endlocal
diff --git a/build.ps1 b/build.ps1
new file mode 100644
index 0000000..0940a31
--- /dev/null
+++ b/build.ps1
@@ -0,0 +1,15 @@
+$ErrorActionPreference = 'Stop'
+
+$SCRIPT_NAME = "recipe.cake"
+
+Write-Host "Restoring .NET Core tools"
+dotnet tool restore
+if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
+
+Write-Host "Bootstrapping Cake"
+dotnet cake $SCRIPT_NAME --bootstrap
+if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
+
+Write-Host "Running Build"
+dotnet cake $SCRIPT_NAME @args
+if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
\ No newline at end of file
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..ba5d0c9
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+SCRIPT_NAME="recipe.cake"
+
+echo "Restoring .NET Core tools"
+dotnet tool restore
+
+echo "Bootstrapping Cake"
+dotnet cake $SCRIPT_NAME --bootstrap
+
+echo "Running Build"
+dotnet cake $SCRIPT_NAME "$@"
\ No newline at end of file
diff --git a/recipe.cake b/recipe.cake
new file mode 100644
index 0000000..4638f31
--- /dev/null
+++ b/recipe.cake
@@ -0,0 +1,50 @@
+#load nuget:?package=Cake.Recipe&version=2.2.1
+
+Environment.SetVariableNames();
+
+BuildParameters.SetParameters(context: Context,
+ buildSystem: BuildSystem,
+ sourceDirectoryPath: "./src",
+ title: "Chocolatey.Docs.Cake.Recipe",
+ repositoryOwner: "chocolatey",
+ repositoryName: "Chocolatey.Docs.Cake.Recipe",
+ appVeyorAccountName: "chocolatey",
+ nuspecFilePath: "./Chocolatey.Docs.Cake.Recipe/Chocolatey.Docs.Cake.Recipe.nuspec",
+ preferredBuildProviderType: BuildProviderType.TeamCity,
+ masterBranchName: "main");
+
+BuildParameters.PrintParameters(Context);
+
+ToolSettings.SetToolSettings(context: Context);
+
+ToolSettings.SetToolPreprocessorDirectives(
+ gitReleaseManagerTool: "#tool nuget:?package=GitReleaseManager&version=0.13.0",
+ gitReleaseManagerGlobalTool: "#tool dotnet:?package=GitReleaseManager.Tool&version=0.13.0");
+
+BuildParameters.Tasks.CleanTask
+ .IsDependentOn("Generate-Version-File");
+
+Task("Generate-Version-File")
+ .Does((context, buildVersion) => {
+ var buildMetaDataCodeGen = TransformText(@"
+ public class BuildMetaData
+ {
+ public static string Date { get; } = ""<%date%>"";
+ public static string Version { get; } = ""<%version%>"";
+ public static string CakeVersion { get; } = ""<%cakeversion%>"";
+ }",
+ "<%",
+ "%>"
+ )
+ .WithToken("date", BuildMetaData.Date)
+ .WithToken("version", buildVersion.SemVersion)
+ .WithToken("cakeversion", BuildMetaData.CakeVersion)
+ .ToString();
+
+ System.IO.File.WriteAllText(
+ "./Chocolatey.Docs.Cake.Recipe/Content/version.cake",
+ buildMetaDataCodeGen
+ );
+ });
+
+Build.RunNuGet();