4 Commits

Author SHA1 Message Date
daniel-c-harvey a34e083c2e Merge branch 'drop-unit-rsync' into dev
Package install tarball / package (push) Successful in 6s
Deploy DeepDrftAPI / Build, Publish & Bundle (push) Successful in 3m13s
Deploy DeepDrftAPI / Deploy (push) Successful in 1m32s
2026-06-04 14:23:24 -04:00
daniel-c-harvey 52d6afa335 ci: stop shipping unit file in deploy — unit is host config, not CI artifact 2026-06-04 14:23:21 -04:00
daniel-c-harvey ceaa684c74 Merge branch 'factory-fix' into dev
Deploy DeepDrftAPI / Build, Publish & Bundle (push) Successful in 2m28s
Package install tarball / package (push) Successful in 6s
Deploy DeepDrftAPI / Deploy (push) Successful in 1m35s
2026-06-04 14:16:35 -04:00
daniel-c-harvey cd226f3ce9 fix: factory falls back to design-time dummy; remove CI dummy-file step and creds-env cp lines 2026-06-04 14:16:31 -04:00
7 changed files with 16 additions and 72 deletions
-10
View File
@@ -9,7 +9,6 @@ on:
- 'DeepDrftContent/**'
- 'DeepDrftModels/**'
- '.gitea/workflows/deploy-api.yml'
- 'deploy/systemd/deepdrftapi.service'
jobs:
build:
@@ -45,14 +44,6 @@ jobs:
--no-build \
-o DeepDrftAPI/publish
# DeepDrftContextFactory reads environment/connections.json at design time.
# Write a parseable dummy so the factory does not throw during bundle construction.
# The bundle only needs the provider type, not a live database connection.
- name: Write dummy connections file for EF bundle
run: |
mkdir -p DeepDrftAPI/environment
echo '{"ConnectionStrings":{"DefaultConnection":"Host=localhost;Database=dummy;Username=dummy","Auth":"Host=localhost;Database=dummy;Username=dummy"}}' > DeepDrftAPI/environment/connections.json
# EF bundle: self-contained binary that applies DeepDrftContext migrations on the host
# without the .NET SDK. AuthBlocks' Identity DB is NOT covered here — it self-migrates
# via UseAuthBlocksStartupAsync() on first boot.
@@ -118,7 +109,6 @@ jobs:
rsync -e "ssh -i ~/.ssh/deepdrft_ed25519 -o StrictHostKeyChecking=yes" \
staging/deepdrft-api.tar.gz \
staging/deepdrft-migrations-bundle \
deploy/systemd/deepdrftapi.service \
deepdrft@$DEPLOY_HOST:
- name: Trigger deploy on host
+15 -16
View File
@@ -1,5 +1,6 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using NetBlocks.Utilities.Environment;
namespace DeepDrftData.Data;
@@ -7,23 +8,21 @@ public class DeepDrftContextFactory : IDesignTimeDbContextFactory<DeepDrftContex
{
public DeepDrftContext CreateDbContext(string[] args)
{
// Load the real connection string from environment/connections.json — the same
// file DeepDrftPublic's Program.cs loads via CredentialTools. When EF tools run with
// --startup-project DeepDrftPublic, the working directory resolves there, so this
// relative path works without any env var configuration.
const string relPath = "environment/connections.json";
if (!File.Exists(relPath))
throw new FileNotFoundException(
$"'{relPath}' not found. Run EF commands with --startup-project DeepDrftPublic " +
$"from the solution root (current dir: {Directory.GetCurrentDirectory()}).", relPath);
var path = CredentialTools.ResolvePath("connections", "environment/connections.json");
using var doc = System.Text.Json.JsonDocument.Parse(File.ReadAllText(relPath));
var connectionString = doc.RootElement
.GetProperty("ConnectionStrings")
.GetProperty("DefaultConnection")
.GetString()
?? throw new InvalidOperationException(
"ConnectionStrings:DefaultConnection not found in environment/connections.json");
string? connectionString = null;
if (File.Exists(path))
{
using var doc = System.Text.Json.JsonDocument.Parse(File.ReadAllText(path));
connectionString = doc.RootElement
.GetProperty("ConnectionStrings")
.GetProperty("DefaultConnection")
.GetString();
}
// Fall back to a design-time dummy — the bundle only needs the provider/schema,
// not a live connection. This removes the requirement to write a dummy file in CI.
connectionString ??= "Host=localhost;Database=deepdrft-design-time;Username=dummy";
var optionsBuilder = new DbContextOptionsBuilder<DeepDrftContext>();
optionsBuilder.UseNpgsql(connectionString);
+1
View File
@@ -18,6 +18,7 @@
</PackageReference>
<!-- Npgsql 10.0.1 requires Microsoft.EntityFrameworkCore >= 10.0.4; keep in sync -->
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.1" />
<PackageReference Include="Cerebellum.NetBlocks" Version="10.3.30" />
<PackageReference Include="Cerebellum.BlazorBlocks.Data" Version="10.3.30" />
<PackageReference Include="Cerebellum.BlazorBlocks.Data.Postgres" Version="10.3.30" />
</ItemGroup>
-10
View File
@@ -5,7 +5,6 @@
# Expects in ${APP_HOME}/staging/:
# deepdrft-api.tar.gz -- published self-contained linux-x64 binary tree
# deepdrft-migrations-bundle -- self-contained EF bundle (pre-built in CI)
# deepdrftapi.service -- systemd unit file (optional)
#
# Migrations are applied BEFORE the service restarts via the EF bundle binary.
# The bundle covers DeepDrftContext (track metadata DB) only.
@@ -94,15 +93,6 @@ if [[ -d "${APPROOT}/environment" ]]; then
fi
fi
# ── Install systemd unit file (if present in staging) ─────────────────────
if [[ -f "${STAGING}/deepdrftapi.service" ]]; then
mkdir -p "${APP_HOME}/.config/systemd/user"
cp "${STAGING}/deepdrftapi.service" "${APP_HOME}/.config/systemd/user/deepdrftapi.service"
rm -f "${STAGING}/deepdrftapi.service"
systemctl --user daemon-reload
echo "[deploy-api] systemd unit file installed"
fi
# ── Enable and restart service ─────────────────────────────────────────────
systemctl --user enable deepdrftapi.service
systemctl --user restart deepdrftapi.service
-15
View File
@@ -5,9 +5,6 @@
# Expects in ${APP_HOME}/staging/:
# deepdrft-manager.tar.gz -- published self-contained linux-x64 binary tree
#
# DeepDrftManager reads its API URL and API key credential from environment/api.json at startup
# (populated by setup-step10-creds.sh). The env-file copy block below keeps it current.
#
# Paths are derived at runtime — no hardcoded usernames or home dirs.
# APP_HOME comes from $HOME (sshd sets this for the app user).
@@ -36,18 +33,6 @@ rm -f "${STAGING}/${ARCHIVE}"
echo "[deploy-manager] archive extracted"
# ── Apply environment files (host-managed, not in archive) ────────────────
if [[ -d "${APPROOT}/environment" ]]; then
shopt -s nullglob
env_files=("${APPROOT}/environment/"*)
shopt -u nullglob
if [[ ${#env_files[@]} -gt 0 ]]; then
mkdir -p "${APPROOT}/bin/environment"
cp "${env_files[@]}" "${APPROOT}/bin/environment/"
echo "[deploy-manager] environment files applied"
fi
fi
# ── Enable and restart service ─────────────────────────────────────────────
systemctl --user enable deepdrftmanager.service
systemctl --user restart deepdrftmanager.service
-15
View File
@@ -5,9 +5,6 @@
# Expects in ${APP_HOME}/staging/:
# deepdrft-public.tar.gz -- published self-contained linux-x64 binary tree
#
# DeepDrftPublic reads its API URL credential from environment/api.json at startup
# (populated by setup-step10-creds.sh). The env-file copy block below keeps it current.
#
# Paths are derived at runtime — no hardcoded usernames or home dirs.
# APP_HOME comes from $HOME (sshd sets this for the app user).
@@ -36,18 +33,6 @@ rm -f "${STAGING}/${ARCHIVE}"
echo "[deploy-public] archive extracted"
# ── Apply environment files (host-managed, not in archive) ────────────────
if [[ -d "${APPROOT}/environment" ]]; then
shopt -s nullglob
env_files=("${APPROOT}/environment/"*)
shopt -u nullglob
if [[ ${#env_files[@]} -gt 0 ]]; then
mkdir -p "${APPROOT}/bin/environment"
cp "${env_files[@]}" "${APPROOT}/bin/environment/"
echo "[deploy-public] environment files applied"
fi
fi
# ── Enable and restart service ─────────────────────────────────────────────
systemctl --user enable deepdrftpublic.service
systemctl --user restart deepdrftpublic.service
-6
View File
@@ -92,7 +92,6 @@ need_cred() {
if need_cred "filedatabase"; then
write_cred "filedatabase" \
"{\"FileDatabaseSettings\":{\"VaultPath\":\"${APP_HOME}/api/deepdrft/vaults\"}}"
cp "${CREDDIR}/filedatabase.json" "${APP_HOME}/api/deepdrft/environment/filedatabase.json"
else
echo "[setup-step10-creds] filedatabase.json already exists, skipping"
fi
@@ -111,7 +110,6 @@ if need_cred "apikey"; then
unset API_KEY_INPUT
write_cred "apikey" \
"{\"ApiKeySettings\":{\"ApiKey\":\"$(json_escape "${API_KEY}")\"}}"
cp "${CREDDIR}/apikey.json" "${APP_HOME}/api/deepdrft/environment/apikey.json"
else
echo "[setup-step10-creds] apikey.json already exists, skipping"
# Still need the value for api-manager.json if that's also being written.
@@ -152,7 +150,6 @@ if need_cred "connections"; then
AUTH_CONN="Host=localhost;Database=${DB_AUTH};Username=${PG_ROLE};Password=$(json_escape "${PG_PASSWORD}")"
write_cred "connections" \
"{\"ConnectionStrings\":{\"DefaultConnection\":\"${META_CONN}\",\"Auth\":\"${AUTH_CONN}\"}}"
cp "${CREDDIR}/connections.json" "${APP_HOME}/api/deepdrft/environment/connections.json"
unset PG_PASSWORD META_CONN AUTH_CONN
else
echo "[setup-step10-creds] connections.json already exists, skipping"
@@ -207,7 +204,6 @@ if need_cred "authblocks"; then
{"AuthBlocks":{"Jwt":{"Secret":"$(json_escape "${JWT_SECRET}")","Issuer":"$(json_escape "${JWT_ISSUER}")","Audience":"$(json_escape "${JWT_AUDIENCE}")"},"Email":{"Host":"$(json_escape "${EMAIL_HOST}")","Token":"$(json_escape "${EMAIL_TOKEN}")"},"Admin":{"UserName":"$(json_escape "${ADMIN_USERNAME}")","Email":"$(json_escape "${ADMIN_EMAIL}")","Password":"$(json_escape "${ADMIN_PASSWORD}")"},"SupportEmail":"$(json_escape "${SUPPORT_EMAIL}")"}}
JSON
)"
cp "${CREDDIR}/authblocks.json" "${APP_HOME}/api/deepdrft/environment/authblocks.json"
unset JWT_SECRET JWT_ISSUER JWT_AUDIENCE EMAIL_HOST EMAIL_TOKEN
unset ADMIN_USERNAME ADMIN_EMAIL ADMIN_PASSWORD SUPPORT_EMAIL
else
@@ -218,7 +214,6 @@ fi
if need_cred "api-public"; then
write_cred "api-public" \
"{\"Api\":{\"ContentApiUrl\":\"http://localhost:${PORT_API:-5002}\"}}"
cp "${CREDDIR}/api-public.json" "${APP_HOME}/public/environment/api.json"
else
echo "[setup-step10-creds] api-public.json already exists, skipping"
fi
@@ -232,7 +227,6 @@ if need_cred "api-manager"; then
fi
write_cred "api-manager" \
"{\"Api\":{\"ContentApiUrl\":\"http://localhost:${PORT_API:-5002}\",\"ContentApiKey\":\"$(json_escape "${API_KEY}")\"}}"
cp "${CREDDIR}/api-manager.json" "${APP_HOME}/manager/environment/api.json"
unset API_KEY
else
echo "[setup-step10-creds] api-manager.json already exists, skipping"