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
10c7988e
Commit
10c7988e
authored
Jul 15, 2026
by
xuchentao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: simplify version preview and release workflow
parent
2d6e5007
Changes
12
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
180 additions
and
82 deletions
+180
-82
build-manager.ts
backend/src/build/build-manager.ts
+14
-8
git-manager.ts
backend/src/git/git-manager.ts
+6
-0
schemas.ts
backend/src/schemas.ts
+1
-1
server.ts
backend/src/server.ts
+6
-4
create-site.ts
backend/src/sites/create-site.ts
+2
-1
site-agent-service.ts
backend/src/sites/site-agent-service.ts
+8
-2
site-repository.ts
backend/src/sites/site-repository.ts
+2
-1
site-version-service.ts
backend/src/sites/site-version-service.ts
+63
-20
App.tsx
frontend/src/App.tsx
+65
-42
api.ts
frontend/src/api.ts
+3
-2
styles.css
frontend/src/styles.css
+3
-1
index.ts
shared/src/index.ts
+7
-0
No files found.
backend/src/build/build-manager.ts
View file @
10c7988e
...
...
@@ -35,11 +35,24 @@ export class BuildManager {
}
async
publishPreview
(
siteId
:
string
,
distPath
:
string
):
Promise
<
string
>
{
return
this
.
publish
To
(
path
.
join
(
runtimePaths
.
previews
,
siteId
),
distPath
);
return
this
.
publish
Atomically
(
path
.
join
(
runtimePaths
.
previews
,
siteId
),
distPath
);
}
async
publishProduction
(
siteId
:
string
,
distPath
:
string
):
Promise
<
string
>
{
return
this
.
publishAtomically
(
path
.
join
(
config
.
productionDir
,
siteId
),
distPath
);
}
async
ensureProductionPlaceholder
(
siteId
:
string
,
siteName
:
string
):
Promise
<
string
>
{
const
target
=
path
.
join
(
config
.
productionDir
,
siteId
);
const
indexPath
=
path
.
join
(
target
,
"index.html"
);
if
(
await
stat
(
indexPath
).
then
((
value
)
=>
value
.
isFile
()).
catch
(()
=>
false
))
return
target
;
const
safeName
=
siteName
.
replaceAll
(
"&"
,
"&"
).
replaceAll
(
"<"
,
"<"
).
replaceAll
(
">"
,
">"
);
await
mkdir
(
target
,
{
recursive
:
true
});
await
writeFile
(
indexPath
,
`<!doctype html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width"><title>
${
safeName
}
|尚未上线</title><style>body{margin:0;min-height:100vh;display:grid;place-items:center;color:#24242f;background:#f7f7fb;font-family:system-ui,"PingFang SC",sans-serif}.card{max-width:420px;padding:42px;text-align:center;background:white;border:1px solid #e8e5f1;border-radius:24px;box-shadow:0 22px 60px rgba(36,16,95,.09)}span{display:grid;place-items:center;width:48px;height:48px;margin:auto;color:white;background:linear-gradient(135deg,#7028ff,#536cff);border-radius:15px;font-weight:800}h1{margin:20px 0 10px;font-size:24px}p{margin:0;color:#777985;font-size:14px;line-height:1.8}</style></head><body><main class="card"><span>W</span><h1>
${
safeName
}
</h1><p>该官网尚未上线。<br>请先在测试环境确认效果后发布。</p></main></body></html>`
,
"utf8"
);
return
target
;
}
private
async
publishAtomically
(
target
:
string
,
distPath
:
string
):
Promise
<
string
>
{
const
suffix
=
crypto
.
randomBytes
(
4
).
toString
(
"hex"
);
const
staging
=
target
+
".next-"
+
suffix
;
const
previous
=
target
+
".previous-"
+
suffix
;
...
...
@@ -57,11 +70,4 @@ export class BuildManager {
await
rm
(
previous
,
{
recursive
:
true
,
force
:
true
});
return
target
;
}
private
async
publishTo
(
target
:
string
,
distPath
:
string
):
Promise
<
string
>
{
await
rm
(
target
,
{
recursive
:
true
,
force
:
true
});
await
mkdir
(
path
.
dirname
(
target
),
{
recursive
:
true
});
await
cp
(
distPath
,
target
,
{
recursive
:
true
});
return
target
;
}
}
backend/src/git/git-manager.ts
View file @
10c7988e
...
...
@@ -24,6 +24,12 @@ export class GitManager {
return
result
.
stdout
.
trim
();
}
async
previousCommit
(
projectPath
:
string
,
commit
=
"HEAD"
):
Promise
<
string
|
undefined
>
{
await
this
.
assertCommit
(
projectPath
,
commit
);
const
result
=
await
execa
(
"git"
,
[
"rev-list"
,
"--parents"
,
"-n"
,
"1"
,
commit
],
{
cwd
:
projectPath
});
return
result
.
stdout
.
trim
().
split
(
/
\s
+/
)[
1
];
}
async
history
(
projectPath
:
string
):
Promise
<
GitHistoryItem
[]
>
{
const
current
=
await
this
.
currentCommit
(
projectPath
);
const
result
=
await
execa
(
"git"
,
[
"log"
,
"--date=iso-strict"
,
"--format=%H%x1f%h%x1f%s%x1f%an%x1f%cI%x1e"
,
"-30"
],
{
cwd
:
projectPath
});
...
...
backend/src/schemas.ts
View file @
10c7988e
...
...
@@ -14,7 +14,7 @@ export const chatSchema = z.object({
message
:
z
.
string
().
trim
().
min
(
2
).
max
(
2000
),
});
export
const
rollback
Schema
=
z
.
object
({
export
const
versionCommit
Schema
=
z
.
object
({
commit
:
z
.
string
().
regex
(
/^
[
0-9a-f
]{7,40}
$/
),
});
...
...
backend/src/server.ts
View file @
10c7988e
...
...
@@ -8,7 +8,7 @@ import { BuildManager } from "./build/build-manager.js";
import
{
config
,
runtimePaths
}
from
"./config.js"
;
import
{
GitManager
}
from
"./git/git-manager.js"
;
import
{
PreviewProcessManager
}
from
"./preview/preview-process-manager.js"
;
import
{
chatSchema
,
createSiteSchema
,
rollback
Schema
}
from
"./schemas.js"
;
import
{
chatSchema
,
createSiteSchema
,
versionCommit
Schema
}
from
"./schemas.js"
;
import
{
CreateSiteService
}
from
"./sites/create-site.js"
;
import
{
SiteAgentService
}
from
"./sites/site-agent-service.js"
;
import
{
SiteRepository
}
from
"./sites/site-repository.js"
;
...
...
@@ -33,11 +33,12 @@ app.post<{ Params: { siteId: string } }>("/api/sites/:siteId/chat", async (reque
const
body
=
chatSchema
.
parse
(
request
.
body
);
return
siteAgent
.
execute
(
request
.
params
.
siteId
,
body
.
message
);
});
app
.
post
<
{
Params
:
{
siteId
:
string
}
}
>
(
"/api/sites/:siteId/build"
,
async
(
request
)
=>
versions
.
rebuild
(
request
.
params
.
siteId
));
app
.
post
<
{
Params
:
{
siteId
:
string
}
}
>
(
"/api/sites/:siteId/preview-version"
,
async
(
request
)
=>
{
const
body
=
versionCommitSchema
.
parse
(
request
.
body
);
return
versions
.
previewVersion
(
request
.
params
.
siteId
,
body
.
commit
);
});
app
.
post
<
{
Params
:
{
siteId
:
string
}
}
>
(
"/api/sites/:siteId/publish"
,
async
(
request
)
=>
versions
.
publish
(
request
.
params
.
siteId
));
app
.
get
<
{
Params
:
{
siteId
:
string
}
}
>
(
"/api/sites/:siteId/history"
,
async
(
request
)
=>
git
.
history
(
sites
.
getProjectPath
(
request
.
params
.
siteId
)));
app
.
post
<
{
Params
:
{
siteId
:
string
}
}
>
(
"/api/sites/:siteId/rollback"
,
async
(
request
)
=>
{
const
body
=
rollbackSchema
.
parse
(
request
.
body
);
return
versions
.
rollback
(
request
.
params
.
siteId
,
body
.
commit
);
});
app
.
post
<
{
Params
:
{
siteId
:
string
}
}
>
(
"/api/sites/:siteId/undo"
,
async
(
request
)
=>
versions
.
undo
(
request
.
params
.
siteId
));
app
.
setErrorHandler
((
error
,
_request
,
reply
)
=>
{
const
isMissingFile
=
error
instanceof
Error
&&
"code"
in
error
&&
error
.
code
===
"ENOENT"
;
...
...
@@ -54,6 +55,7 @@ await rm(runtimePaths.builds, { recursive: true, force: true });
await
mkdir
(
runtimePaths
.
builds
,
{
recursive
:
true
});
for
(
const
site
of
await
sites
.
list
())
{
await
git
.
pruneWorktrees
(
sites
.
getProjectPath
(
site
.
siteId
));
await
builds
.
ensureProductionPlaceholder
(
site
.
siteId
,
site
.
name
);
if
(
site
.
environmentVersion
!==
3
)
{
await
versions
.
rebuild
(
site
.
siteId
).
catch
((
error
)
=>
app
.
log
.
warn
(
error
));
continue
;
...
...
backend/src/sites/create-site.ts
View file @
10c7988e
...
...
@@ -48,7 +48,8 @@ export class CreateSiteService {
await
this
.
sites
.
update
(
siteId
,
{
currentCommit
:
commit
});
const
published
=
await
this
.
builds
.
publishPreview
(
siteId
,
dist
);
await
this
.
previews
.
start
(
siteId
,
published
,
previewPort
);
return
await
this
.
sites
.
update
(
siteId
,
{
status
:
"ready"
,
currentCommit
:
commit
,
lastError
:
undefined
});
await
this
.
builds
.
ensureProductionPlaceholder
(
siteId
,
input
.
name
);
return
await
this
.
sites
.
update
(
siteId
,
{
status
:
"ready"
,
currentCommit
:
commit
,
previewCommit
:
commit
,
lastError
:
undefined
});
}
catch
(
error
)
{
const
message
=
error
instanceof
Error
?
error
.
message
:
String
(
error
);
await
this
.
sites
.
update
(
siteId
,
{
status
:
"failed"
,
lastError
:
message
});
...
...
backend/src/sites/site-agent-service.ts
View file @
10c7988e
...
...
@@ -19,6 +19,9 @@ export class SiteAgentService {
async
execute
(
siteId
:
string
,
message
:
string
):
Promise
<
ChatResult
>
{
const
site
=
await
this
.
sites
.
get
(
siteId
);
if
(
site
.
previewCommit
&&
site
.
previewCommit
!==
site
.
currentCommit
)
{
throw
new
Error
(
"当前测试环境正在预览历史版本,请先切换到最近保存版本再继续修改"
);
}
const
projectPath
=
this
.
sites
.
getProjectPath
(
siteId
);
const
taskId
=
"task_"
+
crypto
.
randomBytes
(
4
).
toString
(
"hex"
);
const
workspace
=
path
.
join
(
runtimePaths
.
builds
,
taskId
,
"workspace"
);
...
...
@@ -49,11 +52,14 @@ export class SiteAgentService {
const
commit
=
await
this
.
git
.
cherryPick
(
projectPath
,
worktreeCommit
);
const
published
=
await
this
.
builds
.
publishPreview
(
siteId
,
dist
);
await
this
.
previews
.
start
(
siteId
,
published
,
site
.
previewPort
);
await
this
.
sites
.
update
(
siteId
,
{
status
:
"ready"
,
currentCommit
:
commit
,
environmentVersion
:
3
,
lastError
:
undefined
});
await
this
.
sites
.
update
(
siteId
,
{
status
:
"ready"
,
currentCommit
:
commit
,
previewCommit
:
commit
,
previousCommit
:
site
.
currentCommit
,
environmentVersion
:
3
,
lastError
:
undefined
,
});
return
{
summary
:
generated
.
patch
.
summary
,
commit
,
previewUrl
:
site
.
previewUrl
,
changedFiles
,
mode
:
generated
.
mode
};
}
catch
(
error
)
{
const
details
=
error
instanceof
BuildError
?
error
.
output
.
slice
(
-
3000
)
:
error
instanceof
Error
?
error
.
message
:
String
(
error
);
await
this
.
sites
.
update
(
siteId
,
{
status
:
"failed"
,
lastError
:
details
});
await
this
.
sites
.
update
(
siteId
,
{
status
:
site
.
previewCommit
?
"ready"
:
"failed"
,
lastError
:
details
});
throw
error
;
}
finally
{
await
this
.
git
.
removeWorktree
(
projectPath
,
workspace
);
...
...
backend/src/sites/site-repository.ts
View file @
10c7988e
...
...
@@ -30,7 +30,8 @@ export class SiteRepository {
return
{
...
stored
,
previewUrl
:
getPublicPreviewUrl
(
siteId
),
productionUrl
:
stored
.
publishedCommit
?
getPublicProductionUrl
(
siteId
)
:
undefined
,
previewCommit
:
stored
.
previewCommit
||
stored
.
currentCommit
,
productionUrl
:
getPublicProductionUrl
(
siteId
),
publishStatus
:
stored
.
publishStatus
||
(
stored
.
publishedCommit
?
"published"
:
"unpublished"
),
};
}
...
...
backend/src/sites/site-version-service.ts
View file @
10c7988e
import
crypto
from
"node:crypto"
;
import
path
from
"node:path"
;
import
type
{
P
ublishResult
}
from
"@webagent/shared"
;
import
type
{
P
reviewVersionResult
,
PublishResult
,
SiteInfo
}
from
"@webagent/shared"
;
import
{
getPublicPreviewUrl
,
getPublicProductionUrl
,
runtimePaths
}
from
"../config.js"
;
import
{
BuildError
,
BuildManager
}
from
"../build/build-manager.js"
;
import
{
GitManager
}
from
"../git/git-manager.js"
;
...
...
@@ -15,42 +15,53 @@ export class SiteVersionService {
)
{}
async
rebuild
(
siteId
:
string
):
Promise
<
{
previewUrl
:
string
}
>
{
const
site
=
await
this
.
sites
.
get
(
siteId
);
const
project
=
this
.
sites
.
getProjectPath
(
siteId
);
const
site
=
await
this
.
sites
.
get
(
siteId
);
let
currentCommit
=
await
this
.
git
.
currentCommit
(
project
);
let
previewCommit
=
site
.
previewCommit
||
site
.
currentCommit
||
currentCommit
;
if
(
await
ensureEnvironmentConfig
(
project
))
{
await
this
.
git
.
commit
(
project
,
"System: support preview and production paths"
);
}
await
this
.
sites
.
update
(
siteId
,
{
status
:
"building"
,
lastError
:
undefined
});
try
{
const
dist
=
await
this
.
builds
.
build
(
project
,
"rebuild_"
+
siteId
,
getPublicPreviewUrl
(
siteId
));
const
published
=
await
this
.
builds
.
publishPreview
(
siteId
,
dist
);
await
this
.
previews
.
start
(
siteId
,
published
,
site
.
previewPort
);
await
this
.
sites
.
update
(
siteId
,
{
status
:
"ready"
,
currentCommit
:
await
this
.
git
.
currentCommit
(
project
),
environmentVersion
:
3
});
return
{
previewUrl
:
site
.
previewUrl
};
}
catch
(
error
)
{
await
this
.
sites
.
update
(
siteId
,
{
status
:
"failed"
,
lastError
:
error
instanceof
Error
?
error
.
message
:
String
(
error
)
});
throw
error
;
currentCommit
=
await
this
.
git
.
commit
(
project
,
"System: support preview and production paths"
);
if
(
previewCommit
===
site
.
currentCommit
)
previewCommit
=
currentCommit
;
}
await
this
.
buildPreview
(
site
,
previewCommit
,
"rebuild"
,
{
currentCommit
});
return
{
previewUrl
:
site
.
previewUrl
};
}
async
rollback
(
siteId
:
string
,
targetCommit
:
string
):
Promise
<
{
commit
:
string
;
previewUrl
:
string
}
>
{
async
previewVersion
(
siteId
:
string
,
targetCommit
:
string
):
Promise
<
PreviewVersionResult
>
{
const
site
=
await
this
.
sites
.
get
(
siteId
);
const
project
=
this
.
sites
.
getProjectPath
(
siteId
);
await
this
.
git
.
assertCommit
(
project
,
targetCommit
);
const
taskId
=
"rollback_"
+
crypto
.
randomBytes
(
4
).
toString
(
"hex"
);
await
this
.
buildPreview
(
site
,
targetCommit
,
"preview_version"
);
return
{
commit
:
targetCommit
,
previewUrl
:
site
.
previewUrl
};
}
async
undo
(
siteId
:
string
):
Promise
<
PreviewVersionResult
>
{
const
site
=
await
this
.
sites
.
get
(
siteId
);
const
project
=
this
.
sites
.
getProjectPath
(
siteId
);
if
(
site
.
previewCommit
&&
site
.
previewCommit
!==
site
.
currentCommit
)
{
throw
new
Error
(
"当前正在查看历史版本,请先切换回最近保存版本再撤销修改"
);
}
const
currentCommit
=
await
this
.
git
.
currentCommit
(
project
);
const
targetCommit
=
site
.
previousCommit
||
await
this
.
git
.
previousCommit
(
project
,
currentCommit
);
if
(
!
targetCommit
)
throw
new
Error
(
"当前没有可撤销的上一版本"
);
await
this
.
git
.
assertCommit
(
project
,
targetCommit
);
const
taskId
=
"undo_"
+
crypto
.
randomBytes
(
4
).
toString
(
"hex"
);
const
workspace
=
path
.
join
(
runtimePaths
.
builds
,
taskId
,
"workspace"
);
await
this
.
sites
.
update
(
siteId
,
{
status
:
"building"
,
lastError
:
undefined
});
try
{
await
this
.
git
.
createWorktree
(
project
,
workspace
,
targetCommit
);
await
ensureEnvironmentConfig
(
workspace
);
const
dist
=
await
this
.
builds
.
build
(
workspace
,
taskId
,
getPublicPreviewUrl
(
siteId
));
const
published
=
await
this
.
builds
.
publishPreview
(
siteId
,
dist
);
const
commit
=
await
this
.
git
.
restoreAsCommit
(
project
,
targetCommit
);
const
published
=
await
this
.
builds
.
publishPreview
(
siteId
,
dist
);
await
this
.
previews
.
start
(
siteId
,
published
,
site
.
previewPort
);
await
this
.
sites
.
update
(
siteId
,
{
status
:
"ready"
,
currentCommit
:
commit
,
environmentVersion
:
3
,
lastError
:
undefined
});
await
this
.
sites
.
update
(
siteId
,
{
status
:
"ready"
,
currentCommit
:
commit
,
previewCommit
:
commit
,
previousCommit
:
undefined
,
environmentVersion
:
3
,
lastError
:
undefined
,
});
return
{
commit
,
previewUrl
:
site
.
previewUrl
};
}
catch
(
error
)
{
await
this
.
sites
.
update
(
siteId
,
{
status
:
"failed"
,
lastError
:
error
instanceof
Error
?
error
.
message
:
String
(
error
)
});
await
this
.
sites
.
update
(
siteId
,
{
status
:
site
.
previewCommit
?
"ready"
:
"failed"
,
lastError
:
error
instanceof
Error
?
error
.
message
:
String
(
error
)
});
throw
error
;
}
finally
{
await
this
.
git
.
removeWorktree
(
project
,
workspace
);
}
}
...
...
@@ -63,8 +74,10 @@ export class SiteVersionService {
const
workspace
=
path
.
join
(
runtimePaths
.
builds
,
taskId
,
"workspace"
);
await
this
.
sites
.
update
(
siteId
,
{
publishStatus
:
"publishing"
,
lastPublishError
:
undefined
});
try
{
const
commit
=
await
this
.
git
.
currentCommit
(
project
);
const
commit
=
site
.
previewCommit
||
site
.
currentCommit
;
await
this
.
git
.
assertCommit
(
project
,
commit
);
await
this
.
git
.
createWorktree
(
project
,
workspace
,
commit
);
await
ensureEnvironmentConfig
(
workspace
);
const
dist
=
await
this
.
builds
.
build
(
workspace
,
taskId
,
getPublicProductionUrl
(
siteId
));
await
this
.
builds
.
publishProduction
(
siteId
,
dist
);
const
publishedAt
=
new
Date
().
toISOString
();
...
...
@@ -82,4 +95,34 @@ export class SiteVersionService {
await
this
.
git
.
removeWorktree
(
project
,
workspace
);
}
}
private
async
buildPreview
(
site
:
SiteInfo
,
commit
:
string
,
taskPrefix
:
string
,
metadata
:
Partial
<
SiteInfo
>
=
{},
):
Promise
<
void
>
{
const
project
=
this
.
sites
.
getProjectPath
(
site
.
siteId
);
await
this
.
git
.
assertCommit
(
project
,
commit
);
const
taskId
=
taskPrefix
+
"_"
+
crypto
.
randomBytes
(
4
).
toString
(
"hex"
);
const
workspace
=
path
.
join
(
runtimePaths
.
builds
,
taskId
,
"workspace"
);
await
this
.
sites
.
update
(
site
.
siteId
,
{
status
:
"building"
,
lastError
:
undefined
});
try
{
await
this
.
git
.
createWorktree
(
project
,
workspace
,
commit
);
await
ensureEnvironmentConfig
(
workspace
);
const
dist
=
await
this
.
builds
.
build
(
workspace
,
taskId
,
getPublicPreviewUrl
(
site
.
siteId
));
const
published
=
await
this
.
builds
.
publishPreview
(
site
.
siteId
,
dist
);
await
this
.
previews
.
start
(
site
.
siteId
,
published
,
site
.
previewPort
);
await
this
.
sites
.
update
(
site
.
siteId
,
{
...
metadata
,
status
:
"ready"
,
previewCommit
:
commit
,
environmentVersion
:
3
,
lastError
:
undefined
,
});
}
catch
(
error
)
{
const
details
=
error
instanceof
BuildError
?
error
.
output
.
slice
(
-
3000
)
:
error
instanceof
Error
?
error
.
message
:
String
(
error
);
await
this
.
sites
.
update
(
site
.
siteId
,
{
status
:
site
.
previewCommit
?
"ready"
:
"failed"
,
lastError
:
details
});
throw
error
;
}
finally
{
await
this
.
git
.
removeWorktree
(
project
,
workspace
);
}
}
}
frontend/src/App.tsx
View file @
10c7988e
This diff is collapsed.
Click to expand it.
frontend/src/api.ts
View file @
10c7988e
import
type
{
ChatResult
,
CreateSiteInput
,
GitHistoryItem
,
PublishResult
,
SiteInfo
}
from
"@webagent/shared"
;
import
type
{
ChatResult
,
CreateSiteInput
,
GitHistoryItem
,
P
reviewVersionResult
,
P
ublishResult
,
SiteInfo
}
from
"@webagent/shared"
;
async
function
request
<
T
>
(
url
:
string
,
options
?:
RequestInit
):
Promise
<
T
>
{
const
headers
=
new
Headers
(
options
?.
headers
);
...
...
@@ -19,7 +19,8 @@ export const api = {
createSite
:
(
input
:
CreateSiteInput
)
=>
request
<
SiteInfo
>
(
"/api/sites"
,
{
method
:
"POST"
,
body
:
JSON
.
stringify
(
input
)
}),
chat
:
(
siteId
:
string
,
message
:
string
)
=>
request
<
ChatResult
>
(
"/api/sites/"
+
siteId
+
"/chat"
,
{
method
:
"POST"
,
body
:
JSON
.
stringify
({
message
})
}),
history
:
(
siteId
:
string
)
=>
request
<
GitHistoryItem
[]
>
(
"/api/sites/"
+
siteId
+
"/history"
),
previewVersion
:
(
siteId
:
string
,
commit
:
string
)
=>
request
<
PreviewVersionResult
>
(
"/api/sites/"
+
siteId
+
"/preview-version"
,
{
method
:
"POST"
,
body
:
JSON
.
stringify
({
commit
})
}),
rebuild
:
(
siteId
:
string
)
=>
request
<
{
previewUrl
:
string
}
>
(
"/api/sites/"
+
siteId
+
"/build"
,
{
method
:
"POST"
}),
publish
:
(
siteId
:
string
)
=>
request
<
PublishResult
>
(
"/api/sites/"
+
siteId
+
"/publish"
,
{
method
:
"POST"
}),
rollback
:
(
siteId
:
string
,
commit
:
string
)
=>
request
<
{
commit
:
string
;
previewUrl
:
string
}
>
(
"/api/sites/"
+
siteId
+
"/rollback"
,
{
method
:
"POST"
,
body
:
JSON
.
stringify
({
commit
})
}),
undo
:
(
siteId
:
string
)
=>
request
<
PreviewVersionResult
>
(
"/api/sites/"
+
siteId
+
"/undo"
,
{
method
:
"POST"
}),
};
frontend/src/styles.css
View file @
10c7988e
This diff is collapsed.
Click to expand it.
shared/src/index.ts
View file @
10c7988e
...
...
@@ -22,6 +22,8 @@ export interface SiteInfo {
previewUrl
:
string
;
productionUrl
?:
string
;
currentCommit
:
string
;
previewCommit
?:
string
;
previousCommit
?:
string
;
publishedCommit
?:
string
;
publishedAt
?:
string
;
publishStatus
:
PublishStatus
;
...
...
@@ -61,3 +63,8 @@ export interface PublishResult {
commit
:
string
;
publishedAt
:
string
;
}
export
interface
PreviewVersionResult
{
previewUrl
:
string
;
commit
:
string
;
}
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