Skip to content

Commit

Permalink
Merge branch 'develop' into chore/playwright-in-gha-k8s
Browse files Browse the repository at this point in the history
  • Loading branch information
myieye authored Nov 18, 2024
2 parents f839ef4 + 022f8b5 commit fefddfd
Show file tree
Hide file tree
Showing 27 changed files with 1,659 additions and 41 deletions.
2 changes: 1 addition & 1 deletion .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "8.0.8",
"version": "8.0.10",
"commands": [
"dotnet-ef"
]
Expand Down
14 changes: 8 additions & 6 deletions .github/workflows/fw-lite.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ jobs:
shortSha=$(echo ${{ github.sha }} | cut -c1-8)
echo "VERSION=v$(date --rfc-3339=date)-$shortSha" >> ${GITHUB_OUTPUT}
echo "SEMVER_VERSION=$(date +%Y.%-m.%-d)" >> ${GITHUB_OUTPUT}
- name: Build viewer
working-directory: frontend/viewer
run: |
corepack enable
pnpm install
pnpm run build-app
- name: Dotnet build
working-directory: backend/FwLite/FwLiteDesktop
run: |
Expand All @@ -55,12 +63,6 @@ jobs:
- name: Dotnet test
run: dotnet test FwLiteOnly.slnf --configuration Release --logger GitHubActions

- name: Build viewer
working-directory: frontend/viewer
run: |
corepack enable
pnpm install
pnpm run build-app
- name: Upload viewer artifacts
uses: actions/upload-artifact@v4
with:
Expand Down
2 changes: 1 addition & 1 deletion backend/FwLite/FwLiteProjectSync.Tests/UpdateDiffTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class UpdateDiffTests
{
private readonly AutoFaker _autoFaker = new(new AutoFakerConfig()
{
Overrides = [new MultiStringOverride()]
Overrides = [new MultiStringOverride(), new WritingSystemIdOverride()]
});

[Fact]
Expand Down
10 changes: 8 additions & 2 deletions backend/FwLite/LcmCrdt.Tests/DataModelSnapshotTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,21 @@
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MiniLcm.Tests.AutoFakerHelpers;
using SIL.Harmony.Changes;
using SIL.Harmony.Entities;
using Soenneker.Utils.AutoBogus;
using Soenneker.Utils.AutoBogus.Config;

namespace LcmCrdt.Tests;

public class DataModelSnapshotTests : IAsyncLifetime
{
private static AutoFaker _faker = new AutoFaker(new AutoFakerConfig()
{
Overrides = [new MultiStringOverride(), new WritingSystemIdOverride()]
});

protected readonly AsyncServiceScope _services;
private readonly LcmCrdtDbContext _crdtDbContext;
private CrdtConfig _crdtConfig;
Expand Down Expand Up @@ -76,15 +83,14 @@ public async Task VerifyIObjectWithIdModels()
[Fact]
public void VerifyIObjectWithIdsMatchAdapterGetObjectTypeName()
{
var faker = new AutoFaker();
var jsonSerializerOptions = _crdtConfig.JsonSerializerOptions;
var types = jsonSerializerOptions.GetTypeInfo(typeof(IObjectWithId)).PolymorphismOptions?.DerivedTypes ?? [];
using (new AssertionScope())
{
foreach (var jsonDerivedType in types)
{
var typeDiscriminator = jsonDerivedType.TypeDiscriminator.Should().BeOfType<string>().Subject;
var obj = faker.Generate(jsonDerivedType.DerivedType);
var obj = _faker.Generate(jsonDerivedType.DerivedType);
new MiniLcmCrdtAdapter((IObjectWithId)obj).GetObjectTypeName().Should().Be(typeDiscriminator);
}
}
Expand Down
7 changes: 6 additions & 1 deletion backend/FwLite/LcmCrdt.Tests/EntityCopyMethodTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using SIL.Harmony.Entities;
using LcmCrdt.Objects;
using MiniLcm.Tests.AutoFakerHelpers;
using SIL.Harmony;
using Soenneker.Utils.AutoBogus;
using Soenneker.Utils.AutoBogus.Config;
Expand All @@ -8,7 +9,11 @@ namespace LcmCrdt.Tests;

public class EntityCopyMethodTests
{
private readonly AutoFaker _autoFaker = new(new AutoFakerConfig());
private readonly AutoFaker _autoFaker = new(new AutoFakerConfig()
{
Overrides = [new MultiStringOverride(), new WritingSystemIdOverride()]
});

public static IEnumerable<object[]> GetEntityTypes()
{
var crdtConfig = new CrdtConfig();
Expand Down
22 changes: 0 additions & 22 deletions backend/FwLite/LcmCrdt.Tests/MultiStringOverride.cs

This file was deleted.

5 changes: 5 additions & 0 deletions backend/FwLite/LocalWebApp/LocalWebApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@
<EmbeddedResource Include="..\..\..\frontend\viewer\dist\**\*" />
</ItemGroup>

<Target Name="FailIfViewerNotEmbedded" BeforeTargets="Build">
<Error Condition="@(EmbeddedResource->Count()) == 0"
Text="The viewer app was not found. Run 'pnpm run build-app' from the viewer folder." />
</Target>

<ItemGroup Condition="$([MSBuild]::IsOsPlatform('macOS'))">
<!--
This assumes that icu4c libs are installed under "/opt/local/lib" on macOS. This is the default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ public override void Generate(AutoFakerOverrideContext context)
var wordsArray = context.Faker.Random.WordsArray(1, 4);
foreach (var word in wordsArray)
{
var writingSystemId = validWs is not null
? context.Faker.Random.ArrayElement(validWs)
: context.Faker.Random.String(2, 'a', 'z');
var writingSystemId = context.Faker.Random.ArrayElement(validWs ?? WritingSystemCodes.ValidTwoLetterCodes);
target[writingSystemId] = word;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using MiniLcm.Models;
using Soenneker.Utils.AutoBogus.Context;
using Soenneker.Utils.AutoBogus.Override;

namespace MiniLcm.Tests.AutoFakerHelpers;

public class WritingSystemIdOverride: AutoFakerOverride<WritingSystemId>
{
public override bool Preinitialize => false;

public override void Generate(AutoFakerOverrideContext context)
{
var ws = context.Faker.Random.ArrayElement(WritingSystemCodes.ValidTwoLetterCodes);
context.Instance = new WritingSystemId(ws);
}
}
8 changes: 8 additions & 0 deletions backend/FwLite/MiniLcm.Tests/WritingSystemCodes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using SIL.WritingSystems;

namespace MiniLcm.Tests;

public static class WritingSystemCodes
{
public static readonly string[] ValidTwoLetterCodes = StandardSubtags.RegisteredLanguages.Select(lang => lang.Code).ToArray();
}
34 changes: 34 additions & 0 deletions backend/FwLite/MiniLcm.Tests/WritingSystemIdTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using MiniLcm.Models;

namespace MiniLcm.Tests;

public class WritingSystemIdTests
{
[Theory]
[InlineData("en")]
[InlineData("th")]
[InlineData("en-Zxxx-x-audio")]
public void ValidWritingSystemId_ShouldNotThrow(string code)
{
var ws = new WritingSystemId(code);
ws.Should().NotBeNull();
}

[Theory]
[InlineData("gx")]
[InlineData("oo")]
[InlineData("eng")] // Three-letter codes not allowed when there's a valid two-letter code
[InlineData("eng-Zxxx-x-audio")]
[InlineData("nonsense")]
public void InvalidWritingSystemId_ShouldThrow(string code)
{
Assert.Throws<ArgumentException>(() => new WritingSystemId(code));
}

[Fact]
public void DefaultWritingSystemId_IsValid()
{
var ws = new WritingSystemId("default");
ws.Should().NotBeNull();
}
}
1 change: 1 addition & 0 deletions backend/FwLite/MiniLcm/MiniLcm.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="SIL.WritingSystems" Version="14.2.0-beta*" />
<PackageReference Include="System.Text.Json" Version="8.0.5" />
<PackageReference Include="SystemTextJsonPatch" Version="3.2.1" />
</ItemGroup>
Expand Down
18 changes: 17 additions & 1 deletion backend/FwLite/MiniLcm/Models/WritingSystemId.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using SIL.WritingSystems;

namespace MiniLcm.Models;

Expand All @@ -26,11 +27,26 @@ public override void WriteAsPropertyName(Utf8JsonWriter writer, WritingSystemId
}

[JsonConverter(typeof(WritingSystemIdJsonConverter))]
public readonly record struct WritingSystemId(string Code): ISpanFormattable, ISpanParsable<WritingSystemId>
public readonly record struct WritingSystemId: ISpanFormattable, ISpanParsable<WritingSystemId>
{
public string Code { get; init; }

public WritingSystemId(string code)
{
if (code == "default" || IetfLanguageTag.IsValid(code))
{
Code = code;
}
else
{
throw new ArgumentException($"Invalid writing system ID '{code}'", nameof(code));
}
}

public static implicit operator string(WritingSystemId ws) => ws.Code;
public static implicit operator WritingSystemId(string code) => new(code);
public static implicit operator WritingSystemId(ReadOnlySpan<char> code) => new(new string(code));

public override string ToString()
{
return Code;
Expand Down
18 changes: 18 additions & 0 deletions backend/LexBoxApi/GraphQL/ProjectMutations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,24 @@ public async Task<IQueryable<Project>> SetRetentionPolicy(
return dbContext.Projects.Where(p => p.Id == input.ProjectId);
}

[Error<NotFoundException>]
[Error<DbError>]
[Error<UnauthorizedAccessException>]
[UseMutationConvention]
[UseFirstOrDefault]
[UseProjection]
public async Task<IQueryable<Project>> UpdateProjectRepoSizeInKb(string code,
IPermissionService permissionService,
ProjectService projectService,
LexBoxDbContext dbContext)
{
var projectId = await projectService.LookupProjectId(code);
await permissionService.AssertCanViewProject(projectId);
if (projectId == default) throw NotFoundException.ForType<Project>();
await projectService.UpdateRepoSizeInKb(code);
return dbContext.Projects.Where(p => p.Id == projectId);
}

[Error<NotFoundException>]
[Error<DbError>]
[Error<UnauthorizedAccessException>]
Expand Down
7 changes: 7 additions & 0 deletions backend/LexBoxApi/Services/HgService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,13 @@ public async Task<string> GetTipHash(ProjectCode code, CancellationToken token =
return await content.ReadAsStringAsync();
}

public async Task<int?> GetRepoSizeInKb(ProjectCode code, CancellationToken token = default)
{
var content = await ExecuteHgCommandServerCommand(code, "reposizeinkb", token);
var sizeStr = await content.ReadAsStringAsync();
return int.TryParse(sizeStr, out var size) ? size : null;
}

private async Task WaitForRepoEmptyState(ProjectCode code, RepoEmptyState expectedState, int timeoutMs = 30_000, CancellationToken token = default)
{
// Set timeout so unforeseen errors can't cause an infinite loop
Expand Down
12 changes: 12 additions & 0 deletions backend/LexBoxApi/Services/ProjectService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ public async Task ResetProject(ResetProjectByAdminInput input)
var rowsAffected = await dbContext.Projects.Where(p => p.Code == input.Code && p.ResetStatus == ResetStatus.None)
.ExecuteUpdateAsync(u => u
.SetProperty(p => p.ResetStatus, ResetStatus.InProgress)
.SetProperty(p => p.RepoSizeInKb, 0)
.SetProperty(p => p.LastCommit, null as DateTimeOffset?));
if (rowsAffected == 0) throw new NotFoundException($"project {input.Code} not ready for reset, either already reset or not found", nameof(Project));
await ResetLexEntryCount(input.Code);
Expand Down Expand Up @@ -239,9 +240,20 @@ public async Task UpdateProjectMetadata(Project project)
}

project.LastCommit = await hgService.GetLastCommitTimeFromHg(project.Code);
project.RepoSizeInKb = await hgService.GetRepoSizeInKb(project.Code);
// Caller is responsible for caling dbContext.SaveChangesAsync()
}

public async Task<int?> UpdateRepoSizeInKb(string projectCode)
{
var project = await dbContext.Projects.FirstOrDefaultAsync(p => p.Code == projectCode);
if (project is null) return null;
var size = await hgService.GetRepoSizeInKb(projectCode);
project.RepoSizeInKb = size;
await dbContext.SaveChangesAsync();
return size;
}

public async Task ResetLexEntryCount(string projectCode)
{
var project = await dbContext.Projects
Expand Down
1 change: 1 addition & 0 deletions backend/LexCore/Entities/Project.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class Project : EntityBase
public required List<ProjectUsers> Users { get; set; }
public required List<Organization> Organizations { get; set; }
public required DateTimeOffset? LastCommit { get; set; }
public int? RepoSizeInKb { get; set; }
public DateTimeOffset? DeletedDate { get; set; }
public ResetStatus ResetStatus { get; set; } = ResetStatus.None;

Expand Down
1 change: 1 addition & 0 deletions backend/LexCore/ServiceInterfaces/IHgService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public interface IHgService
Task FinishReset(ProjectCode code, Stream zipFile);
Task<HttpContent> VerifyRepo(ProjectCode code, CancellationToken token);
Task<string> GetTipHash(ProjectCode code, CancellationToken token = default);
Task<int?> GetRepoSizeInKb(ProjectCode code, CancellationToken token = default);
Task<int?> GetLexEntryCount(ProjectCode code, ProjectType projectType);
Task<string?> GetRepositoryIdentifier(Project project);
Task<HttpContent> ExecuteHgRecover(ProjectCode code, CancellationToken token);
Expand Down
Loading

0 comments on commit fefddfd

Please sign in to comment.