Skip to content
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

feat: create release commit #52

Merged
merged 4 commits into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .nuke/build.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"type": "string",
"enum": [
"BuildTemplate",
"CreateVersionChangeCommit",
"GenerateDocumentationFeature",
"GetFeatures",
"GetTemplates",
Expand All @@ -95,6 +96,7 @@
"type": "string",
"enum": [
"BuildTemplate",
"CreateVersionChangeCommit",
"GenerateDocumentationFeature",
"GetFeatures",
"GetTemplates",
Expand Down
198 changes: 145 additions & 53 deletions build.test/Fixture.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
using System.Text.Json;
using CliWrap;
using CliWrap.Builders;
using Nuke.Common;
using Nuke.Common.IO;

namespace build.test;

internal sealed class CustomFixture : IAsyncDisposable
{
private readonly List<string> tags = new();
private readonly List<Tag> tags = new();
private readonly List<string> tempFiles = new();
private int commitsCount = 0;
private string? commitToRestore;

public async Task SaveCommit(string commit)
{
await Cli.Wrap("git")
.WithArguments(args => args
.Add("rev-parse")
.Add(commit))
.WithStandardOutputPipe(PipeTarget.ToDelegate(x => commitToRestore = x))
.ExecuteAsync();
}

public bool KeepFiles { get; init; }

Expand All @@ -28,7 +39,7 @@ public async ValueTask DisposeAsync()

if (!KeepCommits)
{
await RevertCommits(commitsCount);
await RevertCommits(commitToRestore);
}

if (!KeepFiles)
Expand All @@ -52,14 +63,13 @@ await Cli.Wrap("git")
.Add("--progress")
.Add(files))
.WithStandardOutputPipe(PipeTarget.ToDelegate(Console.WriteLine))
.WithValidation(CommandResultValidation.None)
.ExecuteAsync();
}

public string GetTagForFeature(string feature) => $"feature_{feature}";

public async Task RevertCommits(int numberOfCommits)
public async Task RevertCommits(string? commit)
{
if (numberOfCommits <= 0)
if (string.IsNullOrEmpty(commit))
{
return;
}
Expand All @@ -69,7 +79,7 @@ await Cli.Wrap("git")
.Add("reset")
.Add("--no-refresh")
.Add("--soft")
.Add($"HEAD~{numberOfCommits}"))
.Add(commit))
.WithStandardOutputPipe(PipeTarget.ToDelegate(Console.WriteLine))
.ExecuteAsync();
}
Expand Down Expand Up @@ -107,55 +117,64 @@ public void CreateTempFile(string path)
}

public async Task CreateFeatureConfig(
string featureName,
int major,
int minor,
int build)
Feature featureName,
Version version)
{
this.CreateTempDirectory(GetFeatureRoot(featureName));
this.CreateTempDirectory(featureName.GetFeatureRoot(RootDirectory));

await File.WriteAllTextAsync(
GetFeatureConfig(featureName),
$$"""{ "version": "{{major}}.{{minor}}.{{build}}" }""");
}

public AbsolutePath GetFeatureRoot(string featureName)
=> NukeBuild.RootDirectory
/ "features"
/ "src"
/ featureName;
var featureConfig = featureName.GetFeatureConfig(RootDirectory);
var json = $$"""
{
"version": "{{version}}",
"id": "{{featureName}}",
"name": "{{featureName}}"
}
""";

public AbsolutePath GetFeatureConfig(string featureName)
=> GetFeatureRoot(featureName)
/ "devcontainer-feature.json";
await File.WriteAllTextAsync(featureConfig, json);
}

public async Task<string?> GetVersion(string feature)
public async Task<string?> GetVersion(Feature feature)
{
var featureConfig = this.GetFeatureConfig(feature);
var featureConfig = feature.GetFeatureConfig(RootDirectory);
using var fileStream = File.OpenRead(featureConfig);
var document = await JsonDocument.ParseAsync(fileStream);

return document.RootElement.GetProperty("version").GetString();
}

public async Task RunBuild(string feature)
public async Task RunBuild(Func<ArgumentsBuilder, ArgumentsBuilder> configure)
{
await Cli.Wrap("dotnet")
.WithArguments(args => args
.Add("run")
.Add("--project")
.Add("/workspaces/devcontainers/build")
.Add("Version")
.Add("--feature")
.Add(feature)
.WithArguments(args => configure(args
.Add("run")
.Add("--project")
.Add("/workspaces/devcontainers/build"))
.Add("--no-logo"))
.WithStandardOutputPipe(PipeTarget.ToDelegate(Console.WriteLine))
.ExecuteAsync();
}

public async Task RunCreateReleaseCommitTarget(Feature feature)
{
await RunBuild(args => args
.Add("--target")
.Add("CreateVersionChangeCommit")
.Add("--feature")
.Add(feature));
}

public async Task RunVersionTarget(Feature feature)
{
await RunBuild(args => args
.Add("Version")
.Add("--feature")
.Add(feature));
}

public async Task Commit(
string path,
string message)
CommitMessage message,
string path)
{
await Cli.Wrap("git")
.WithArguments(args => args
Expand All @@ -173,12 +192,10 @@ await Cli.Wrap("git")
.Add(message))
.WithStandardOutputPipe(PipeTarget.ToDelegate(Console.WriteLine))
.ExecuteAsync();

this.commitsCount++;
}

public async Task AddGitTag(
string tag,
Tag tag,
string commit = "HEAD")
{
await Cli.Wrap("git")
Expand All @@ -191,7 +208,7 @@ await Cli.Wrap("git")
this.tags.Add(tag);
}

public async Task DeleteGitTags(IReadOnlyCollection<string> tags)
public async Task DeleteGitTags(IReadOnlyCollection<Tag> tags)
{
if (tags.Count is 0)
{
Expand All @@ -202,24 +219,99 @@ await Cli.Wrap("git")
.WithArguments(args => args
.Add("tag")
.Add("--delete")
.Add(tags))
.Add(tags.Select(x => x.ToString())))
.WithStandardOutputPipe(PipeTarget.ToDelegate(Console.WriteLine))
.ExecuteAsync();
}

public async Task<string> GetLatestCommitMessage()
{
var commitMessage = string.Empty;

await Cli.Wrap("git")
.WithArguments(args => args
.Add("rev-list")
.Add("HEAD")
.Add("--pretty=%s")
.Add("--no-commit-header")
.Add("-n1"))
.WithStandardOutputPipe(PipeTarget.ToDelegate(x => commitMessage = x))
.ExecuteAsync();

return commitMessage;
}

public async Task<string> GetLatestTag(string feature)
{
var tag = string.Empty;

var result = await Cli.Wrap("git")
.WithArguments(args => args
.Add("describe")
.Add("--abbrev=0")
.Add("--tags")
.Add("--match")
.Add($"feature_{feature}*"))
.WithStandardOutputPipe(PipeTarget.ToDelegate(x => tag = x))
.ExecuteAsync();

return tag;
}

public async Task<List<string>> GetModifiedFilesLatestCommit(
string commit = "HEAD")
{
var modifiedFiles = new List<string>();

await Cli.Wrap("git")
.WithArguments(args => args
.Add("diff-tree")
.Add("--no-commit-id")
.Add("--name-only")
.Add("-r")
.Add(commit))
.WithStandardOutputPipe(PipeTarget.ToDelegate(modifiedFiles.Add))
.ExecuteAsync();

return modifiedFiles;
}
}

public static class EnumerableExtenssions
public static class FeatureExtenssions
{
public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
public static Tag GetTag(this Feature feature) => new($"feature_{feature}");

public static AbsolutePath GetFeatureRoot(
this Feature feature,
AbsolutePath projectRoot) => projectRoot
/ "features"
/ "src"
/ feature;

public static AbsolutePath GetFeatureConfig(
this Feature featureName,
AbsolutePath projectRoot)
=> featureName.GetFeatureRoot(projectRoot)
/ "devcontainer-feature.json";

public static string GetRelativePathToConfig(this Feature feature)
=> Path.Combine("features", "src", feature, "devcontainer-feature.json");

public static async Task<string?> GetVersion(
this Feature feature,
AbsolutePath projectRoot)
{
foreach (var item in items)
{
action(item);
}
var featureConfig = feature.GetFeatureConfig(projectRoot);
using var fileStream = File.OpenRead(featureConfig);
var document = await JsonDocument.ParseAsync(fileStream);

return document.RootElement.GetProperty("version").GetString();
}

public static void ForEach<T, TReturn>(
this IEnumerable<T> items,
Func<T, TReturn> action)
=> items.ForEach(x => { action(x); });
public static void CreateTempFile(
this Feature feature,
AbsolutePath root)
{
using var _ = File.Create(feature.GetFeatureRoot(root) / $"tmp_{Guid.NewGuid():N}");
}
}
Loading
Loading