Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
W
WebAgent
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
xuchentao
WebAgent
Commits
331123b5
Commit
331123b5
authored
Jul 15, 2026
by
xuchentao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor: move previews outside runtime directory
parent
bd42cab9
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
42 additions
and
9 deletions
+42
-9
.env.example
.env.example
+2
-0
README.md
README.md
+2
-1
build-manager.ts
backend/src/build/build-manager.ts
+1
-1
config.ts
backend/src/config.ts
+5
-1
server.ts
backend/src/server.ts
+1
-1
site-repository.ts
backend/src/sites/site-repository.ts
+25
-0
webagent.conf
deploy/nginx/webagent.conf
+1
-1
storage-convention.md
docs/storage-convention.md
+5
-4
No files found.
.env.example
View file @
331123b5
...
...
@@ -5,6 +5,8 @@ FRONTEND_ORIGIN=http://localhost
WEBAGENT_USER_PASSWORD=user
# 相对路径以 WebAgent 项目根目录为基准,也支持 /data/WebAgent-sites 等绝对路径。
WEBAGENT_SITES_DIR=../WebAgent-sites
# 测试预览静态产物独立保存,便于直接查看,也不会随运行缓存清理。
WEBAGENT_PREVIEWS_DIR=../WebAgent-previews
# 已上线的静态产物独立保存,不会被测试环境构建覆盖。
WEBAGENT_PRODUCTION_DIR=../WebAgent-production
# 自定义域名使用单独的根路径构建产物,不会覆盖上面的生产目录。
...
...
README.md
View file @
331123b5
...
...
@@ -21,6 +21,7 @@ pnpm dev
```
bash
WEBAGENT_SITES_DIR
=
../WebAgent-sites
WEBAGENT_PREVIEWS_DIR
=
../WebAgent-previews
WEBAGENT_PRODUCTION_DIR
=
../WebAgent-production
# 或 WEBAGENT_SITES_DIR=/data/WebAgent-sites
```
...
...
@@ -53,6 +54,6 @@ WEBAGENT_PRODUCTION_DIR=../WebAgent-production
-
可接入 Cloudflare for SaaS 自动创建 Custom Hostname、展示证书验证记录并跟踪 HTTPS 状态
-
自定义域名使用独立根路径产物,域名故障不影响系统默认生产链接
-
浏览 Git 历史并安全回滚到任意版本
-
生成站点保存在独立的可配置目录,构建缓存等临时数据隔离在
`.runtime/`
-
生成站点
、测试预览和生产产物
保存在独立的可配置目录,构建缓存等临时数据隔离在
`.runtime/`
详细目录约束见
[
docs/storage-convention.md
](
docs/storage-convention.md
)
,Agent 写入规则见
[
docs/site-patch-schema.md
](
docs/site-patch-schema.md
)
。
backend/src/build/build-manager.ts
View file @
331123b5
...
...
@@ -35,7 +35,7 @@ export class BuildManager {
}
async
publishPreview
(
siteId
:
string
,
distPath
:
string
):
Promise
<
string
>
{
return
this
.
publishAtomically
(
path
.
join
(
runtimePaths
.
previews
,
siteId
),
distPath
);
return
this
.
publishAtomically
(
path
.
join
(
config
.
previewsDir
,
siteId
),
distPath
);
}
async
publishProduction
(
siteId
:
string
,
distPath
:
string
):
Promise
<
string
>
{
...
...
backend/src/config.ts
View file @
331123b5
...
...
@@ -8,6 +8,10 @@ const configuredSitesDir = process.env.WEBAGENT_SITES_DIR?.trim() || "../WebAgen
const
sitesDir
=
path
.
isAbsolute
(
configuredSitesDir
)
?
configuredSitesDir
:
path
.
resolve
(
rootDir
,
configuredSitesDir
);
const
configuredPreviewsDir
=
process
.
env
.
WEBAGENT_PREVIEWS_DIR
?.
trim
()
||
"../WebAgent-previews"
;
const
previewsDir
=
path
.
isAbsolute
(
configuredPreviewsDir
)
?
configuredPreviewsDir
:
path
.
resolve
(
rootDir
,
configuredPreviewsDir
);
const
configuredProductionDir
=
process
.
env
.
WEBAGENT_PRODUCTION_DIR
?.
trim
()
||
"../WebAgent-production"
;
const
productionDir
=
path
.
isAbsolute
(
configuredProductionDir
)
?
configuredProductionDir
...
...
@@ -26,6 +30,7 @@ export const config = {
runtimeDir
:
path
.
resolve
(
currentDir
,
"../../.runtime"
),
templateDir
:
path
.
resolve
(
currentDir
,
"../../astro-template"
),
sitesDir
,
previewsDir
,
productionDir
,
customDomainsDir
,
host
:
process
.
env
.
HOST
||
"127.0.0.1"
,
...
...
@@ -59,7 +64,6 @@ export const config = {
export
const
runtimePaths
=
{
sites
:
config
.
sitesDir
,
builds
:
path
.
join
(
config
.
runtimeDir
,
"builds"
),
previews
:
path
.
join
(
config
.
runtimeDir
,
"previews"
),
uploads
:
path
.
join
(
config
.
runtimeDir
,
"uploads"
),
pnpmStore
:
path
.
join
(
config
.
runtimeDir
,
"pnpm-store"
),
logs
:
path
.
join
(
config
.
runtimeDir
,
"logs"
),
...
...
backend/src/server.ts
View file @
331123b5
...
...
@@ -128,7 +128,7 @@ for (let site of await sites.list()) {
await
versions
.
rebuild
(
site
.
siteId
).
catch
((
error
)
=>
app
.
log
.
warn
(
error
));
site
=
await
sites
.
get
(
site
.
siteId
);
}
const
previewPath
=
path
.
join
(
runtimePaths
.
previews
,
site
.
siteId
);
const
previewPath
=
path
.
join
(
config
.
previewsDir
,
site
.
siteId
);
if
(
await
access
(
previewPath
).
then
(()
=>
true
).
catch
(()
=>
false
))
{
await
previews
.
start
(
site
.
siteId
,
previewPath
,
site
.
previewPort
)
.
then
(
async
()
=>
sites
.
update
(
site
.
siteId
,
{
...
...
backend/src/sites/site-repository.ts
View file @
331123b5
...
...
@@ -77,10 +77,12 @@ export class SiteRepository {
private
async
initializeRuntime
():
Promise
<
void
>
{
await
Promise
.
all
([
...
Object
.
values
(
runtimePaths
).
map
((
directory
)
=>
mkdir
(
directory
,
{
recursive
:
true
})),
mkdir
(
config
.
previewsDir
,
{
recursive
:
true
}),
mkdir
(
config
.
productionDir
,
{
recursive
:
true
}),
mkdir
(
config
.
customDomainsDir
,
{
recursive
:
true
}),
]);
await
this
.
migrateLegacySites
();
await
this
.
migrateLegacyPreviews
();
}
private
async
migrateLegacySites
():
Promise
<
void
>
{
...
...
@@ -105,4 +107,27 @@ export class SiteRepository {
}
}
}
private
async
migrateLegacyPreviews
():
Promise
<
void
>
{
const
legacyPreviewsDir
=
path
.
join
(
config
.
runtimeDir
,
"previews"
);
if
(
path
.
resolve
(
legacyPreviewsDir
)
===
path
.
resolve
(
config
.
previewsDir
))
return
;
const
legacyExists
=
await
stat
(
legacyPreviewsDir
).
then
((
value
)
=>
value
.
isDirectory
()).
catch
(()
=>
false
);
if
(
!
legacyExists
)
return
;
const
entries
=
await
readdir
(
legacyPreviewsDir
,
{
withFileTypes
:
true
});
for
(
const
entry
of
entries
)
{
if
(
!
entry
.
isDirectory
()
||
!
/^site_
[
a-z0-9
]
+$/
.
test
(
entry
.
name
))
continue
;
const
source
=
path
.
join
(
legacyPreviewsDir
,
entry
.
name
);
const
destination
=
path
.
join
(
config
.
previewsDir
,
entry
.
name
);
const
destinationExists
=
await
stat
(
destination
).
then
(()
=>
true
).
catch
(()
=>
false
);
if
(
destinationExists
)
continue
;
try
{
await
rename
(
source
,
destination
);
}
catch
(
error
)
{
if
(
!
(
error
instanceof
Error
)
||
!
(
"code"
in
error
)
||
error
.
code
!==
"EXDEV"
)
throw
error
;
await
cp
(
source
,
destination
,
{
recursive
:
true
,
errorOnExist
:
true
});
await
rm
(
source
,
{
recursive
:
true
,
force
:
true
});
}
}
}
}
deploy/nginx/webagent.conf
View file @
331123b5
...
...
@@ -48,7 +48,7 @@ server {
}
location
/
previews
/ {
alias
/
Users
/
mac
/
Desktop
/
code
/
WebAgent
/.
runtime
/
previews
/;
alias
/
Users
/
mac
/
Desktop
/
code
/
WebAgent
-
previews
/;
index
index
.
html
;
add_header
Cache
-
Control
"no-store"
always
;
}
...
...
docs/storage-convention.md
View file @
331123b5
# 本地存储规范
生成站点源码、测试构建和生产产物分开保存。
`.env`
中默认配置为
`WEBAGENT_SITES_DIR=../WebAgent-sites`
、
`WEBAGENT_PRODUCTION_DIR=../WebAgent-production`
,相对路径以 WebAgent 项目根目录为基准,也可以指定绝对路径。
生成站点源码、测试构建和生产产物分开保存。
`.env`
中默认配置为
`WEBAGENT_SITES_DIR=../WebAgent-sites`
、
`WEBAGENT_PR
EVIEWS_DIR=../WebAgent-previews`
、
`WEBAGENT_PR
ODUCTION_DIR=../WebAgent-production`
,相对路径以 WebAgent 项目根目录为基准,也可以指定绝对路径。
```
text
WebAgent-sites/
...
...
@@ -10,6 +10,9 @@ WebAgent-sites/
└── metadata/
└── site.json # WebAgent 管理信息,不交给 Agent 修改
WebAgent-previews/
└── site_xxxxxx/ # 当前代码最近一次构建成功的测试产物
WebAgent-production/
└── site_xxxxxx/ # 用户确认发布的生产静态产物
...
...
@@ -20,15 +23,13 @@ WebAgent/.runtime/
├── builds/
│ └── task_xxxxxx/
│ └── workspace/ # 临时 Git Worktree,任务结束必须删除
├── previews/
│ └── site_xxxxxx/ # 当前代码最近一次构建成功的测试产物
├── uploads/ # 原始上传文件的临时落点
├── pnpm-store/ # 所有生成站点共享的 pnpm store
├── logs/ # Agent 与构建日志
└── nginx/ # 根据已验证域名生成的 Host 路由映射
```
`WebAgent-sites/`
、
`WebAgent-pr
oduction/`
和
`WebAgent-custom-domains/`
是持久数据,应纳入服务器备份;
`.runtime/`
是可重建的测试与运行缓存,不提交 Git。修改路径配置后,系统不会自动迁移外部目录之间的数据,需要由管理员手动移动。旧版本位于
`.runtime/sites/`
的站点
会在首次启动时自动迁移到当前配置目录。
`WebAgent-sites/`
、
`WebAgent-pr
eviews/`
、
`WebAgent-production/`
和
`WebAgent-custom-domains/`
位于项目外部,便于直接查看和按需备份;
`.runtime/`
是可重建的运行缓存,不提交 Git。修改路径配置后,系统不会自动迁移外部目录之间的数据,需要由管理员手动移动。旧版本位于
`.runtime/sites/`
的站点和
`.runtime/previews/`
的测试产物
会在首次启动时自动迁移到当前配置目录。
## 不变量
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment