diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..fe1152b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,30 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md +!**/.gitignore +!.git/HEAD +!.git/config +!.git/packed-refs +!.git/refs/heads/** \ No newline at end of file diff --git a/.github/workflows/addressdata-backend.yml b/.github/workflows/addressdata-backend.yml new file mode 100644 index 0000000..2c50d6e --- /dev/null +++ b/.github/workflows/addressdata-backend.yml @@ -0,0 +1,32 @@ +name: Build and deploy .NET application to container app addressdata-backend +on: + push: + branches: + - main +env: + CONTAINER_APP_CONTAINER_NAME: addressdatabackend + CONTAINER_APP_NAME: addressdata-backend + CONTAINER_APP_RESOURCE_GROUP_NAME: addressdata-rg + CONTAINER_REGISTRY_LOGIN_SERVER: containerplace.azurecr.io + DOCKER_FILE_PATH: src/AddressData.WebApi/Dockerfile + PROJECT_NAME_FOR_DOCKER: addressdatawebapi +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout to the branch + uses: actions/checkout@v4 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Log in to container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }} + username: ${{ secrets.containerplace_USERNAME_BB72 }} + password: ${{ secrets.containerplace_PASSWORD_BB72 }} + - name: Build and push container image to registry + uses: docker/build-push-action@v6 + with: + push: true + tags: ${{ env.CONTAINER_REGISTRY_LOGIN_SERVER }}/${{ env.PROJECT_NAME_FOR_DOCKER }}:${{ github.sha }} + file: ${{ env.DOCKER_FILE_PATH }} diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index a999fbd..919986d 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -19,7 +19,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: 9.0.x - name: Restore dependencies run: dotnet restore - name: Build diff --git a/src/AddressData.Core/AddressData.Core.csproj b/src/AddressData.Core/AddressData.Core.csproj index d036743..af50009 100644 --- a/src/AddressData.Core/AddressData.Core.csproj +++ b/src/AddressData.Core/AddressData.Core.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 enable enable true @@ -10,8 +10,8 @@ - - + + diff --git a/src/AddressData.Core/Services/Interfaces/IDocumentService.cs b/src/AddressData.Core/Services/Interfaces/IDocumentService.cs index 519fafe..30b566e 100644 --- a/src/AddressData.Core/Services/Interfaces/IDocumentService.cs +++ b/src/AddressData.Core/Services/Interfaces/IDocumentService.cs @@ -5,7 +5,7 @@ namespace AddressData.Core.Services.Interfaces; public interface IDocumentService { - Task InsertAsync(IEnumerable writeModel, LocationDomainModel location); - Task GetAsync(LocationDomainModel location); - Task> GetAllAsync(); + public Task InsertAsync(IEnumerable writeModel, LocationDomainModel location); + public Task GetAsync(LocationDomainModel location); + public Task> GetAllAsync(); } diff --git a/src/AddressData.Core/Services/Interfaces/IOverpassTurboService.cs b/src/AddressData.Core/Services/Interfaces/IOverpassTurboService.cs index 876d9ab..4fb82f5 100644 --- a/src/AddressData.Core/Services/Interfaces/IOverpassTurboService.cs +++ b/src/AddressData.Core/Services/Interfaces/IOverpassTurboService.cs @@ -4,8 +4,8 @@ namespace AddressData.Core.Services.Interfaces; public interface IOverpassTurboService { - Task?> GetCities(); - Task GetCity(long areaId); - Task GetLocation(long areaId); - Task?> GetAddresses(long areaId); + public Task?> GetCities(); + public Task GetCity(long areaId); + public Task GetLocation(long areaId); + public Task?> GetAddresses(long areaId); } diff --git a/src/AddressData.Core/Services/Interfaces/ISeedingService.cs b/src/AddressData.Core/Services/Interfaces/ISeedingService.cs index 2d1fb3c..a156379 100644 --- a/src/AddressData.Core/Services/Interfaces/ISeedingService.cs +++ b/src/AddressData.Core/Services/Interfaces/ISeedingService.cs @@ -4,6 +4,6 @@ namespace AddressData.Core.Services.Interfaces; public interface ISeedingService { - Task> RunSeeding(long? limit); - Task AddCity(long areaId); + public Task> RunSeeding(long? limit); + public Task AddCity(long areaId); } diff --git a/src/AddressData.Core/Services/OverpassTurboService.cs b/src/AddressData.Core/Services/OverpassTurboService.cs index a6e6c8d..a8f708c 100644 --- a/src/AddressData.Core/Services/OverpassTurboService.cs +++ b/src/AddressData.Core/Services/OverpassTurboService.cs @@ -78,9 +78,7 @@ public class OverpassTurboService using var streamReader = new StreamReader(stream); using var csvReader = new CsvReader(streamReader, CultureInfo.InvariantCulture); - return csvReader - .GetRecords() - .ToList(); + return [.. csvReader.GetRecords()]; } catch (Exception ex) { diff --git a/src/AddressData.WebApi/AddressData.WebApi.csproj b/src/AddressData.WebApi/AddressData.WebApi.csproj index 0b549cb..eacfd96 100644 --- a/src/AddressData.WebApi/AddressData.WebApi.csproj +++ b/src/AddressData.WebApi/AddressData.WebApi.csproj @@ -1,21 +1,23 @@ - net8.0 + net9.0 enable enable Linux + fa62b18b-f3b6-4352-bd0c-b9289770d19d + ..\.. - - - - - - - - + + + + + + + + diff --git a/src/AddressData.WebApi/Dockerfile b/src/AddressData.WebApi/Dockerfile new file mode 100644 index 0000000..0bead19 --- /dev/null +++ b/src/AddressData.WebApi/Dockerfile @@ -0,0 +1,30 @@ +# See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. + +# This stage is used when running from VS in fast mode (Default for Debug configuration) +FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base +USER $APP_UID +WORKDIR /app +EXPOSE 8080 +EXPOSE 8081 + +# This stage is used to build the service project +FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["src/AddressData.WebApi/AddressData.WebApi.csproj", "src/AddressData.WebApi/"] +COPY ["src/AddressData.Core/AddressData.Core.csproj", "src/AddressData.Core/"] +RUN dotnet restore "./src/AddressData.WebApi/AddressData.WebApi.csproj" +COPY . . +WORKDIR "/src/src/AddressData.WebApi" +RUN dotnet build "./AddressData.WebApi.csproj" -c $BUILD_CONFIGURATION -o /app/build + +# This stage is used to publish the service project to be copied to the final stage +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "./AddressData.WebApi.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + +# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration) +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "AddressData.WebApi.dll"] diff --git a/tests/AddressData.FunctionalTests/AddressData.FunctionalTests.csproj b/tests/AddressData.FunctionalTests/AddressData.FunctionalTests.csproj index 5828b05..b9db6cd 100644 --- a/tests/AddressData.FunctionalTests/AddressData.FunctionalTests.csproj +++ b/tests/AddressData.FunctionalTests/AddressData.FunctionalTests.csproj @@ -1,7 +1,7 @@ - + - net8.0 + net9.0 enable enable AddressData.FunctionalTests @@ -13,13 +13,13 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + - - + + diff --git a/tests/AddressData.UnitTests/AddressData.UnitTests.csproj b/tests/AddressData.UnitTests/AddressData.UnitTests.csproj index 5d06e8e..217d74a 100644 --- a/tests/AddressData.UnitTests/AddressData.UnitTests.csproj +++ b/tests/AddressData.UnitTests/AddressData.UnitTests.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 enable enable false @@ -11,11 +11,11 @@ - + - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -23,6 +23,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + + diff --git a/tests/AddressData.UnitTests/Models/ErrorModelApiResponseTests.cs b/tests/AddressData.UnitTests/Models/ErrorModelApiResponseTests.cs index 56573e6..8a0b015 100644 --- a/tests/AddressData.UnitTests/Models/ErrorModelApiResponseTests.cs +++ b/tests/AddressData.UnitTests/Models/ErrorModelApiResponseTests.cs @@ -22,13 +22,13 @@ public void ErrorModelConstructedWithExceptionExceptionPropertiesMatchModelPrope // Act var errorModel = new ErrorModelApiResponse(comparedException); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { // Assert Assert.That(errorModel.Type, Is.EqualTo(comparedException.GetType().Name)); Assert.That(errorModel.Message, Is.EqualTo(comparedException.Message)); Assert.That(errorModel.StackTrace, Is.EqualTo(comparedException.ToString())); - }); + } } } diff --git a/tests/AddressData.UnitTests/Services/DocumentServiceTests.cs b/tests/AddressData.UnitTests/Services/DocumentServiceTests.cs index a0f237a..53088c1 100644 --- a/tests/AddressData.UnitTests/Services/DocumentServiceTests.cs +++ b/tests/AddressData.UnitTests/Services/DocumentServiceTests.cs @@ -285,7 +285,7 @@ public async Task GetAsyncReturnsZeroSizeWhenCsvHasOnlyHeader() // Assert Assert.That(doc, Is.Not.Null); - Assert.That(doc!.Size, Is.EqualTo(0)); + Assert.That(doc!.Size, Is.Zero); } [Test]