Skip to content

Commit dd154c7

Browse files
authored
Add Documentation Assembler GitHub Action (#501)
Introduce a new GitHub Action named "Documentation Assembler" to run specified assembler commands using a Docker image.
1 parent 53874f8 commit dd154c7

File tree

5 files changed

+123
-72
lines changed

5 files changed

+123
-72
lines changed

actions/assembler/action.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: 'Documentation Assembler'
2+
description: 'Run the documenation assembler commands'
3+
4+
branding:
5+
icon: 'filter'
6+
color: 'red'
7+
8+
inputs:
9+
command:
10+
description: 'The assembler command to run'
11+
required: true
12+
13+
runs:
14+
using: 'docker'
15+
image: "docker://ghcr.io/elastic/docs-assembler:edge"

docs-builder.sln

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "authoring", "tests\authorin
4848
EndProject
4949
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elastic.Markdown.Refactor", "src\Elastic.Markdown.Refactor\Elastic.Markdown.Refactor.csproj", "{7D36DDDA-9E0B-4D2C-8033-5D62FF8B6166}"
5050
EndProject
51+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "assembler", "assembler", "{CFEE9FAD-9E0C-4C0E-A0C2-B97D594C14B5}"
52+
ProjectSection(SolutionItems) = preProject
53+
actions\assembler\action.yml = actions\assembler\action.yml
54+
EndProjectSection
55+
EndProject
5156
Global
5257
GlobalSection(SolutionConfigurationPlatforms) = preSolution
5358
Debug|Any CPU = Debug|Any CPU
@@ -100,5 +105,6 @@ Global
100105
{28350800-B44B-479B-86E2-1D39E321C0B4} = {BE6011CC-1200-4957-B01F-FCCA10C5CF5A}
101106
{018F959E-824B-4664-B345-066784478D24} = {67B576EE-02FA-4F9B-94BC-3630BC09ECE5}
102107
{7D36DDDA-9E0B-4D2C-8033-5D62FF8B6166} = {BE6011CC-1200-4957-B01F-FCCA10C5CF5A}
108+
{CFEE9FAD-9E0C-4C0E-A0C2-B97D594C14B5} = {245023D2-D3CA-47B9-831D-DAB91A2FFDC7}
103109
EndGlobalSection
104110
EndGlobal

src/docs-assembler/Cli/LinkCommands.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ private void AssignOutputLogger()
2525
/// Create an index.json file from all discovered links.json files in our S3 bucket
2626
/// </summary>
2727
/// <param name="ctx"></param>
28-
[Command("links create-index")]
28+
[Command("create-index")]
2929
public async Task CreateLinkIndex(Cancel ctx = default)
3030
{
3131
AssignOutputLogger();
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using System.Collections.Concurrent;
6+
using System.Diagnostics;
7+
using ConsoleAppFramework;
8+
using Elastic.Markdown.IO;
9+
using Microsoft.Extensions.Logging;
10+
using ProcNet;
11+
using ProcNet.Std;
12+
13+
namespace Documentation.Assembler.Cli;
14+
15+
public class ConsoleLineHandler(string prefix) : IConsoleLineHandler
16+
{
17+
public void Handle(LineOut lineOut) => lineOut.CharsOrString(
18+
r => Console.Write(prefix + ": " + r),
19+
l => Console.WriteLine(prefix + ": " + l));
20+
21+
public void Handle(Exception e) { }
22+
}
23+
24+
internal class RepositoryCommands(ILoggerFactory logger)
25+
{
26+
private void AssignOutputLogger()
27+
{
28+
var log = logger.CreateLogger<Program>();
29+
ConsoleApp.Log = msg => log.LogInformation(msg);
30+
ConsoleApp.LogError = msg => log.LogError(msg);
31+
}
32+
33+
// would love to use libgit2 so there is no git dependency but
34+
// libgit2 is magnitudes slower to clone repositories https://github.com/libgit2/libgit2/issues/4674
35+
/// <summary> Clones all repositories </summary>
36+
/// <param name="ctx"></param>
37+
[Command("clone-all")]
38+
public async Task CloneAll(Cancel ctx = default)
39+
{
40+
var configFile = Path.Combine(Paths.Root.FullName, "src/docs-assembler/conf.yml");
41+
var config = AssemblyConfiguration.Deserialize(File.ReadAllText(configFile));
42+
43+
Console.WriteLine(config.Repositories.Count);
44+
var dict = new ConcurrentDictionary<string, Stopwatch>();
45+
await Parallel.ForEachAsync(config.Repositories,
46+
new ParallelOptions { CancellationToken = ctx, MaxDegreeOfParallelism = Environment.ProcessorCount / 4 }, async (kv, c) =>
47+
{
48+
await Task.Run(() =>
49+
{
50+
var name = kv.Key;
51+
var repository = kv.Value;
52+
var checkoutFolder = Path.Combine(Paths.Root.FullName, $".artifacts/assembly/{name}");
53+
54+
var sw = Stopwatch.StartNew();
55+
dict.AddOrUpdate(name, sw, (_, _) => sw);
56+
Console.WriteLine($"Checkout: {name}\t{repository}\t{checkoutFolder}");
57+
var branch = repository.Branch ?? "main";
58+
var args = new StartArguments(
59+
"git", "clone", repository.Origin, checkoutFolder, "--depth", "1"
60+
, "--single-branch", "--branch", branch
61+
);
62+
Proc.StartRedirected(args, new ConsoleLineHandler(name));
63+
sw.Stop();
64+
}, c);
65+
}).ConfigureAwait(false);
66+
67+
foreach (var kv in dict.OrderBy(kv => kv.Value.Elapsed))
68+
Console.WriteLine($"-> {kv.Key}\ttook: {kv.Value.Elapsed}");
69+
}
70+
71+
/// <summary> List all checked out repositories </summary>
72+
/// <param name="ctx"></param>
73+
[Command("list")]
74+
public async Task ListRepositories(Cancel ctx = default)
75+
{
76+
var assemblyPath = Path.Combine(Paths.Root.FullName, $".artifacts/assembly");
77+
var dir = new DirectoryInfo(assemblyPath);
78+
var dictionary = new Dictionary<string, string>();
79+
foreach (var d in dir.GetDirectories())
80+
{
81+
var checkoutFolder = Path.Combine(assemblyPath, d.Name);
82+
83+
var capture = Proc.Start(
84+
new StartArguments("git", "rev-parse", "--abbrev-ref", "HEAD") { WorkingDirectory = checkoutFolder }
85+
);
86+
dictionary.Add(d.Name, capture.ConsoleOut.FirstOrDefault()?.Line ?? "unknown");
87+
}
88+
89+
foreach (var kv in dictionary.OrderBy(kv => kv.Value))
90+
Console.WriteLine($"-> {kv.Key}\tbranch: {kv.Value}");
91+
92+
await Task.CompletedTask;
93+
}
94+
}

src/docs-assembler/Program.cs

Lines changed: 7 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Collections.Concurrent;
66
using System.Diagnostics;
77
using Actions.Core.Extensions;
8+
using Actions.Core.Services;
89
using ConsoleAppFramework;
910
using Documentation.Assembler;
1011
using Documentation.Assembler.Cli;
@@ -38,81 +39,16 @@
3839
await using var serviceProvider = services.BuildServiceProvider();
3940
ConsoleApp.ServiceProvider = serviceProvider;
4041

41-
4242
var app = ConsoleApp.Create();
4343
app.UseFilter<StopwatchFilter>();
4444
app.UseFilter<CatchExceptionFilter>();
4545

46-
app.Add<LinkCommands>();
47-
48-
// would love to use libgit2 so there is no git dependency but
49-
// libgit2 is magnitudes slower to clone repositories https://github.com/libgit2/libgit2/issues/4674
50-
app.Add("clone-all", async Task (CancellationToken ctx) =>
51-
{
52-
Console.WriteLine(config.Repositories.Count);
53-
var dict = new ConcurrentDictionary<string, Stopwatch>();
54-
await Parallel.ForEachAsync(config.Repositories, new ParallelOptions
55-
{
56-
CancellationToken = ctx,
57-
MaxDegreeOfParallelism = Environment.ProcessorCount / 4
58-
}, async (kv, c) =>
59-
{
60-
await Task.Run(() =>
61-
{
62-
var name = kv.Key;
63-
var repository = kv.Value;
64-
var checkoutFolder = Path.Combine(Paths.Root.FullName, $".artifacts/assembly/{name}");
46+
app.Add<LinkCommands>("link");
47+
app.Add<RepositoryCommands>("repo");
6548

66-
var sw = Stopwatch.StartNew();
67-
dict.AddOrUpdate(name, sw, (_, _) => sw);
68-
Console.WriteLine($"Checkout: {name}\t{repository}\t{checkoutFolder}");
69-
var branch = repository.Branch ?? "main";
70-
var args = new StartArguments(
71-
"git", "clone", repository.Origin, checkoutFolder, "--depth", "1"
72-
, "--single-branch", "--branch", branch
73-
);
74-
Proc.StartRedirected(args, new ConsoleLineHandler(name));
75-
sw.Stop();
76-
}, c);
77-
}).ConfigureAwait(false);
78-
79-
foreach (var kv in dict.OrderBy(kv => kv.Value.Elapsed))
80-
Console.WriteLine($"-> {kv.Key}\ttook: {kv.Value.Elapsed}");
81-
});
82-
app.Add("list", async Task (CancellationToken ctx) =>
83-
{
84-
85-
var assemblyPath = Path.Combine(Paths.Root.FullName, $".artifacts/assembly");
86-
var dir = new DirectoryInfo(assemblyPath);
87-
var dictionary = new Dictionary<string, string>();
88-
foreach (var d in dir.GetDirectories())
89-
{
90-
var checkoutFolder = Path.Combine(assemblyPath, d.Name);
91-
92-
var capture = Proc.Start(
93-
new StartArguments("git", "rev-parse", "--abbrev-ref", "HEAD")
94-
{
95-
WorkingDirectory = checkoutFolder
96-
}
97-
);
98-
dictionary.Add(d.Name, capture.ConsoleOut.FirstOrDefault()?.Line ?? "unknown");
99-
}
100-
foreach (var kv in dictionary.OrderBy(kv => kv.Value))
101-
Console.WriteLine($"-> {kv.Key}\tbranch: {kv.Value}");
102-
103-
await Task.CompletedTask;
104-
});
49+
var githubActions = ConsoleApp.ServiceProvider.GetService<ICoreService>();
50+
var command = githubActions?.GetInput("command");
51+
if (!string.IsNullOrEmpty(command))
52+
args = command.Split(' ');
10553

10654
await app.RunAsync(args);
107-
108-
namespace Documentation.Assembler
109-
{
110-
public class ConsoleLineHandler(string prefix) : IConsoleLineHandler
111-
{
112-
public void Handle(LineOut lineOut) => lineOut.CharsOrString(
113-
r => Console.Write(prefix + ": " + r),
114-
l => Console.WriteLine(prefix + ": " + l));
115-
116-
public void Handle(Exception e) { }
117-
}
118-
}

0 commit comments

Comments
 (0)