Repository: microsoft/kiota (csharp)

Issue:
Add a generated code comment to go files
### Is your feature request related to a problem? Please describe the problem.

A lot of golang third party tools exclude files from processing when they are detected as generated. This is usually done by looking at the first line for something like `// Code generated by xxxx - DO NOT EDIT.`

For example `gofumpt`:
https://github.com/mvdan/gofumpt/blob/2d5c20d3444ebe466795b22784ec1e498ebc201f/gofmt.go#L117

Currently those tools modify and/or process the generated kiota clients as they can not determine that it is generated code. In the example of `gofumpt` this results in the generated code being reformated, changed again on a kiota generate and so on.

### Client library/SDK language

Go

### Describe the solution you'd like

My feature request is to add this line to all golang generated code so it's clear that this code is autogenerated and should not be touched by tools like linters and formatters. VSCode also shows a warning that this file should not be edited when it's opened.

So the first line of every generated go file should be
```
// Code generated by kiota - DO NOT EDIT.
```

You could also include the version of kiota that generated this code, but this tends to get messy when the tool version changes but the generated output does not.

### Additional context

Example comment from `go-templ` for example:
```
// Code generated by templ - DO NOT EDIT.
```

Example comment from `mockery`:
```
// Code generated by mockery. DO NOT EDIT.
```

Example comment from `stringer`:
```
// Code generated by "stringer -type=XXXXType"; DO NOT EDIT.
```

Pull request:
This fixes #6363

This PR ensure that every generated golang file has a generated by comment on top.

The comment:
```golang
// Code generated by Microsoft Kiota - DO NOT EDIT.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
```

To test:
```bash
dotnet build && ./src/kiota/bin/Debug/net9.0/kiota generate --openapi https://aka.ms/graph/v1.0/openapi.yaml --output ./golang-test --language go --exclude-backward-compatible --clean-output -n test -c GraphServiceClient -i '/groups/getByIds#POST'
```
Every `.go` file in the `golang-test` folder should now have the comment on top,

Happy about feedback!

PS: I also updated the devcontainer file as it seems like it was outdated regarding dotnet9.0. I can also remove this from the PR if it's not wanted.

Patch:
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index 51e30c6552..dbf51b21c6 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -1,6 +1,6 @@
 # See here for image contents: https://github.com/microsoft/vscode-dev-containers/blob/v0.245.2/containers/dotnet/.devcontainer/Dockerfile
 
-ARG VARIANT="8.0-bookworm-slim"
+ARG VARIANT="9.0-bookworm-slim"
 FROM mcr.microsoft.com/vscode/devcontainers/dotnet:${VARIANT}
 
 # [Choice] Node.js version: none, lts/*, 16, 14, 12, 10
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 158465dd6d..70eb569548 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -3,7 +3,7 @@
   "build": {
     "dockerfile": "Dockerfile",
     "args": {
-      "VARIANT": "8.0",
+      "VARIANT": "9.0",
       "NODE_VERSION": "20"
     }
   },
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0dc4050c46..673d0de4f0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,8 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Added
 
+- Added a comment on top of every golang file to indicate the file is machine generated so it can be excluded from various tools. [#6363](https://github.com/microsoft/kiota/issues/6363)
+
 ### Changed
-- Fixed a bug with creating the correct runtime with auth using http bearer security scheme or when root auth is set. [#6357](https://github.com/microsoft/kiota/issues/6357)   
+
+- Fixed a bug with creating the correct runtime with auth using http bearer security scheme or when root auth is set. [#6357](https://github.com/microsoft/kiota/issues/6357)
 
 ## [1.24.3] - 2025-03-26
 
diff --git a/src/Kiota.Builder/Writers/Go/CodeEnumWriter.cs b/src/Kiota.Builder/Writers/Go/CodeEnumWriter.cs
index 2326c74196..ba6e68414c 100644
--- a/src/Kiota.Builder/Writers/Go/CodeEnumWriter.cs
+++ b/src/Kiota.Builder/Writers/Go/CodeEnumWriter.cs
@@ -14,7 +14,11 @@ public override void WriteCodeElement(CodeEnum codeElement, LanguageWriter write
         ArgumentNullException.ThrowIfNull(writer);
         if (!codeElement.Options.Any()) return;
         if (codeElement.Parent is CodeNamespace ns)
+        {
+            // always add a comment to the top of the file to indicate it's generated
+            conventions.WriteGeneratorComment(writer);
             writer.WriteLine($"package {ns.Name.GetLastNamespaceSegment().Replace("-", string.Empty, StringComparison.OrdinalIgnoreCase)}");
+        }
 
         var usings = codeElement.Usings.OrderBy(static x => x.Name, StringComparer.OrdinalIgnoreCase).ToArray();
         if (usings.Length > 0)
diff --git a/src/Kiota.Builder/Writers/Go/CodeFileDeclarationWriter.cs b/src/Kiota.Builder/Writers/Go/CodeFileDeclarationWriter.cs
index 998f19ec6e..dadac0950e 100644
--- a/src/Kiota.Builder/Writers/Go/CodeFileDeclarationWriter.cs
+++ b/src/Kiota.Builder/Writers/Go/CodeFileDeclarationWriter.cs
@@ -16,6 +16,8 @@ public override void WriteCodeElement(CodeFileDeclaration codeElement, LanguageW
         ArgumentNullException.ThrowIfNull(writer);
         if (codeElement.Parent is CodeFile cs && cs.Parent is CodeNamespace ns)
         {
+            // always add a comment to the top of the file to indicate it's generated
+            conventions.WriteGeneratorComment(writer);
             writer.WriteLine($"package {ns.Name.GetLastNamespaceSegment().Replace("-", string.Empty, StringComparison.OrdinalIgnoreCase)}");
             var importSegments = cs
                                 .AllUsingsFromChildElements
diff --git a/src/Kiota.Builder/Writers/Go/CodeProprietableBlockDeclarationWriter.cs b/src/Kiota.Builder/Writers/Go/CodeProprietableBlockDeclarationWriter.cs
index 0dee8faa7e..500c64daf7 100644
--- a/src/Kiota.Builder/Writers/Go/CodeProprietableBlockDeclarationWriter.cs
+++ b/src/Kiota.Builder/Writers/Go/CodeProprietableBlockDeclarationWriter.cs
@@ -16,6 +16,8 @@ public override void WriteCodeElement(T codeElement, LanguageWriter writer)
         ArgumentNullException.ThrowIfNull(writer);
         if (codeElement.Parent?.Parent is CodeNamespace ns)
         {
+            // always add a comment to the top of the file to indicate it's generated
+            conventions.WriteGeneratorComment(writer);
             writer.WriteLine($"package {ns.Name.GetLastNamespaceSegment().Replace("-", string.Empty, StringComparison.OrdinalIgnoreCase)}");
             var importSegments = codeElement
                                 .Usings
diff --git a/src/Kiota.Builder/Writers/Go/GoConventionService.cs b/src/Kiota.Builder/Writers/Go/GoConventionService.cs
index 284a85cb5b..7a297fe86d 100644
--- a/src/Kiota.Builder/Writers/Go/GoConventionService.cs
+++ b/src/Kiota.Builder/Writers/Go/GoConventionService.cs
@@ -183,6 +183,13 @@ public override bool WriteShortDescription(IDocumentedElement element, LanguageW
         WriteDescriptionItem($"{prefix}{description}{suffix}", writer);
         return true;
     }
+    public void WriteGeneratorComment(LanguageWriter writer)
+    {
+        ArgumentNullException.ThrowIfNull(writer);
+        writer.WriteLine($"{DocCommentPrefix}Code generated by Microsoft Kiota - DO NOT EDIT.");
+        writer.WriteLine($"{DocCommentPrefix}Changes may cause incorrect behavior and will be lost if the code is regenerated.");
+        writer.WriteLine(string.Empty);
+    }
     public void WriteDescriptionItem(string description, LanguageWriter writer)
     {
         ArgumentNullException.ThrowIfNull(writer);


Test patch:
diff --git a/tests/Kiota.Builder.Tests/Writers/Go/CodeClassDeclarationWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/Go/CodeClassDeclarationWriterTests.cs
index 546a7cf6fd..391326cd9d 100644
--- a/tests/Kiota.Builder.Tests/Writers/Go/CodeClassDeclarationWriterTests.cs
+++ b/tests/Kiota.Builder.Tests/Writers/Go/CodeClassDeclarationWriterTests.cs
@@ -41,6 +41,7 @@ public void WritesSimpleDeclaration()
     {
         codeElementWriter.WriteCodeElement(parentClass.StartBlock, writer);
         var result = tw.ToString();
+        Assert.Contains("DO NOT EDIT", result);
         Assert.Contains("type", result);
         Assert.Contains("struct", result);
         Assert.Contains("package", result);
diff --git a/tests/Kiota.Builder.Tests/Writers/Go/CodeEnumWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/Go/CodeEnumWriterTests.cs
index 39f8ce54af..d51e54412f 100644
--- a/tests/Kiota.Builder.Tests/Writers/Go/CodeEnumWriterTests.cs
+++ b/tests/Kiota.Builder.Tests/Writers/Go/CodeEnumWriterTests.cs
@@ -122,6 +122,23 @@ public void WritesUsing()
         Assert.Contains("using1", result);
     }
     [Fact]
+    public void WritesGenerateCodeComment()
+    {
+        var option = new CodeEnumOption
+        {
+            Documentation = new()
+            {
+            },
+            Name = "generated1",
+        };
+        currentEnum.AddOption(option);
+        writer.Write(currentEnum);
+        var result = tw.ToString();
+        Assert.Contains(Environment.NewLine, result);
+        var firstline = result[0..^result.IndexOf(Environment.NewLine)];
+        Assert.Contains("DO NOT EDIT", firstline);
+    }
+    [Fact]
     public void WritesEnumOptionDescription()
     {
         var option = new CodeEnumOption
diff --git a/tests/Kiota.Builder.Tests/Writers/Go/CodeInterfaceDeclarationWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/Go/CodeInterfaceDeclarationWriterTests.cs
index 2941424878..e55beb5892 100644
--- a/tests/Kiota.Builder.Tests/Writers/Go/CodeInterfaceDeclarationWriterTests.cs
+++ b/tests/Kiota.Builder.Tests/Writers/Go/CodeInterfaceDeclarationWriterTests.cs
@@ -42,6 +42,7 @@ public void WritesSimpleDeclaration()
     {
         codeElementWriter.WriteCodeElement(parentInterface.StartBlock, writer);
         var result = tw.ToString();
+        Assert.Contains("DO NOT EDIT", result);
         Assert.Contains("type", result);
         Assert.Contains("interface", result);
         Assert.DoesNotContain("struct", result);