[FA-5] Adds image support with proper S3 upload and replacement after upload
This commit is contained in:
@@ -21,6 +21,11 @@
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.7" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2"/>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Builds the Fusion graph file before building the application itself -->
|
||||
<Target Name="RunFusionBuild" BeforeTargets="BeforeBuild">
|
||||
<Exec Command="python build_gateway.py" WorkingDirectory="$(ProjectDir)" />
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\.dockerignore">
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Export GraphQL schemas, pack subgraphs and compose the gateway (PowerShell).
|
||||
.DESCRIPTION
|
||||
- Searches for FictionArchive.Service.* folders one directory above this script.
|
||||
- Reads skip-projects.txt next to the script.
|
||||
- Builds each service (Release).
|
||||
- Runs `dotnet run --no-build --no-launch-profile -- schema export` in each service to avoid running the web host.
|
||||
- Packs subgraphs.
|
||||
- Composes the gateway from FictionArchive.API.
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param()
|
||||
|
||||
function Write-ErrExit {
|
||||
param($Message, $Code = 1)
|
||||
Write-Error $Message
|
||||
exit $Code
|
||||
}
|
||||
|
||||
# Resolve directories
|
||||
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
||||
$ServicesDir = Resolve-Path -Path (Join-Path $ScriptDir '..') -ErrorAction Stop
|
||||
$ApiDir = Join-Path $ServicesDir 'FictionArchive.API'
|
||||
|
||||
Write-Host "Script dir: $ScriptDir"
|
||||
Write-Host "Services dir: $ServicesDir"
|
||||
|
||||
# Load skip list
|
||||
$SkipFile = Join-Path $ScriptDir 'gateway_skip.txt'
|
||||
$SkipList = @()
|
||||
|
||||
Write-Host "----------------------------------------"
|
||||
Write-Host " Loading skip list..."
|
||||
Write-Host "----------------------------------------"
|
||||
|
||||
if (Test-Path $SkipFile) {
|
||||
$SkipList = Get-Content $SkipFile |
|
||||
ForEach-Object { $_.Trim() } |
|
||||
Where-Object { $_ -and -not $_.StartsWith('#') }
|
||||
|
||||
Write-Host "Skipping: $($SkipList -join ', ')"
|
||||
} else {
|
||||
Write-Warning "skip-projects.txt not found — no services will be skipped."
|
||||
}
|
||||
|
||||
# Find service directories
|
||||
Write-Host
|
||||
Write-Host "----------------------------------------"
|
||||
Write-Host " Finding GraphQL services..."
|
||||
Write-Host "----------------------------------------"
|
||||
|
||||
$servicePattern = 'FictionArchive.Service.*'
|
||||
$serviceDirs = Get-ChildItem -Path $ServicesDir -Directory -Filter 'FictionArchive.Service.*'
|
||||
|
||||
if (-not $serviceDirs) {
|
||||
Write-ErrExit "No service folders found matching FictionArchive.Service.* under $ServicesDir"
|
||||
}
|
||||
|
||||
$selectedServices = @()
|
||||
|
||||
foreach ($d in $serviceDirs) {
|
||||
if ($SkipList -contains $d.Name) {
|
||||
Write-Host "Skipping: $($d.Name)"
|
||||
continue
|
||||
}
|
||||
|
||||
Write-Host "Found: $($d.Name)"
|
||||
$selectedServices += $d.FullName
|
||||
}
|
||||
|
||||
if (-not $selectedServices) {
|
||||
Write-ErrExit "All services skipped — nothing to do."
|
||||
}
|
||||
|
||||
# Export schemas and pack subgraphs
|
||||
Write-Host
|
||||
Write-Host "----------------------------------------"
|
||||
Write-Host " Exporting schemas & packing subgraphs..."
|
||||
Write-Host "----------------------------------------"
|
||||
|
||||
foreach ($svcPath in $selectedServices) {
|
||||
$svcName = Split-Path -Leaf $svcPath
|
||||
Write-Host "`nProcessing: $svcName"
|
||||
|
||||
Push-Location $svcPath
|
||||
try {
|
||||
# Build Release
|
||||
Write-Host "Building $svcName..."
|
||||
dotnet build -c Release
|
||||
if ($LASTEXITCODE -ne 0) { Write-ErrExit "dotnet build failed for $svcName" }
|
||||
|
||||
# Schema export using dotnet run (no server)
|
||||
Write-Host "Running schema export..."
|
||||
dotnet run --no-build --no-launch-profile -- schema export --output schema.graphql
|
||||
if ($LASTEXITCODE -ne 0) { Write-ErrExit "Schema export failed for $svcName" }
|
||||
|
||||
# Pack subgraph
|
||||
Write-Host "Running fusion subgraph pack..."
|
||||
fusion subgraph pack
|
||||
if ($LASTEXITCODE -ne 0) { Write-ErrExit "fusion subgraph pack failed for $svcName" }
|
||||
|
||||
Write-Host "Completed: $svcName"
|
||||
}
|
||||
finally {
|
||||
Pop-Location
|
||||
}
|
||||
}
|
||||
|
||||
# Compose gateway
|
||||
Write-Host
|
||||
Write-Host "----------------------------------------"
|
||||
Write-Host " Running fusion compose..."
|
||||
Write-Host "----------------------------------------"
|
||||
|
||||
if (-not (Test-Path $ApiDir)) {
|
||||
Write-ErrExit "API directory not found: $ApiDir"
|
||||
}
|
||||
|
||||
Push-Location $ApiDir
|
||||
try {
|
||||
if (Test-Path "gateway.fgp") { Remove-Item "gateway.fgp" -Force }
|
||||
|
||||
foreach ($svcPath in $selectedServices) {
|
||||
$svcName = Split-Path -Leaf $svcPath
|
||||
Write-Host "Composing: $svcName"
|
||||
fusion compose -p gateway.fgp -s ("..\" + $svcName)
|
||||
if ($LASTEXITCODE -ne 0) { Write-ErrExit "fusion compose failed for $svcName" }
|
||||
}
|
||||
|
||||
Write-Host "`nFusion build complete!"
|
||||
}
|
||||
finally {
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
exit 0
|
||||
129
FictionArchive.API/build_gateway.py
Normal file
129
FictionArchive.API/build_gateway.py
Normal file
@@ -0,0 +1,129 @@
|
||||
#!/usr/bin/env python3
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# ----------------------------------------
|
||||
# Helpers
|
||||
# ----------------------------------------
|
||||
|
||||
def run(cmd, cwd=None):
|
||||
"""Run a command and exit on failure."""
|
||||
print(f"> {' '.join(cmd)}")
|
||||
result = subprocess.run(cmd, cwd=cwd)
|
||||
if result.returncode != 0:
|
||||
print(f"ERROR: command failed in {cwd or os.getcwd()}")
|
||||
sys.exit(result.returncode)
|
||||
|
||||
|
||||
def load_skip_list(skip_file: Path):
|
||||
if not skip_file.exists():
|
||||
print(f"WARNING: skip-projects.txt not found at {skip_file}")
|
||||
return set()
|
||||
|
||||
lines = skip_file.read_text().splitlines()
|
||||
skip = {line.strip() for line in lines
|
||||
if line.strip() and not line.strip().startswith("#")}
|
||||
print("Skip list:", ", ".join(skip) if skip else "(none)")
|
||||
return skip
|
||||
|
||||
|
||||
# ----------------------------------------
|
||||
# Setup paths
|
||||
# ----------------------------------------
|
||||
|
||||
script_dir = Path(__file__).parent.resolve()
|
||||
services_dir = (script_dir / "..").resolve()
|
||||
api_dir = services_dir / "FictionArchive.API"
|
||||
|
||||
print(f"Script dir: {script_dir}")
|
||||
print(f"Services dir: {services_dir}")
|
||||
|
||||
skip_file = script_dir / "gateway_skip.txt"
|
||||
skip_list = load_skip_list(skip_file)
|
||||
|
||||
# ----------------------------------------
|
||||
# Find services
|
||||
# ----------------------------------------
|
||||
|
||||
print("\n----------------------------------------")
|
||||
print(" Finding GraphQL services...")
|
||||
print("----------------------------------------")
|
||||
|
||||
service_dirs = [
|
||||
d for d in services_dir.glob("FictionArchive.Service.*")
|
||||
if d.is_dir()
|
||||
]
|
||||
|
||||
selected_services = []
|
||||
|
||||
for d in service_dirs:
|
||||
name = d.name
|
||||
if name in skip_list:
|
||||
print(f"Skipping: {name}")
|
||||
else:
|
||||
print(f"Found: {name}")
|
||||
selected_services.append(d)
|
||||
|
||||
if not selected_services:
|
||||
print("No services to process. Exiting.")
|
||||
sys.exit(0)
|
||||
|
||||
# ----------------------------------------
|
||||
# Export + pack
|
||||
# ----------------------------------------
|
||||
|
||||
print("\n----------------------------------------")
|
||||
print(" Exporting schemas & packing subgraphs...")
|
||||
print("----------------------------------------")
|
||||
|
||||
for svc in selected_services:
|
||||
name = svc.name
|
||||
print(f"\nProcessing {name}")
|
||||
|
||||
# Build once
|
||||
run(["dotnet", "build", "-c", "Release"], cwd=svc)
|
||||
|
||||
# Export schema
|
||||
run([
|
||||
"dotnet", "run",
|
||||
"--no-build",
|
||||
"--no-launch-profile",
|
||||
"--",
|
||||
"schema", "export",
|
||||
"--output", "schema.graphql"
|
||||
], cwd=svc)
|
||||
|
||||
# Pack subgraph
|
||||
run(["fusion", "subgraph", "pack"], cwd=svc)
|
||||
|
||||
# ----------------------------------------
|
||||
# Compose gateway
|
||||
# ----------------------------------------
|
||||
|
||||
print("\n----------------------------------------")
|
||||
print(" Running fusion compose...")
|
||||
print("----------------------------------------")
|
||||
|
||||
if not api_dir.exists():
|
||||
print(f"ERROR: FictionArchive.API not found at {api_dir}")
|
||||
sys.exit(1)
|
||||
|
||||
gateway_file = api_dir / "gateway.fgp"
|
||||
if gateway_file.exists():
|
||||
gateway_file.unlink()
|
||||
|
||||
for svc in selected_services:
|
||||
name = svc.name
|
||||
print(f"Composing: {name}")
|
||||
|
||||
run([
|
||||
"fusion", "compose",
|
||||
"-p", "gateway.fgp",
|
||||
"-s", f"..{os.sep}{name}"
|
||||
], cwd=api_dir)
|
||||
|
||||
print("\n----------------------------------------")
|
||||
print(" Fusion build complete!")
|
||||
print("----------------------------------------")
|
||||
@@ -1,112 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
###############################################
|
||||
# Resolve important directories
|
||||
###############################################
|
||||
|
||||
# Directory where this script lives
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Services live one directory above the script's directory
|
||||
SERVICES_DIR="$(cd "$ROOT/.." && pwd)"
|
||||
|
||||
###############################################
|
||||
# Skip list (folder names, match exactly)
|
||||
###############################################
|
||||
SKIP_FILE="$ROOT/gateway_skip.txt"
|
||||
SKIP_PROJECTS=()
|
||||
|
||||
if [[ -f "$SKIP_FILE" ]]; then
|
||||
# Read non-empty lines ignoring comments
|
||||
while IFS= read -r line; do
|
||||
[[ -z "$line" || "$line" =~ ^# ]] && continue
|
||||
SKIP_PROJECTS+=("$line")
|
||||
done < "$SKIP_FILE"
|
||||
else
|
||||
echo "WARNING: skip-projects.txt not found — no projects will be skipped."
|
||||
fi
|
||||
|
||||
echo "----------------------------------------"
|
||||
echo " Finding GraphQL services..."
|
||||
echo "----------------------------------------"
|
||||
|
||||
SERVICE_LIST=()
|
||||
|
||||
# Convert skip projects into a single searchable string
|
||||
SKIP_STRING=" ${SKIP_PROJECTS[*]} "
|
||||
|
||||
# Find service directories
|
||||
shopt -s nullglob
|
||||
for FOLDER in "$SERVICES_DIR"/FictionArchive.Service.*; do
|
||||
[ -d "$FOLDER" ] || continue
|
||||
|
||||
PROJECT_NAME="$(basename "$FOLDER")"
|
||||
|
||||
# Skip entries that match the skip list
|
||||
if [[ "$SKIP_STRING" == *" $PROJECT_NAME "* ]]; then
|
||||
echo "Skipping service: $PROJECT_NAME"
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "Found service: $PROJECT_NAME"
|
||||
SERVICE_LIST+=("$FOLDER")
|
||||
done
|
||||
shopt -u nullglob
|
||||
|
||||
echo
|
||||
echo "----------------------------------------"
|
||||
echo " Exporting schemas and packing subgraphs..."
|
||||
echo "----------------------------------------"
|
||||
|
||||
for SERVICE in "${SERVICE_LIST[@]}"; do
|
||||
PROJECT_NAME="$(basename "$SERVICE")"
|
||||
|
||||
echo "Processing service: $PROJECT_NAME"
|
||||
pushd "$SERVICE" >/dev/null
|
||||
|
||||
echo "Building service..."
|
||||
dotnet build -c Release >/dev/null
|
||||
|
||||
# Automatically detect built DLL in bin/Release/<TFM>/
|
||||
DLL_PATH="$(find "bin/Release" -maxdepth 3 -name '*.dll' | head -n 1)"
|
||||
if [[ -z "$DLL_PATH" ]]; then
|
||||
echo "ERROR: Could not locate DLL for $PROJECT_NAME"
|
||||
popd >/dev/null
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Running schema export..."
|
||||
dotnet exec "$DLL_PATH" schema export --output schema.graphql
|
||||
|
||||
echo "Running subgraph pack..."
|
||||
fusion subgraph pack
|
||||
|
||||
popd >/dev/null
|
||||
echo "Completed: $PROJECT_NAME"
|
||||
echo
|
||||
done
|
||||
|
||||
echo "----------------------------------------"
|
||||
echo " Running fusion compose..."
|
||||
echo "----------------------------------------"
|
||||
|
||||
pushd "$ROOT" >/dev/null
|
||||
|
||||
# Remove old composition file
|
||||
rm -f gateway.fgp
|
||||
|
||||
for SERVICE in "${SERVICE_LIST[@]}"; do
|
||||
SERVICE_NAME="$(basename "$SERVICE")"
|
||||
|
||||
echo "Composing subgraph: $SERVICE_NAME"
|
||||
|
||||
# Note: Fusion compose must reference parent dir (services live above ROOT)
|
||||
fusion compose -p gateway.fgp -s "../$SERVICE_NAME"
|
||||
done
|
||||
|
||||
popd >/dev/null
|
||||
|
||||
echo "----------------------------------------"
|
||||
echo " Fusion build complete!"
|
||||
echo "----------------------------------------"
|
||||
Reference in New Issue
Block a user