Skip to content

Commit

Permalink
.NET 8 update (#44)
Browse files Browse the repository at this point in the history
- updated all projects to .NET 8
  - updated all other dependencies to latest
- switch to shared docker build workflow
- fix and improve event interceptor
- added signalR stateful reconnect from .NET 8
https://learn.microsoft.com/en-us/aspnet/core/signalr/configuration?view=aspnetcore-8.0&tabs=dotnet#configure-stateful-reconnect
  - added SignalR appsettings section with 2 settings
    - EnableStatefulReconnect defaults to true
    - StatefulReconnectBufferSizeBytes defaults to the .NET default of 100000
  • Loading branch information
sei-aschlackman authored Oct 9, 2024
1 parent 593f6b2 commit 2d71d9d
Show file tree
Hide file tree
Showing 28 changed files with 804 additions and 540 deletions.
75 changes: 11 additions & 64 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,73 +1,20 @@
name: Publish Docker Images
name: Build and Publish Image

on:
pull_request:
branches:
- development
push:
branches: [ development, staging ]
branches: [development, staging]
release:
types: [ "published" ]
workflow_dispatch:
inputs:
tagName:
description: 'Tag of the image you want to build and push'
required: true
types: ["published"]

jobs:
build:
runs-on: ubuntu-latest
steps:

- name: Checkout
uses: actions/checkout@v2

- name: Prepare
id: prep
run: |
DOCKER_IMAGE=cmusei/player-api
VERSION=development
if [[ ! -z "${{ github.event.inputs.tagName }}" ]]; then
VERSION=${{ github.event.inputs.tagName }}
TAGS="${DOCKER_IMAGE}:${VERSION}"
elif [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
MAJORMINORVERSION=$(echo $VERSION | grep -oP '(\d+)\.(\d+)')
TAGS="${DOCKER_IMAGE}:${VERSION},${DOCKER_IMAGE}:${MAJORMINORVERSION}"
elif [[ $GITHUB_REF == refs/heads/* ]]; then
VERSION=$(echo ${GITHUB_REF#refs/heads/} | sed -r 's#/+#-#g')
TAGS="${DOCKER_IMAGE}:${VERSION}"
fi
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
echo ::set-output name=push::false
echo "event is pull_request, not pushing image"
else
echo ::set-output name=push::true
echo "event is not pull_request, pushing image"
fi
echo ::set-output name=version::${VERSION}
echo ::set-output name=tags::${TAGS}
echo ::set-output name=created::$(date -u +'%Y-%m-%dT%H:%M:%SZ')
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}

- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
push: ${{ steps.prep.outputs.push }}
pull: true
tags: ${{ steps.prep.outputs.tags }}
labels: |
org.opencontainers.image.source=${{ github.event.repository.clone_url }}
org.opencontainers.image.created=${{ steps.prep.outputs.created }}
org.opencontainers.image.revision=${{ github.sha }}
build-and-publish:
name: Build and Publish
uses: cmu-sei/Crucible-Github-Actions/.github/workflows/[email protected]
with:
imageName: cmusei/player-api
secrets:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }}
16 changes: 7 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#
#multi-stage target: dev
#
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS dev
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS dev

ENV ASPNETCORE_URLS=http://0.0.0.0:4300 \
ASPNETCORE_ENVIRONMENT=DEVELOPMENT
ENV ASPNETCORE_HTTP_PORTS=4300
ENV ASPNETCORE_ENVIRONMENT=DEVELOPMENT

COPY . /app
WORKDIR /app
Expand All @@ -14,16 +14,14 @@ CMD ["dotnet", "run"]
#
#multi-stage target: prod
#
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS prod
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS prod
ARG commit
ENV COMMIT=$commit
ENV DOTNET_HOSTBUILDER__RELOADCONFIGCHANGE=false
COPY --from=dev /app/dist /app

WORKDIR /app
ENV ASPNETCORE_URLS=http://*:80
ENV ASPNETCORE_HTTP_PORTS=80
EXPOSE 80

CMD ["dotnet", "Player.Api.dll"]

RUN apt-get update && \
apt-get install -y jq
CMD ["dotnet", "Player.Api.dll"]
4 changes: 2 additions & 2 deletions Player.Api.Data/Data/Extensions/ModelBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ public static void AddPostgresUUIDGeneration(this ModelBuilder builder)
.GetEntityTypes()
.SelectMany(t => t.GetProperties())
.Where(p => p.ClrType == typeof(Guid))
.Select(p => builder.Entity(p.DeclaringEntityType.ClrType).Property(p.Name))
.Where(p => p.Metadata.ValueGenerated == Microsoft.EntityFrameworkCore.Metadata.ValueGenerated.OnAdd &&
.Select(p => builder.Entity(p.DeclaringType.ClrType).Property(p.Name))
.Where(p => p.Metadata.ValueGenerated == ValueGenerated.OnAdd &&
p.Metadata.IsPrimaryKey())
)
{
Expand Down
60 changes: 60 additions & 0 deletions Player.Api.Data/Data/Models/Entry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright 2024 Carnegie Mellon University. All Rights Reserved.
// Released under a MIT (SEI)-style license. See LICENSE.md in the project root for license information.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;

namespace Player.Api.Data;

public class Entry
{
public object Entity { get; set; }
public EntityState State { get; set; }
public IEnumerable<PropertyEntry> Properties { get; set; }
private Dictionary<string, bool> IsPropertyModified { get; set; } = new();

public Entry(EntityEntry entry, Entry oldEntry = null)
{
Entity = entry.Entity;
State = entry.State;
Properties = entry.Properties;

ProcessOldEntry(oldEntry);

foreach (var prop in Properties)
{
IsPropertyModified[prop.Metadata.Name] = prop.IsModified;
}
}

private void ProcessOldEntry(Entry oldEntry)
{
if (oldEntry == null) return;

if (oldEntry.State != EntityState.Unchanged && oldEntry.State != EntityState.Detached)
{
State = oldEntry.State;
}

var modifiedProperties = oldEntry.GetModifiedProperties();

foreach (var property in Properties)
{
if (modifiedProperties.Contains(property.Metadata.Name))
{
property.IsModified = true;
}
}
}

public string[] GetModifiedProperties()
{
return IsPropertyModified
.Where(x => x.Value)
.Select(x => x.Key)
.ToArray();
}
}
11 changes: 4 additions & 7 deletions Player.Api.Data/Data/PlayerContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,19 @@
// Released under a MIT (SEI)-style license. See LICENSE.md in the project root for license information.

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure.Internal;
using Player.Api.Data.Data.Models;
using Player.Api.Data.Data.Models.Webhooks;
using Player.Api.Data.Data.Extensions;
using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal;
using System;

namespace Player.Api.Data.Data
{
public class PlayerContext : DbContext
{
private DbContextOptions<PlayerContext> _options;
// Needed for EventInterceptor
public IServiceProvider ServiceProvider;

public PlayerContext(DbContextOptions<PlayerContext> options) : base(options)
{
_options = options;
}
public PlayerContext(DbContextOptions<PlayerContext> options) : base(options) { }

public DbSet<UserEntity> Users { get; set; }
public DbSet<ViewEntity> Views { get; set; }
Expand Down
30 changes: 30 additions & 0 deletions Player.Api.Data/Data/PlayerContextFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2024 Carnegie Mellon University. All Rights Reserved.
// Released under a MIT (SEI)-style license. See LICENSE.md in the project root for license information.

using System;
using Microsoft.EntityFrameworkCore;

namespace Player.Api.Data.Data;

public class PlayerContextFactory : IDbContextFactory<PlayerContext>
{
private readonly IDbContextFactory<PlayerContext> _pooledFactory;
private readonly IServiceProvider _serviceProvider;

public PlayerContextFactory(
IDbContextFactory<PlayerContext> pooledFactory,
IServiceProvider serviceProvider)
{
_pooledFactory = pooledFactory;
_serviceProvider = serviceProvider;
}

public PlayerContext CreateDbContext()
{
var context = _pooledFactory.CreateDbContext();

// Inject the current scope's ServiceProvider
context.ServiceProvider = _serviceProvider;
return context;
}
}
9 changes: 3 additions & 6 deletions Player.Api.Data/Player.Api.Data.csproj
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.1" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" />
</ItemGroup>

</Project>
</Project>

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace Player.Api.Migrations.PostgreSQL.Migrations.Player
{
public partial class notifications : Migration
public partial class Notifications : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace Player.Api.Migrations.PostgreSQL.Migrations
{
public partial class filetable : Migration
public partial class FileTable : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace Player.Api.Migrations.PostgreSQL.Migrations
{
public partial class addteamids : Migration
public partial class AddTeamIds : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
Expand Down
Loading

0 comments on commit 2d71d9d

Please sign in to comment.