diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml index b795a530..33805c4c 100644 --- a/.gitea/workflows/deploy.yaml +++ b/.gitea/workflows/deploy.yaml @@ -33,6 +33,14 @@ jobs: # 2. Navigate to your website directory cd /var/www/atom-nexst/ + DEPLOY_USER="$(id -un)" + DEPLOY_GROUP="$(id -gn)" + + # CRITICAL: last deploy chowns the tree to www-data. Reclaim ownership + # BEFORE git reset, otherwise stale sources (e.g. old nitro editor with + # a removed Json type) can survive and break typecheck. + sudo chown -R "${DEPLOY_USER}:${DEPLOY_GROUP}" /var/www/atom-nexst/ + # CRITICAL: Prevent Git permission blocks caused by the www-data ownership change git config --global --add safe.directory /var/www/atom-nexst @@ -44,6 +52,8 @@ jobs: git reset --hard origin/main # Drop stray untracked sources left on the host (keep secrets/env). git clean -fd -e .env -e .env.local -e .env.production -e .env*.local -- src + # Force-refresh sources after reclaiming ownership (belt-and-suspenders). + git checkout -f HEAD -- src # Preserve .next/cache so Next.js can reuse its incremental build cache. rm -rf .output dist @@ -53,6 +63,12 @@ jobs: export NEXT_PUBLIC_APP_VERSION="${APP_VERSION}" echo "APP_VERSION=${APP_VERSION}" + # Fail fast if a host-local stale copy still has the removed Json type. + if grep -nE ':\s*Json\b|Json\s*\|' src/app/admin/import/furni/nitro-editor-dialog.tsx; then + echo "ERROR: nitro-editor-dialog.tsx still contains a Json type after checkout" >&2 + exit 1 + fi + # 4. Install — onlyBuiltDependencies comes from pnpm-workspace.yaml # (do not set a PNPM only-built-deps env override here). pnpm install --frozen-lockfile diff --git a/src/app/admin/import/furni/nitro-editor-dialog.tsx b/src/app/admin/import/furni/nitro-editor-dialog.tsx index 352b0fd7..c3068f93 100644 --- a/src/app/admin/import/furni/nitro-editor-dialog.tsx +++ b/src/app/admin/import/furni/nitro-editor-dialog.tsx @@ -39,6 +39,7 @@ interface NitroEditorDialogProps { onOpenChange: (open: boolean) => void; } +/** Nested metadata patch helpers (no ambient Json type — keep this file typecheck-clean). */ function updateNested( obj: Record, path: string, diff --git a/src/lib/deploy-workflow-contract.test.ts b/src/lib/deploy-workflow-contract.test.ts index 65c72c51..32593a96 100644 --- a/src/lib/deploy-workflow-contract.test.ts +++ b/src/lib/deploy-workflow-contract.test.ts @@ -15,6 +15,16 @@ describe("production deploy workflow", () => { expect(workflow).toContain("SKIP_ENV_VALIDATION=1"); }); + it("reclaims ownership before git reset so www-data files can be overwritten", () => { + expect(workflow).toContain('sudo chown -R "${DEPLOY_USER}:${DEPLOY_GROUP}"'); + const reclaimAt = workflow.indexOf( + 'sudo chown -R "${DEPLOY_USER}:${DEPLOY_GROUP}"', + ); + const resetAt = workflow.indexOf("git reset --hard origin/main"); + expect(reclaimAt).toBeGreaterThan(-1); + expect(resetAt).toBeGreaterThan(reclaimAt); + }); + it("does not override onlyBuiltDependencies (uses pnpm-workspace.yaml)", () => { expect(workflow).not.toContain("PNPM_CONFIG_ONLY_BUILT_DEPENDENCIES"); });