Skip to content

Commit 27048cd

Browse files
committed
feat: add C# SDK CI/CD integration, example app, and documentation
- Add apps/csharp example application - Add C# to CI pipeline (ci/src/pipeline.ts) and release pipeline (ci/src/release.ts) - Add NUGET_API_KEY for NuGet publishing - Add DocFX documentation setup (docfx.json, filterConfig.yml, index.md, toc.yml) - Add WaitStepTests.cs for complete test coverage - Add install, docs:build, docs:serve targets to sdk/csharp/project.json - Update .gitignore for C# build artifacts (bin/, obj/) Amp-Thread-ID: https://ampcode.com/threads/T-019ba0f4-7bb7-701a-a467-9a5f507df553
1 parent bc8a400 commit 27048cd

File tree

14 files changed

+418
-14
lines changed

14 files changed

+418
-14
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,7 @@ Gemfile.lock
2626
Thumbs.db
2727
.vscode
2828
.zed
29+
30+
# C# build artifacts
31+
bin/
32+
obj/

apps/csharp/App.csproj

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
</PropertyGroup>
7+
<ItemGroup>
8+
<ProjectReference Include="../../sdk/csharp/src/Buildkite.Sdk/Buildkite.Sdk.csproj" />
9+
</ItemGroup>
10+
</Project>

apps/csharp/Program.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System;
2+
using System.IO;
3+
using Buildkite.Sdk;
4+
using Buildkite.Sdk.Schema;
5+
6+
var pipeline = new Pipeline();
7+
8+
pipeline.AddStep(new CommandStep
9+
{
10+
Label = "some-label",
11+
Command = "echo 'Hello, world!'"
12+
});
13+
14+
Directory.CreateDirectory("../../out/apps/csharp");
15+
16+
var json = pipeline.ToJson();
17+
File.WriteAllText("../../out/apps/csharp/pipeline.json", json);
18+
19+
var yaml = pipeline.ToYaml();
20+
File.WriteAllText("../../out/apps/csharp/pipeline.yaml", yaml);

apps/csharp/project.json

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{
2+
"name": "app-csharp",
3+
"$schema": "../../node_modules/nx/schemas/project-schema.json",
4+
"sourceRoot": "apps/csharp",
5+
"projectType": "application",
6+
"tags": [],
7+
"targets": {
8+
"install": {
9+
"executor": "nx:run-commands",
10+
"options": {
11+
"commands": ["dotnet restore"],
12+
"cwd": "apps/csharp"
13+
}
14+
},
15+
"clean": {
16+
"executor": "nx:run-commands",
17+
"options": {
18+
"commands": ["dotnet clean", "rimraf bin", "rimraf obj"],
19+
"cwd": "apps/csharp"
20+
},
21+
"cache": false
22+
},
23+
"format": {
24+
"executor": "nx:run-commands",
25+
"options": {
26+
"commands": ["dotnet format"],
27+
"cwd": "apps/csharp"
28+
},
29+
"cache": false
30+
},
31+
"build": {
32+
"executor": "nx:run-commands",
33+
"outputs": ["{workspaceRoot}/dist/apps/csharp"],
34+
"options": {
35+
"commands": [
36+
"rimraf ../../dist/apps/csharp",
37+
"mkdir -p ../../dist/apps/csharp",
38+
"dotnet build --configuration Release --output ../../dist/apps/csharp"
39+
],
40+
"cwd": "apps/csharp",
41+
"parallel": false
42+
},
43+
"cache": false
44+
},
45+
"run": {
46+
"executor": "nx:run-commands",
47+
"dependsOn": ["build"],
48+
"options": {
49+
"commands": ["dotnet run"],
50+
"cwd": "apps/csharp"
51+
}
52+
},
53+
"test": {
54+
"options": {
55+
"passWithNoTests": true
56+
}
57+
}
58+
}
59+
}

ci/src/pipeline.ts

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,14 @@ const languageTargets: Target[] = [
116116
appTarget: "app-ruby",
117117
versions: languageVersions["ruby"],
118118
},
119+
{
120+
icon: ":csharp:",
121+
label: "C#",
122+
key: "csharp",
123+
sdkTarget: "sdk-csharp",
124+
appTarget: "app-csharp",
125+
versions: [], // C# doesn't use mise for version management
126+
},
119127
];
120128

121129
function generateAppCommands(key: string, appTarget: string) {
@@ -124,6 +132,15 @@ function generateAppCommands(key: string, appTarget: string) {
124132
language = "node";
125133
}
126134

135+
// C# uses dotnet directly, not mise
136+
if (key === "csharp") {
137+
return [
138+
"mise trust",
139+
`nx install ${appTarget}`,
140+
`nx run ${appTarget}:run`,
141+
];
142+
}
143+
127144
let appInstallCommand = `mise exec ${language}@{{matrix}} -- nx install ${appTarget}`;
128145
if (language === "python") {
129146
appInstallCommand = `mise exec ${language}@{{matrix}} -- pip install --no-cache-dir uv black && nx install ${appTarget}`;
@@ -196,17 +213,42 @@ languageTargets.forEach((target) => {
196213
`nx run ${target.sdkTarget}:docs:build`,
197214
],
198215
},
199-
{
200-
label: ":lab_coat: Apps",
201-
key: `${target.key}-apps`,
202-
depends_on: [`${target.key}-test`, `${target.key}-build`],
203-
plugins: languagePlugins,
204-
commands: generateAppCommands(target.key, target.appTarget),
205-
matrix: target.versions,
206-
env: {
207-
MISE_NODE_VERIFY: false,
208-
},
209-
},
216+
// Only add matrix if there are versions to test
217+
...(target.versions.length > 0
218+
? [
219+
{
220+
label: ":lab_coat: Apps",
221+
key: `${target.key}-apps`,
222+
depends_on: [
223+
`${target.key}-test`,
224+
`${target.key}-build`,
225+
],
226+
plugins: languagePlugins,
227+
commands: generateAppCommands(
228+
target.key,
229+
target.appTarget
230+
),
231+
matrix: target.versions,
232+
env: {
233+
MISE_NODE_VERIFY: false,
234+
},
235+
},
236+
]
237+
: [
238+
{
239+
label: ":lab_coat: Apps",
240+
key: `${target.key}-apps`,
241+
depends_on: [
242+
`${target.key}-test`,
243+
`${target.key}-build`,
244+
],
245+
plugins: languagePlugins,
246+
commands: generateAppCommands(
247+
target.key,
248+
target.appTarget
249+
),
250+
},
251+
]),
210252
],
211253
});
212254
});

ci/src/release.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ const plugins = [
1111
"GITHUB_TOKEN",
1212
"NPM_TOKEN",
1313
"PYPI_TOKEN",
14-
"GEM_HOST_API_KEY"
14+
"GEM_HOST_API_KEY",
15+
"NUGET_API_KEY"
1516
]
1617
}},
1718
{ "rubygems-oidc#v0.2.0": { role: "rg_oidc_akr_emf87k6zphtb7x7adyrk" } },
@@ -22,7 +23,8 @@ const plugins = [
2223
parameters: {
2324
NPM_TOKEN: "/prod/buildkite-sdk/npm-token",
2425
PYPI_TOKEN: "/prod/buildkite-sdk/pypi-token",
25-
GITHUB_TOKEN: "/prod/buildkite-sdk/github-token"
26+
GITHUB_TOKEN: "/prod/buildkite-sdk/github-token",
27+
NUGET_API_KEY: "/prod/buildkite-sdk/nuget-api-key"
2628
}
2729
}}
2830
]
@@ -79,6 +81,13 @@ const languageTargets = [
7981
key: "ruby",
8082
sdkLabel: "sdk-ruby",
8183
appLabel: "app-ruby"
84+
},
85+
{
86+
icon: ":csharp:",
87+
label: "C#",
88+
key: "csharp",
89+
sdkLabel: "sdk-csharp",
90+
appLabel: "app-csharp"
8291
}
8392
]
8493

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"version": 1,
3+
"isRoot": true,
4+
"tools": {
5+
"docfx": {
6+
"version": "2.75.3",
7+
"commands": [
8+
"docfx"
9+
]
10+
}
11+
}
12+
}

sdk/csharp/docfx.json

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"metadata": [
3+
{
4+
"src": [
5+
{
6+
"files": [
7+
"src/Buildkite.Sdk/Buildkite.Sdk.csproj"
8+
]
9+
}
10+
],
11+
"dest": "api",
12+
"filter": "filterConfig.yml",
13+
"allowCompilationErrors": false,
14+
"disableGitFeatures": false,
15+
"disableDefaultFilter": false
16+
}
17+
],
18+
"build": {
19+
"content": [
20+
{
21+
"files": [
22+
"api/**.yml",
23+
"api/index.md"
24+
]
25+
},
26+
{
27+
"files": [
28+
"index.md",
29+
"README.md",
30+
"toc.yml",
31+
"*.md"
32+
]
33+
}
34+
],
35+
"resource": [
36+
{
37+
"files": [
38+
"images/**"
39+
]
40+
}
41+
],
42+
"dest": "../../dist/docs/csharp",
43+
"globalMetadataFiles": [],
44+
"fileMetadataFiles": [],
45+
"globalMetadata": {
46+
"_appTitle": "Buildkite SDK for .NET",
47+
"_appFooter": "Buildkite SDK for .NET Documentation"
48+
},
49+
"template": [
50+
"default"
51+
],
52+
"postProcessors": [],
53+
"keepFileLink": false,
54+
"disableGitFeatures": false
55+
}
56+
}

sdk/csharp/filterConfig.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
apiRules:
2+
- include:
3+
uidRegex: ^Buildkite\.Sdk\.Pipeline$
4+
- include:
5+
uidRegex: ^Buildkite\.Sdk\.Environment$
6+
- include:
7+
uidRegex: ^Buildkite\.Sdk\.Schema\.CommandStep$
8+
- include:
9+
uidRegex: ^Buildkite\.Sdk\.Schema\.BlockStep$
10+
- include:
11+
uidRegex: ^Buildkite\.Sdk\.Schema\.TriggerStep$
12+
- include:
13+
uidRegex: ^Buildkite\.Sdk\.Schema\.InputStep$
14+
- include:
15+
uidRegex: ^Buildkite\.Sdk\.Schema\.GroupStep$
16+
- include:
17+
uidRegex: ^Buildkite\.Sdk\.Schema\.WaitStep$
18+
- exclude:
19+
uidRegex: .*

0 commit comments

Comments
 (0)