Compare commits

..
2 Commits
Author SHA1 Message Date
ajandClaude Fable 5 7f3beebe85 ci: add Gitea workflow to build and push image on main
Build PepApi image / build-and-push (push) Successful in 21s
Same auto-build setup as CncApi and LaserQuote.Web so all forge
services publish to the Gitea registry on push instead of the
manual docker save/load flow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 11:20:18 -04:00
aj 1d4f64726b fix: resolve 500s on nest-details endpoints under Docker deployment
NestReader opened .pep files with FileStream(path, FileMode.Open), which
defaults to FileAccess.ReadWrite. The forge deployment bind-mounts
/mnt/pep-nest read-only, so every read-only open was rejected with
"Read-only file system" (EROFS) even though the code never writes.
Pass FileAccess.Read/FileShare.Read explicitly, matching DrawingReader
and ZipHelper elsewhere in PepLib.Core.

Once that was fixed, a second pre-existing bug surfaced: GetNestDetailsAsync
matched DB rows by NestName AND a literal Path comparison built from the
container's local mount path. NestHeader.Path stores the original Windows
UNC share path (e.g. \REMCOSRV0\pep nest\) from when PepApi ran directly
against the network share, so the comparison can never match post-Docker.
Match by NestName alone (ordered by most recent), consistent with the
fallback lookup already used elsewhere in NestsController.
2026-06-30 15:00:22 -04:00
4 changed files with 65 additions and 3 deletions
+28
View File
@@ -0,0 +1,28 @@
name: Build PepApi image
on:
push:
branches: [main]
paths:
- "PepApi.Core/**"
- "PepLib.Core/**"
- "Dockerfile"
- ".gitea/workflows/build-pepapi.yml"
workflow_dispatch: {}
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Log in to Gitea container registry
run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login git.thecozycat.net -u "${{ gitea.actor }}" --password-stdin
- name: Build image
run: docker build -t git.thecozycat.net/${{ gitea.repository_owner }}/pepapi:latest -t git.thecozycat.net/${{ gitea.repository_owner }}/pepapi:${{ gitea.sha }} .
- name: Push image
run: |
docker push git.thecozycat.net/${{ gitea.repository_owner }}/pepapi:latest
docker push git.thecozycat.net/${{ gitea.repository_owner }}/pepapi:${{ gitea.sha }}
+3 -2
View File
@@ -409,11 +409,12 @@ public class NestsController : ControllerBase
private async Task<NestDetails> GetNestDetailsAsync(string nestFilePath) private async Task<NestDetails> GetNestDetailsAsync(string nestFilePath)
{ {
var nest = Nest.Load(nestFilePath); var nest = Nest.Load(nestFilePath);
var dir = Path.GetDirectoryName(nestFilePath) + "\\";
var name = Path.GetFileNameWithoutExtension(nestFilePath).ToUpper(); var name = Path.GetFileNameWithoutExtension(nestFilePath).ToUpper();
var info = await _db.NestHeaders var info = await _db.NestHeaders
.FirstOrDefaultAsync(n => n.NestName.ToUpper() == name && dir == n.Path); .Where(n => n.NestName.ToUpper() == name)
.OrderByDescending(n => n.DateProgrammed)
.FirstOrDefaultAsync();
if (info == null) if (info == null)
throw new Exception("Nest header not found in database"); throw new Exception("Nest header not found in database");
+33
View File
@@ -0,0 +1,33 @@
using PepLib.IO;
using Xunit;
namespace PepLib.Core.Tests.IO;
public class NestReaderTests
{
[Fact]
public void Read_ReadOnlyFile_DoesNotRequestWriteAccess()
{
// Arrange: a file on a read-only mount denies write-access opens (EROFS on Linux,
// UnauthorizedAccessException on Windows when the read-only attribute is set).
// NestReader only ever reads nest files, so it must never request FileAccess.Write.
var path = Path.GetTempFileName();
try
{
File.SetAttributes(path, FileAttributes.ReadOnly);
var reader = new NestReader();
// Act / Assert: opening must succeed (i.e. not throw because of the read-only
// attribute). Parsing the empty/invalid content is expected to fail separately.
var ex = Record.Exception(() => reader.Read(path));
Assert.IsNotType<UnauthorizedAccessException>(ex);
}
finally
{
File.SetAttributes(path, FileAttributes.Normal);
File.Delete(path);
}
}
}
+1 -1
View File
@@ -86,7 +86,7 @@ namespace PepLib.IO
try try
{ {
stream = new FileStream(nestFile, FileMode.Open); stream = new FileStream(nestFile, FileMode.Open, FileAccess.Read, FileShare.Read);
Read(stream); Read(stream);
} }
finally finally