Skip to content

Commit 6d00b42

Browse files
authored
Merge pull request #165 from ap0llo/add-gitlab-ci-module
Add support for GitLab CI
2 parents 2597531 + 991e987 commit 6d00b42

7 files changed

Lines changed: 172 additions & 0 deletions

File tree

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ Currently this module supports:
3939
4040
- Log folding for the Cake build and for individual tasks
4141

42+
### GitLab CI
43+
44+
- Add colored output for Cake log messages in the GitLab pipeline output window
45+
4246
## Usage
4347

4448
Each build system's functionality resides in its own module, with `Cake.Module.Shared` used for shared types. Each module will conditionally register itself, meaning they will only be loaded in their respective CI environments. This means all modules can be deployed with a single codebase without interference.
@@ -81,6 +85,7 @@ public static int Main(string[] args)
8185
.UseModule<MyGetModule>()
8286
.UseModule<TravisCIModule>()
8387
.UseModule<TeamCityModule>()
88+
.UseModule<GitLabCIModule>()
8489
// continue with the "normal" setup of the CakeHost
8590
.UseContext<BuildContext>()
8691
.Run(args);

src/Cake.BuildSystems.Module.sln

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cake.BuildSystems.Module",
2525
EndProject
2626
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cake.GitHubActions.Module", "Cake.GitHubActions.Module\Cake.GitHubActions.Module.csproj", "{A6BAA454-179C-422C-A954-38852265722F}"
2727
EndProject
28+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cake.GitLabCI.Module", "Cake.GitLabCI.Module\Cake.GitLabCI.Module.csproj", "{DA6236E5-E4B3-42B4-BB3D-69CE06DAB85B}"
29+
EndProject
2830
Global
2931
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3032
Debug|Any CPU = Debug|Any CPU
@@ -115,6 +117,18 @@ Global
115117
{A6BAA454-179C-422C-A954-38852265722F}.Release|x64.Build.0 = Release|Any CPU
116118
{A6BAA454-179C-422C-A954-38852265722F}.Release|x86.ActiveCfg = Release|Any CPU
117119
{A6BAA454-179C-422C-A954-38852265722F}.Release|x86.Build.0 = Release|Any CPU
120+
{DA6236E5-E4B3-42B4-BB3D-69CE06DAB85B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
121+
{DA6236E5-E4B3-42B4-BB3D-69CE06DAB85B}.Debug|Any CPU.Build.0 = Debug|Any CPU
122+
{DA6236E5-E4B3-42B4-BB3D-69CE06DAB85B}.Debug|x64.ActiveCfg = Debug|Any CPU
123+
{DA6236E5-E4B3-42B4-BB3D-69CE06DAB85B}.Debug|x64.Build.0 = Debug|Any CPU
124+
{DA6236E5-E4B3-42B4-BB3D-69CE06DAB85B}.Debug|x86.ActiveCfg = Debug|Any CPU
125+
{DA6236E5-E4B3-42B4-BB3D-69CE06DAB85B}.Debug|x86.Build.0 = Debug|Any CPU
126+
{DA6236E5-E4B3-42B4-BB3D-69CE06DAB85B}.Release|Any CPU.ActiveCfg = Release|Any CPU
127+
{DA6236E5-E4B3-42B4-BB3D-69CE06DAB85B}.Release|Any CPU.Build.0 = Release|Any CPU
128+
{DA6236E5-E4B3-42B4-BB3D-69CE06DAB85B}.Release|x64.ActiveCfg = Release|Any CPU
129+
{DA6236E5-E4B3-42B4-BB3D-69CE06DAB85B}.Release|x64.Build.0 = Release|Any CPU
130+
{DA6236E5-E4B3-42B4-BB3D-69CE06DAB85B}.Release|x86.ActiveCfg = Release|Any CPU
131+
{DA6236E5-E4B3-42B4-BB3D-69CE06DAB85B}.Release|x86.Build.0 = Release|Any CPU
118132
EndGlobalSection
119133
GlobalSection(SolutionProperties) = preSolution
120134
HideSolutionNode = FALSE

src/Cake.BuildSystems.Module/Cake.BuildSystems.Module.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@
4646
<ProjectReference Include="..\Cake.GitHubActions.Module\Cake.GitHubActions.Module.csproj">
4747
<PrivateAssets>all</PrivateAssets>
4848
</ProjectReference>
49+
<ProjectReference Include="..\Cake.GitLabCI.Module\Cake.GitLabCI.Module.csproj">
50+
<PrivateAssets>all</PrivateAssets>
51+
</ProjectReference>
4952
</ItemGroup>
5053

5154
<ItemGroup>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
namespace Cake.AzurePipelines.Module
2+
{
3+
internal static class AnsiEscapeCodes
4+
{
5+
public static readonly string Reset = string.Format(FORMAT, 0);
6+
public static readonly string ForegroundWhite = string.Format(FORMAT, 97);
7+
public static readonly string ForegroundYellow = string.Format(FORMAT, 33);
8+
public static readonly string ForegroundLightGray = string.Format(FORMAT, 37);
9+
public static readonly string ForegroundDarkGray = string.Format(FORMAT, 90);
10+
public static readonly string BackgroundMagenta = string.Format(FORMAT, 45);
11+
public static readonly string BackgroundRed = string.Format(FORMAT, 41);
12+
13+
private const string FORMAT = "\u001B[{0}m";
14+
}
15+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net6.0</TargetFramework>
5+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
6+
<AssemblyName>Cake.GitLabCI.Module</AssemblyName>
7+
<IsPackable>false</IsPackable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<ProjectReference Include="..\Cake.Module.Shared\Cake.Module.Shared.csproj" />
12+
</ItemGroup>
13+
14+
<ItemGroup>
15+
<PackageReference Include="Cake.Core" Version="4.0.0" PrivateAssets="All" />
16+
<PackageReference Include="Cake.Common" Version="4.0.0" PrivateAssets="All" />
17+
<PackageReference Include="JetBrains.Annotations" Version="2023.3.0" PrivateAssets="All" />
18+
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0">
19+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
20+
<PrivateAssets>all</PrivateAssets>
21+
</PackageReference>
22+
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
23+
<PrivateAssets>all</PrivateAssets>
24+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
25+
</PackageReference>
26+
</ItemGroup>
27+
</Project>
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
using Cake.Core;
5+
using Cake.Core.Diagnostics;
6+
7+
using JetBrains.Annotations;
8+
9+
namespace Cake.AzurePipelines.Module
10+
{
11+
/// <summary>
12+
/// <see cref="ICakeLog"/> implementation for GitLab CI.
13+
/// </summary>
14+
[UsedImplicitly]
15+
public class GitLabCILog : ICakeLog
16+
{
17+
private readonly ICakeLog _cakeLogImplementation;
18+
private readonly IConsole _console;
19+
20+
// Define the escape sequenes to make GitLab show colored messages
21+
// For reference, see https://docs.gitlab.com/ee/ci/yaml/script.html#add-color-codes-to-script-output
22+
// For the colors, match the colors used by Cake, see https://github.com/cake-build/cake/blob/ed612029b92f5da2b6cbdfe295c62e6b99a2963d/src/Cake.Core/Diagnostics/Console/ConsolePalette.cs#L34C17-L34C17
23+
private readonly Dictionary<LogLevel, string> _escapeSequences = new Dictionary<LogLevel, string>()
24+
{
25+
{ LogLevel.Fatal, $"{AnsiEscapeCodes.BackgroundMagenta}{AnsiEscapeCodes.ForegroundWhite}" },
26+
{ LogLevel.Error, $"{AnsiEscapeCodes.BackgroundRed}{AnsiEscapeCodes.ForegroundWhite}" },
27+
{ LogLevel.Warning, AnsiEscapeCodes.ForegroundYellow },
28+
{ LogLevel.Verbose, AnsiEscapeCodes.ForegroundLightGray },
29+
{ LogLevel.Debug, AnsiEscapeCodes.ForegroundDarkGray },
30+
};
31+
32+
/// <summary>
33+
/// Initializes a new instance of the <see cref="GitLabCILog"/> class.
34+
/// </summary>
35+
/// <param name="console">Implementation of <see cref="IConsole"/>.</param>
36+
/// <param name="verbosity">Default <see cref="Verbosity"/>.</param>
37+
public GitLabCILog(IConsole console, Verbosity verbosity = Verbosity.Normal)
38+
{
39+
_cakeLogImplementation = new CakeBuildLog(console, verbosity);
40+
_console = console;
41+
}
42+
43+
/// <inheritdoc />
44+
public Verbosity Verbosity
45+
{
46+
get { return _cakeLogImplementation.Verbosity; }
47+
set { _cakeLogImplementation.Verbosity = value; }
48+
}
49+
50+
/// <inheritdoc />
51+
public void Write(Verbosity verbosity, LogLevel level, string format, params object[] args)
52+
{
53+
if (!StringComparer.OrdinalIgnoreCase.Equals(Environment.GetEnvironmentVariable("CI_SERVER"), "yes"))
54+
{
55+
_cakeLogImplementation.Write(verbosity, level, format, args);
56+
}
57+
58+
if (verbosity > Verbosity)
59+
{
60+
return;
61+
}
62+
63+
string message;
64+
if (_escapeSequences.TryGetValue(level, out var sequence))
65+
{
66+
message = $"{sequence}{level}: {string.Format(format, args)}{AnsiEscapeCodes.Reset}";
67+
}
68+
else
69+
{
70+
message = $"{level}: {string.Format(format, args)}";
71+
}
72+
73+
if (level > LogLevel.Error)
74+
{
75+
_console.WriteLine(message);
76+
}
77+
else
78+
{
79+
_console.WriteErrorLine(message);
80+
}
81+
}
82+
}
83+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
3+
using Cake.Core.Annotations;
4+
using Cake.Core.Composition;
5+
using Cake.Core.Diagnostics;
6+
7+
[assembly: CakeModule(typeof(Cake.AzurePipelines.Module.GitLabCIModule))]
8+
9+
namespace Cake.AzurePipelines.Module
10+
{
11+
/// <summary>
12+
/// <see cref="ICakeModule"/> implementation for GitLab CI.
13+
/// </summary>
14+
public class GitLabCIModule : ICakeModule
15+
{
16+
/// <inheritdoc cref="ICakeModule.Register"/>
17+
public void Register(ICakeContainerRegistrar registrar)
18+
{
19+
if (StringComparer.OrdinalIgnoreCase.Equals(Environment.GetEnvironmentVariable("CI_SERVER"), "yes"))
20+
{
21+
registrar.RegisterType<GitLabCILog>().As<ICakeLog>().Singleton();
22+
}
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)