-
Notifications
You must be signed in to change notification settings - Fork 3
Support modern Octopus features added since repo last regularly maintained #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
matthewmarchus
wants to merge
49
commits into
Suremaker:master
Choose a base branch
from
tyler-technologies-oss:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
49 commits
Select commit
Hold shift + click to select a range
d587af3
LUNCH: Make several changes to stabilize the build and update the NuG…
matthewmarchus 12f2d0b
Jenkinsfile for dotnet
matthewmarchus 046e82a
LUNCH: Specify path to C:\Program Files\dotnet\dotnet.exe
matthewmarchus e6e53ad
LUNCH: Escape backslash
matthewmarchus da82072
LUNCH: Remove userId from credentials
matthewmarchus e1e9088
LUNCH: Use variable instead of literal for dotnet exe
matthewmarchus 9deaede
Double-quotes for the command word
matthewmarchus 71b57bb
POST-LUNCH: Add support for 'File' YAML key in LibraryVariableSets (S…
matthewmarchus 2571e4a
Improve publish
matthewmarchus 0db6e2a
publish
matthewmarchus e2c7598
Don't checkout twice
matthewmarchus de83b3b
Support soft updates for missing keys in objects
matthewmarchus 6b8c66f
Fix various test compile time errors
matthewmarchus 1b95a39
Implement model validation
matthewmarchus 9b154f5
Implement validation
matthewmarchus 9952142
SKUNK-4: Add a flag for project names during model download (-project…
matthewmarchus e6f7c9a
SKUNK-4: Upgrade Octopus.Client
matthewmarchus 442d6bd
SKUNK-4: Actually pass program argument to DownloadModel
matthewmarchus 08330c8
SKUNK-2: Add project channels in YAML
matthewmarchus 3f356cd
NONE: Download lifecycles
matthewmarchus 9b0a4dd
NONE: Add Default Lifecycle to mock
matthewmarchus d0d4f15
NONE: Fix doc generator
matthewmarchus 947b578
SKUNK-5: Support YAML references to project names
matthewmarchus 69f2ff9
EAG-847: Support a wide variety of new "XNameToId" value conversion t…
matthewmarchus 6f5915f
EAG-847: Don't remove protected IDs from property values, but do set …
matthewmarchus 48ab955
EAG-847: Add support for a wide variety of new keys across the YAML s…
matthewmarchus 99315e2
EAG-847: Better error handling
matthewmarchus 9908d8e
EAG-847: Better error text
matthewmarchus 5099476
EAG-847: Log a warning if you are using an old step template version
matthewmarchus c7a5802
EAG-847: Fix an issue where step templates were all upgraded automati…
matthewmarchus d32bcd3
EAG-847: Fix another bug with step template versioning
matthewmarchus 9854556
EAG-847: Support disabling steps
matthewmarchus 52881ec
EAG-847: Fix tests, Disabled->IsDisabled
matthewmarchus 99b85cb
EAG-847: Update documentation
matthewmarchus 5a83707
EAG-847: Support Variable step conditions
matthewmarchus 921b239
EAG-847: Support conditional actions (variable)
matthewmarchus 2a0e1e8
EAG-847: Fix tests
matthewmarchus e9e142a
EAG-847: Preserve identifiers
matthewmarchus a72f36e
EAG-847: Don't specify an ID for actions
matthewmarchus 63740c5
NONE: Add support for 3 new value transformations
matthewmarchus f2510c4
EAG-887: Support runbooks
matthewmarchus 902fdba
EAG-887: Fix order of YAML definitions
matthewmarchus c504934
EAG-919: Support package references!
matthewmarchus 391b49d
EAG-919: Fix tests
matthewmarchus f1bdf36
EAG-919: EnsureNotNull()
matthewmarchus c6d86d5
EAG-919: Fallbacks
matthewmarchus 5d18436
EAG-919: CanBeUsedForProjectVersioning
matthewmarchus c5f7514
NONE: Vastly improve the downloader. Automatically normalize the down…
matthewmarchus 9b5eca5
Update README.md
matthewmarchus File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,4 +8,6 @@ make/psmake.* | |
*.nupkg | ||
reports/ | ||
wiki/ | ||
Manual.md | ||
Manual.md | ||
.idea/ | ||
launchSettings.json |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
pipeline { | ||
agent any | ||
environment { | ||
dotnet = '"C:\\Program Files\\dotnet\\dotnet.exe"' | ||
} | ||
stages { | ||
stage('Restore Packages') { | ||
steps { | ||
bat "$dotnet restore --configfile NuGet.Config" | ||
} | ||
} | ||
stage('Clean') { | ||
steps { | ||
bat "$dotnet clean" | ||
} | ||
} | ||
stage('Build') { | ||
steps { | ||
bat "$dotnet build --configuration Release" | ||
} | ||
} | ||
stage('Publish') { | ||
steps { | ||
bat "$dotnet publish --configuration Release --runtime win-x64 --output \"E:/OctopusProjectBuilder/$env.BRANCH_NAME\"" | ||
} | ||
} | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,16 @@ | ||
using System; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Net; | ||
using System.Threading.Tasks; | ||
using Fclp; | ||
using Microsoft.Extensions.Logging; | ||
using Octopus.Client; | ||
using Octopus.Client.Model; | ||
using OctopusProjectBuilder.Model; | ||
using OctopusProjectBuilder.Uploader; | ||
using OctopusProjectBuilder.YamlReader; | ||
using OctopusProjectBuilder.YamlReader.Model; | ||
|
||
namespace OctopusProjectBuilder.Console | ||
{ | ||
|
@@ -33,6 +37,8 @@ static int Main(string[] args) | |
DownloadDefinitions(options).GetAwaiter().GetResult(); | ||
else if (options.Action == Options.Verb.CleanupConfig) | ||
CleanupConfig(options); | ||
else if (options.Action == Options.Verb.Validate) | ||
ValidateConfig(options); | ||
} | ||
catch (Exception e) | ||
{ | ||
|
@@ -42,6 +48,11 @@ static int Main(string[] args) | |
return 0; | ||
} | ||
|
||
private static SystemModel ValidateConfig(Options options) | ||
{ | ||
return new YamlSystemModelRepository(_loggerFactory).Load(options.DefinitionsDir); | ||
} | ||
|
||
private static void CleanupConfig(Options options) | ||
{ | ||
new YamlSystemModelRepository(_loggerFactory).CleanupConfig(options.DefinitionsDir); | ||
|
@@ -55,10 +66,167 @@ private static async Task UploadDefinitions(Options options) | |
|
||
private static async Task DownloadDefinitions(Options options) | ||
{ | ||
var model = await new ModelDownloader(await BuildRepository(options), _loggerFactory).DownloadModel(); | ||
new YamlSystemModelRepository(_loggerFactory).Save(model, options.DefinitionsDir); | ||
var repository = await BuildRepository(options); | ||
var model = await new ModelDownloader(repository, _loggerFactory) | ||
.DownloadModel(options.ProjectName); | ||
|
||
await new YamlSystemModelRepository(_loggerFactory).Save(model, options.DefinitionsDir, async yaml => | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please extract the Normalisation logic out of the Program class to make |
||
if (options.Normalize && yaml.LibraryVariableSets != null) | ||
{ | ||
foreach (var libraryVariableSet in yaml.LibraryVariableSets | ||
.Where(x => model.Projects | ||
.Any(p => p.IncludedLibraryVariableSetRefs.Any(r => r.Name == x.Name)))) | ||
{ | ||
if (libraryVariableSet.ContentType != LibraryVariableSet.VariableSetContentType.ScriptModule) | ||
{ | ||
continue; | ||
} | ||
|
||
YamlVariable contentType = libraryVariableSet.Variables | ||
.Where(v => v.Name == "Octopus.Script.Module.Language[" + libraryVariableSet.Name + "]") | ||
.FirstOrDefault(); | ||
string extension; | ||
if (contentType == null) | ||
{ | ||
extension = "script"; | ||
} | ||
else | ||
{ | ||
switch (contentType.Value) | ||
{ | ||
case "PowerShell": | ||
extension = "ps1"; | ||
break; | ||
default: | ||
extension = "script"; | ||
break; | ||
} | ||
} | ||
|
||
YamlVariable content = libraryVariableSet.Variables | ||
.Where(v => v.Name == "Octopus.Script.Module[" + libraryVariableSet.Name + "]") | ||
.FirstOrDefault(); | ||
if (contentType == null) | ||
{ | ||
continue; | ||
} | ||
|
||
string path = Path.Combine(options.DefinitionsDir, | ||
"LibraryVariableSet_" + libraryVariableSet.Name + "." + extension); | ||
File.WriteAllText(path, content.Value); | ||
content.Value = null; | ||
content.File = path; | ||
} | ||
} | ||
|
||
// Massage model: reduce identification | ||
if (options.Normalize && yaml.Projects != null) | ||
{ | ||
foreach (var project in yaml.Projects) | ||
{ | ||
// Normalize IDs on project variable templates | ||
foreach (var variable in project.Templates) | ||
{ | ||
variable.Id = null; | ||
} | ||
|
||
// Normalize deployment step templates | ||
foreach (var step in project.DeploymentProcess.Steps) | ||
{ | ||
foreach (var action in step.Actions.Where(action => | ||
action.Properties.Any(x => x.Key == "Octopus.Action.Template.Id"))) | ||
{ | ||
var actionTemplateId = action.Properties | ||
.FirstOrDefault(property => property.Key == "Octopus.Action.Template.Id"); | ||
var template = | ||
await repository.ActionTemplates.Get(actionTemplateId.Value); | ||
var actionTemplateVersion = action.Properties | ||
.FirstOrDefault(property => property.Key == "Octopus.Action.Template.Version"); | ||
|
||
if (actionTemplateVersion != null) | ||
{ | ||
var templateVersion = | ||
int.Parse(actionTemplateVersion.Value); | ||
var versionedTemplate = | ||
await repository.ActionTemplates.GetVersion(template, templateVersion); | ||
|
||
action.Properties = action.Properties.Where(property => | ||
versionedTemplate.Properties.All(property2 => | ||
property2.Key != property.Key) && | ||
property.Key != "Octopus.Action.Template.Version") | ||
.ToArray(); | ||
} | ||
|
||
actionTemplateId.ValueType = "StepTemplateNameToId"; | ||
actionTemplateId.Value = template.Name; | ||
} | ||
|
||
foreach (var action in step.Actions) | ||
{ | ||
HandleSplitActionToFile(project.Name, action, options.DefinitionsDir); | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
} | ||
|
||
private static void HandleSplitActionToFile(string projectName, YamlDeploymentAction action, string directory) | ||
{ | ||
if (action.ActionType == "Octopus.Script") | ||
{ | ||
var scriptSource = action.Properties | ||
.FirstOrDefault(property => property.Key == "Octopus.Action.Script.ScriptSource"); | ||
if (scriptSource == null) | ||
{ | ||
return; | ||
} | ||
|
||
var syntax = action.Properties | ||
.FirstOrDefault(property => property.Key == "Octopus.Action.Script.Syntax"); | ||
if (syntax == null) | ||
{ | ||
return; | ||
} | ||
|
||
string extension; | ||
switch (syntax.Value) | ||
{ | ||
case "PowerShell": | ||
extension = "ps1"; | ||
break; | ||
default: | ||
extension = "script"; | ||
break; | ||
} | ||
|
||
var scriptBody = action.Properties | ||
.FirstOrDefault(property => property.Key == "Octopus.Action.Script.ScriptBody"); | ||
if (scriptBody == null) | ||
{ | ||
return; | ||
} | ||
|
||
string path = Path.Combine(directory, "Script_" + projectName + "_" + action.Name + "." + extension); | ||
File.WriteAllText(path, scriptBody.Value); | ||
scriptBody.Value = null; | ||
scriptBody.File = path; | ||
} | ||
else if (action.ActionType == "Octopus.TentaclePackage") | ||
{ | ||
foreach (var postDeploy in action.Properties | ||
.Where(property => property.Key.StartsWith("Octopus.Action.CustomScripts."))) | ||
{ | ||
string path = Path.Combine(directory, "Script_" + projectName + "_" + action.Name + "." + | ||
postDeploy.Key.Substring("Octopus.Action.CustomScripts.".Length)); | ||
File.WriteAllText(path, postDeploy.Value); | ||
postDeploy.Value = null; | ||
postDeploy.File = path; | ||
} | ||
} | ||
} | ||
|
||
private static async Task<OctopusAsyncRepository> BuildRepository(Options options) | ||
{ | ||
return new OctopusAsyncRepository( | ||
|
@@ -71,8 +239,10 @@ public static Options ReadOptions(string[] args) | |
var parser = new FluentCommandLineParser<Options>(); | ||
parser.Setup(o => o.Action).As('a', "action").Required().WithDescription($"Action to perform: {string.Join(", ", Enum.GetValues(typeof(Options.Verb)).Cast<object>())}"); | ||
parser.Setup(o => o.DefinitionsDir).As('d', "definitions").Required().WithDescription("Definitions directory"); | ||
parser.Setup(o => o.OctopusUrl).As('u', "octopusUrl").Required().WithDescription("Octopus Url"); | ||
parser.Setup(o => o.OctopusApiKey).As('k', "octopusApiKey").Required().WithDescription("Octopus API key"); | ||
parser.Setup(o => o.OctopusUrl).As('u', "octopusUrl").WithDescription("Octopus Url"); | ||
parser.Setup(o => o.OctopusApiKey).As('k', "octopusApiKey").WithDescription("Octopus API key"); | ||
parser.Setup(o => o.ProjectName).As('p', "projectName").WithDescription("Project Name"); | ||
parser.Setup(o => o.Normalize).As('n', "normalize").SetDefault(true).WithDescription("Project Name"); | ||
parser.SetupHelp("?", "help").Callback(text => System.Console.WriteLine(text)); | ||
|
||
var result = parser.Parse(args); | ||
|
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
namespace OctopusProjectBuilder.Model | ||
{ | ||
public class Channel | ||
{ | ||
public Channel(ElementIdentifier identifier, string description, string projectName, bool? isDefault, | ||
string lifecycleName, IEnumerable<ChannelVersionRule> versionRules, IEnumerable<ElementReference> tenantTags) | ||
{ | ||
if (identifier == null) | ||
throw new ArgumentNullException(nameof(identifier)); | ||
|
||
Identifier = identifier; | ||
Description = description; | ||
ProjectName = projectName; | ||
IsDefault = isDefault; | ||
LifecycleName = lifecycleName; | ||
VersionRules = versionRules; | ||
TenantTags = tenantTags.ToArray(); | ||
} | ||
|
||
public ElementIdentifier Identifier { get; } | ||
public string Description { get; set; } | ||
public string ProjectName { get; set; } | ||
public bool? IsDefault { get; set; } | ||
public string LifecycleName { get; set; } | ||
public IEnumerable<ChannelVersionRule> VersionRules { get; set; } | ||
public IEnumerable<ElementReference> TenantTags { get; } | ||
|
||
public override string ToString() | ||
{ | ||
return Identifier.ToString(); | ||
} | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
|
||
namespace OctopusProjectBuilder.Model | ||
{ | ||
public class ChannelVersionRule | ||
{ | ||
public ChannelVersionRule(string tag, string versionRange, IEnumerable<ChannelVersionRulePackage> actionPackages) | ||
{ | ||
Tag = tag; | ||
VersionRange = versionRange; | ||
ActionPackages = actionPackages; | ||
} | ||
|
||
public string Tag { get; set; } | ||
public string VersionRange { get; set; } | ||
public IEnumerable<ChannelVersionRulePackage> ActionPackages { get; set; } | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
using Octopus.Client.Model; | ||
|
||
namespace OctopusProjectBuilder.Model | ||
{ | ||
public class ChannelVersionRulePackage | ||
{ | ||
public string DeploymentAction { get; set; } | ||
public string PackageReference { get; set; } | ||
|
||
public ChannelVersionRulePackage(string deploymentAction, string packageReference) | ||
{ | ||
DeploymentAction = deploymentAction; | ||
PackageReference = packageReference; | ||
} | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove this file as it won't be used during the project build.