Skip to content

Commit 4bfd233

Browse files
committed
Update build to only trigger on changes to application code. Add a PR workflow for Dependabot to run against to ensure builds pass. Add simple logic to base the library on a JSON file until a backing database is added.
1 parent 5b401e8 commit 4bfd233

File tree

13 files changed

+178
-100
lines changed

13 files changed

+178
-100
lines changed

.github/workflows/deploy.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
name: Build & Deploy
22

33
on:
4+
workflow_dispatch:
45
push:
56
branches:
67
- main
8+
paths:
9+
- 'ui/**'
10+
- 'api/**'
711

812
jobs:
913
build_and_deploy_job:
1014
runs-on: ubuntu-latest
1115
name: Build and Deploy to Azure Static Web App
1216
permissions:
13-
id-token: write
1417
contents: read
1518
steps:
1619
# Checkout the repo
1720
- uses: actions/checkout@v3
18-
with:
19-
submodules: true
20-
lfs: false
2121
# Deploy the application to Azure Static Web Apps
2222
# For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
2323
- name: Deploy

.github/workflows/pr.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Pull Requset
2+
3+
on:
4+
pull_request:
5+
6+
jobs:
7+
build:
8+
runs-on: ubuntu-latest
9+
name: Build the application
10+
permissions:
11+
contents: read
12+
steps:
13+
# Checkout the repo
14+
- uses: actions/checkout@v3
15+
# Install the required Node & .Net versions
16+
- name: Setup Node.js
17+
uses: actions/setup-node@v3
18+
with:
19+
node-version: '22'
20+
- name: Setup .NET
21+
uses: actions/setup-dotnet@v3
22+
with:
23+
dotnet-version: '8.0.x'
24+
# Build the application to ensure it builds successfully
25+
- name: Build Application
26+
working-directory: ./ui
27+
run: |
28+
npm ci
29+
npm run build
30+
- name: Build API
31+
working-directory: ./api
32+
run: |
33+
dotnet build

HomeLibrary.sln

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ Microsoft Visual Studio Solution File, Format Version 12.00
22
# Visual Studio Version 17
33
VisualStudioVersion = 17.5.2.0
44
MinimumVisualStudioVersion = 10.0.40219.1
5-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "api", "api\api.csproj", "{CBFA08EA-AECE-205F-7B85-326FD0B81BAD}"
5+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gemstone.HomeLibrary", "api\Gemstone.HomeLibrary.csproj", "{CBFA08EA-AECE-205F-7B85-326FD0B81BAD}"
6+
EndProject
7+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9F559AD9-C03E-4594-B963-A67F144CA444}"
8+
ProjectSection(SolutionItems) = preProject
9+
books.json = api/books.json
10+
EndProjectSection
611
EndProject
712
Global
813
GlobalSection(SolutionConfigurationPlatforms) = preSolution

api/Dto/BooksResponse.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,8 @@ namespace Gemstone.HomeLibrary.Dto;
77
/// </summary>
88
public class BooksResponse : BaseResponse
99
{
10-
public required Book[] Books { get; set; }
11-
}
10+
/// <summary>
11+
/// The full list of books in the library.
12+
/// </summary>
13+
public required ICollection<Book> Books { get; set; }
14+
}

api/Endpoints/GetBooks.cs

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,30 @@
1+
using Gemstone.HomeLibrary.Dto;
2+
using Gemstone.HomeLibrary.Models;
3+
using Gemstone.HomeLibrary.Services;
14
using Microsoft.AspNetCore.Http;
25
using Microsoft.AspNetCore.Mvc;
36
using Microsoft.Azure.Functions.Worker;
7+
using Microsoft.Extensions.DependencyInjection;
48
using Microsoft.Extensions.Logging;
5-
using Gemstone.HomeLibrary.Dto;
6-
using Gemstone.HomeLibrary.Models;
79

8-
namespace Gemstone.HomeLibrary;
10+
namespace Gemstone.HomeLibrary.Endpoints;
911

1012
/// <summary>
1113
/// Fetch books from the library.
1214
/// </summary>
13-
public class GetBooks
15+
public class GetBooks(IServiceProvider services)
1416
{
15-
private readonly ILogger<GetBooks> _logger;
16-
17-
public GetBooks(ILogger<GetBooks> logger)
18-
{
19-
_logger = logger;
20-
}
17+
private readonly IBookService _bookService = services.GetRequiredService<IBookService>();
2118

2219
[Function("GetBooks")]
2320
public IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req)
2421
{
25-
_logger.LogInformation("Fetching books");
26-
27-
// TODO fetch books from "somewhere"
28-
Book[] books = [
29-
new() { Title = "A Wrinkle in Time" },
30-
new() { Title = "The Hobbit" },
31-
new() { Title = "Hyperion" },
32-
];
22+
var books = _bookService.GetBooks();
3323

3424
return new JsonResult(new BooksResponse
3525
{
36-
Message = "Books retrieved successfully",
26+
Message = "Books retrieved.",
3727
Books = books
3828
});
3929
}
40-
}
30+
}

api/Endpoints/SaveBook.cs

Lines changed: 0 additions & 27 deletions
This file was deleted.
Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
2-
3-
<PropertyGroup>
4-
<TargetFramework>net9.0</TargetFramework>
5-
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
6-
<OutputType>Exe</OutputType>
7-
<ImplicitUsings>enable</ImplicitUsings>
8-
<Nullable>enable</Nullable>
9-
</PropertyGroup>
10-
11-
<ItemGroup>
12-
<FrameworkReference Include="Microsoft.AspNetCore.App" />
13-
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.23.0" />
14-
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="2.50.0" />
15-
<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="2.50.0" />
16-
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="2.1.0" />
17-
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="2.0.6" />
18-
</ItemGroup>
19-
20-
</Project>
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
6+
<OutputType>Exe</OutputType>
7+
<ImplicitUsings>enable</ImplicitUsings>
8+
<Nullable>enable</Nullable>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<FrameworkReference Include="Microsoft.AspNetCore.App"/>
13+
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.23.0"/>
14+
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="2.50.0"/>
15+
<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="2.50.0"/>
16+
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="2.1.0"/>
17+
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="2.0.6"/>
18+
</ItemGroup>
19+
20+
<ItemGroup>
21+
<None Update="books.json">
22+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
23+
</None>
24+
</ItemGroup>
25+
</Project>

api/Models/Book.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,8 @@ namespace Gemstone.HomeLibrary.Models;
55
/// </summary>
66
public class Book
77
{
8+
/// <summary>
9+
/// The book title.
10+
/// </summary>
811
public required string Title { get; set; }
9-
}
12+
}

api/Program.cs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
using Microsoft.Azure.Functions.Worker;
2-
using Microsoft.Azure.Functions.Worker.Builder;
3-
using Microsoft.Extensions.DependencyInjection;
4-
using Microsoft.Extensions.Hosting;
5-
6-
var builder = FunctionsApplication.CreateBuilder(args);
7-
8-
builder.ConfigureFunctionsWebApplication();
9-
10-
builder.Services
11-
.AddApplicationInsightsTelemetryWorkerService()
12-
.ConfigureFunctionsApplicationInsights();
13-
14-
builder.Build().Run();
1+
using Gemstone.HomeLibrary.Services;
2+
using Microsoft.Azure.Functions.Worker;
3+
using Microsoft.Azure.Functions.Worker.Builder;
4+
using Microsoft.Extensions.DependencyInjection;
5+
using Microsoft.Extensions.Hosting;
6+
7+
var builder = FunctionsApplication.CreateBuilder(args);
8+
9+
builder.ConfigureFunctionsWebApplication();
10+
11+
builder.Services
12+
.AddApplicationInsightsTelemetryWorkerService()
13+
.ConfigureFunctionsApplicationInsights()
14+
.AddMemoryCache()
15+
.AddScoped<IBookService, BookService>();
16+
17+
builder.Build().Run();

api/Services/BookService.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System.Text.Json;
2+
using Gemstone.HomeLibrary.Models;
3+
using Microsoft.Extensions.Caching.Memory;
4+
using Microsoft.Extensions.DependencyInjection;
5+
using Microsoft.Extensions.Logging;
6+
7+
namespace Gemstone.HomeLibrary.Services;
8+
9+
/// <inheritdoc cref="IBookService"/>
10+
public class BookService(IServiceProvider services, ILogger<BookService> logger) : IBookService
11+
{
12+
private readonly IMemoryCache _cache = services.GetRequiredService<IMemoryCache>();
13+
14+
/// <inheritdoc cref="IBookService.GetBooks"/>
15+
public ICollection<Book> GetBooks()
16+
{
17+
logger.LogDebug("Fetching books");
18+
19+
// try and get the books from the cache first, falling back to fetching them from the original source
20+
var books = _cache.Get<ICollection<Book>>("books") ?? LoadBooks();
21+
22+
// return the list of books we got
23+
return books;
24+
}
25+
26+
/// <summary>
27+
/// Load the books.
28+
/// </summary>
29+
/// <remarks>As this loads books into the cache</remarks>
30+
private ICollection<Book> LoadBooks()
31+
{
32+
// try and load from the book JSON data source (until we have a database backing the service, it will be readonly).
33+
var books = JsonSerializer
34+
.Deserialize<ICollection<Book>>(File.ReadAllText("books.json")) ?? new List<Book>();
35+
36+
// save them to the cache for the next call
37+
_cache.Set("books", books);
38+
logger.LogDebug("Cached books");
39+
40+
// return the list we now have
41+
return books;
42+
}
43+
}

0 commit comments

Comments
 (0)