Skip to content

Commit 4542592

Browse files
chore: added build and release workflows
1 parent 59cb2b6 commit 4542592

14 files changed

Lines changed: 233 additions & 50 deletions

File tree

.github/workflows/build.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Build and Test
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
build-and-test:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Setup .NET
17+
uses: actions/setup-dotnet@v4
18+
with:
19+
dotnet-version: |
20+
8.0.x
21+
9.0.x
22+
10.0.x
23+
24+
- name: Restore
25+
run: dotnet restore
26+
27+
- name: Build
28+
run: dotnet build --configuration Release --no-restore
29+
30+
- name: Test
31+
run: dotnet test --test-modules tests/**/bin/Release/**/*.Tests.dll

.github/workflows/release.yml

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name: Release to NuGet
2+
3+
on:
4+
push:
5+
branches: [publish]
6+
pull_request:
7+
branches: [publish]
8+
workflow_dispatch:
9+
10+
jobs:
11+
check-version:
12+
if: github.event_name == 'pull_request'
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0
19+
20+
- name: Get PR version
21+
id: pr_version
22+
run: |
23+
PREFIX=$(grep -oP '(?<=<VersionPrefix>)[^<]+' Directory.Build.props)
24+
SUFFIX=$(grep -oP '(?<=<VersionSuffix>)[^<]+' Directory.Build.props || echo "")
25+
if [ -n "$SUFFIX" ]; then
26+
echo "version=$PREFIX-$SUFFIX" >> $GITHUB_OUTPUT
27+
else
28+
echo "version=$PREFIX" >> $GITHUB_OUTPUT
29+
fi
30+
31+
- name: Get base version
32+
id: base_version
33+
run: |
34+
git fetch origin ${{ github.base_ref }}
35+
git show origin/${{ github.base_ref }}:Directory.Build.props > base.props
36+
PREFIX=$(grep -oP '(?<=<VersionPrefix>)[^<]+' base.props || echo "")
37+
SUFFIX=$(grep -oP '(?<=<VersionSuffix>)[^<]+' base.props || echo "")
38+
if [ -n "$SUFFIX" ]; then
39+
echo "version=$PREFIX-$SUFFIX" >> $GITHUB_OUTPUT
40+
else
41+
echo "version=$PREFIX" >> $GITHUB_OUTPUT
42+
fi
43+
44+
- name: Check version changed
45+
run: |
46+
echo "PR version: ${{ steps.pr_version.outputs.version }}"
47+
echo "Base version: ${{ steps.base_version.outputs.version }}"
48+
if [ "${{ steps.pr_version.outputs.version }}" == "${{ steps.base_version.outputs.version }}" ]; then
49+
echo "::error::Version must be changed in Directory.Build.props before merging to publish branch"
50+
exit 1
51+
fi
52+
echo "Version changed from ${{ steps.base_version.outputs.version }} to ${{ steps.pr_version.outputs.version }}"
53+
54+
release:
55+
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
56+
runs-on: ubuntu-latest
57+
58+
steps:
59+
- uses: actions/checkout@v4
60+
61+
- name: Setup .NET
62+
uses: actions/setup-dotnet@v4
63+
with:
64+
dotnet-version: |
65+
8.0.x
66+
9.0.x
67+
10.0.x
68+
69+
- name: Restore
70+
run: dotnet restore
71+
72+
- name: Build
73+
run: dotnet build --configuration Release --no-restore
74+
75+
- name: Test
76+
run: dotnet test --test-modules tests/**/bin/Release/**/*.Tests.dll
77+
78+
- name: Pack
79+
run: dotnet pack --configuration Release --no-build -o ./nupkg
80+
81+
- name: Push to NuGet
82+
run: dotnet nuget push ./nupkg/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate

AzureFunctions.DisabledWhen.slnx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
11
<Solution>
22
<Folder Name="/src/">
3-
<Project Path="src/AzureFunctions.DisabledWhen/AzureFunctions.DisabledWhen.csproj" />
43
<Project Path="src/AzureFunctions.DisabledWhen.SourceGenerator/AzureFunctions.DisabledWhen.SourceGenerator.csproj" />
4+
<Project Path="src/AzureFunctions.DisabledWhen/AzureFunctions.DisabledWhen.csproj" />
55
</Folder>
66
<Folder Name="/tests/">
77
<File Path="tests/.editorconfig" />
88
<File Path="tests/Directory.Build.props" />
9-
<Project Path="tests/AzureFunctions.DisabledWhen.Tests/AzureFunctions.DisabledWhen.Tests.csproj" />
109
<Project Path="tests/AzureFunctions.DisabledWhen.SourceGenerator.Tests/AzureFunctions.DisabledWhen.SourceGenerator.Tests.csproj" />
11-
<Project Path="tests/AzureFunctions.DisabledWhen.TestHost/AzureFunctions.DisabledWhen.TestHost.csproj" />
10+
<Project Path="tests/AzureFunctions.DisabledWhen.Tests/AzureFunctions.DisabledWhen.Tests.csproj" />
1211
</Folder>
1312
<Folder Name="/root/">
1413
<File Path=".editorconfig" />
14+
<File Path=".github/workflows/build.yml" />
15+
<File Path=".github/workflows/release.yml" />
1516
<File Path=".gitignore" />
1617
<File Path="Directory.Build.props" />
1718
<File Path="global.json" />
1819
<File Path="LICENSE" />
1920
<File Path="README.md" />
2021
</Folder>
2122
<Folder Name="/sample/">
22-
<Project Path="sample/SampleFunctionApp/SampleFunctionApp.csproj" />
2323
<Project Path="sample/SampleFunctionApp.SourceGenerated/SampleFunctionApp.SourceGenerated.csproj" />
24+
<Project Path="sample/SampleFunctionApp/SampleFunctionApp.csproj" />
2425
</Folder>
2526
</Solution>

sample/SampleFunctionApp.SourceGenerated/local.settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
55
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
66
"EnvironmentOptions:RegionAbbreviation": "US"
7+
// "ServiceBusConnection": "Endpoint=sb://your-namespace.servicebus.windows.net/;SharedAccessKeyName=...",
78
}
89
}

src/AzureFunctions.DisabledWhen.SourceGenerator/Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<!-- NuGet Package -->
1212
<PropertyGroup>
1313
<PackageId>AzureFunctions.DisabledWhen.SourceGenerator</PackageId>
14-
<Description>Source generator for conditionally disabling Azure Functions.</Description>
14+
<Description>Conditionally disable Azure Functions based on configuration values using attributes and source generation.</Description>
1515
<PackageTags>Azure;Functions;Disable</PackageTags>
1616
</PropertyGroup>
1717

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<IsTestProject>true</IsTestProject>
5+
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
56
<InterceptorsPreviewNamespaces>$(InterceptorsPreviewNamespaces);AzureFunctions.DisabledWhen</InterceptorsPreviewNamespaces>
67
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
78
</PropertyGroup>
89

910
<ItemGroup>
1011
<ProjectReference Include="..\..\src\AzureFunctions.DisabledWhen\AzureFunctions.DisabledWhen.csproj" />
1112
<ProjectReference Include="..\..\src\AzureFunctions.DisabledWhen.SourceGenerator\AzureFunctions.DisabledWhen.SourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
12-
<ProjectReference Include="..\AzureFunctions.DisabledWhen.TestHost\AzureFunctions.DisabledWhen.TestHost.csproj" />
1313
</ItemGroup>
1414

1515
<ItemGroup>
16+
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="2.51.0" />
17+
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.2.0" />
18+
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="2.0.7" OutputItemType="Analyzer" />
1619
<PackageReference Include="TUnit" Version="1.9.64" />
1720
</ItemGroup>
18-
1921
</Project>
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
using Microsoft.Azure.Functions.Worker.Core.FunctionMetadata;
2+
using Microsoft.Extensions.Configuration;
3+
using Microsoft.Extensions.DependencyInjection;
4+
using Microsoft.Extensions.DependencyInjection.Extensions;
5+
using Microsoft.Extensions.Hosting;
6+
7+
namespace AzureFunctions.DisabledWhen.SourceGenerator.Tests;
8+
9+
public sealed class FunctionMetadataTestHost : IAsyncDisposable
10+
{
11+
private IHost? host;
12+
private readonly Action<IHostBuilder> configureTestHost;
13+
14+
public FunctionMetadataTestHost(Action<IHostBuilder> configureTestHost)
15+
=> this.configureTestHost = configureTestHost;
16+
17+
/// <summary>
18+
/// Starts the test host with the specified configuration.
19+
/// <para/>
20+
/// The WorkerHostedService is removed to prevent gRPC errors since no real Azure Functions host is running.
21+
/// </summary>
22+
/// <param name="configuration">Optional configuration key-value pairs to use for the host.</param>
23+
public async Task StartAsync(Dictionary<string, string?>? configuration = null)
24+
{
25+
var builder = new HostBuilder()
26+
.ConfigureFunctionsWorkerDefaults()
27+
.ConfigureAppConfiguration(config =>
28+
{
29+
config.SetBasePath(AppContext.BaseDirectory);
30+
config.AddInMemoryCollection(configuration ?? []);
31+
})
32+
.ConfigureServices(services =>
33+
{
34+
// Removes WorkerHostedService to prevent gRPC errors in tests (no real Azure Functions host)
35+
services.RemoveAll<IHostedService>();
36+
});
37+
38+
configureTestHost(builder);
39+
40+
host = builder.Build();
41+
42+
await host.StartAsync();
43+
}
44+
45+
/// <summary>
46+
/// Retrieves the function metadata from the running host.
47+
/// </summary>
48+
/// <returns>The collection of function metadata registered with the host.</returns>
49+
/// <exception cref="InvalidOperationException">Thrown when the host has not been started.</exception>
50+
public async Task<IEnumerable<IFunctionMetadata>> GetFunctionMetadataAsync()
51+
{
52+
if (host is null)
53+
{
54+
throw new InvalidOperationException("Host has not been started. Call StartAsync first.");
55+
}
56+
57+
return await host.Services
58+
.GetRequiredService<IFunctionMetadataProvider>()
59+
.GetFunctionMetadataAsync(AppContext.BaseDirectory);
60+
}
61+
62+
/// <summary>
63+
/// Retrieves the name of the function metadata provider.
64+
/// </summary>
65+
/// <returns>The name of the function metadata provider.</returns>
66+
/// <exception cref="InvalidOperationException">Thrown when the host has not been started.</exception>
67+
public string GetMetadataProviderTypeName()
68+
{
69+
if (host is null)
70+
{
71+
throw new InvalidOperationException("Host has not been started. Call StartAsync first.");
72+
}
73+
74+
return host.Services
75+
.GetRequiredService<IFunctionMetadataProvider>()
76+
.GetType()
77+
.Name;
78+
}
79+
80+
public async ValueTask DisposeAsync()
81+
{
82+
if (host is not null)
83+
{
84+
await host.StopAsync();
85+
host.Dispose();
86+
host = null;
87+
}
88+
89+
GC.SuppressFinalize(this);
90+
}
91+
}

tests/AzureFunctions.DisabledWhen.SourceGenerator.Tests/HostStartupTests.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
using AzureFunctions.DisabledWhen.TestHost;
2-
31
namespace AzureFunctions.DisabledWhen.SourceGenerator.Tests;
42

53
public class HostStartupTests

tests/AzureFunctions.DisabledWhen.TestHost/AzureFunctions.DisabledWhen.TestHost.csproj

Lines changed: 0 additions & 17 deletions
This file was deleted.

tests/AzureFunctions.DisabledWhen.TestHost/HostBuilderExtensions.cs

Lines changed: 0 additions & 15 deletions
This file was deleted.

0 commit comments

Comments
 (0)