Keep recurring acceptance cleanup scoped to each test run
studio CI and deployment / verify-and-deploy (pull_request) Successful in 3m25s
studio CI and deployment / verify-and-deploy (pull_request) Successful in 3m25s
This commit is contained in:
@@ -5,16 +5,19 @@ async function api(path,body,method=body?'POST':'GET',status=200){const r=await
|
|||||||
if(process.argv.includes('--finalize')){
|
if(process.argv.includes('--finalize')){
|
||||||
const {results}=JSON.parse(await (await import('node:fs/promises')).readFile('/tmp/studio-library/verification.json','utf8'));
|
const {results}=JSON.parse(await (await import('node:fs/promises')).readFile('/tmp/studio-library/verification.json','utf8'));
|
||||||
const canonical='8eb8c76500580f7a4b56ba3c',legacy='9ebd8f78d54b4b9db741b4e8';
|
const canonical='8eb8c76500580f7a4b56ba3c',legacy='9ebd8f78d54b4b9db741b4e8';
|
||||||
|
let documentFailure;let category;
|
||||||
|
try{
|
||||||
const entry=(await api('/api/notes/'+canonical)).entry;
|
const entry=(await api('/api/notes/'+canonical)).entry;
|
||||||
for(const needle of ['standard-01','DELETE','revision','cropX','兼容工具原说明'])assert.ok(entry.editableMarkdown.includes(needle),needle);
|
for(const needle of ['standard-01','DELETE','revision','cropX','兼容工具原说明'])assert.ok(entry.editableMarkdown.includes(needle),needle);
|
||||||
for(const id of [canonical,legacy])assert.equal((await fetch(base+'/explore/'+id)).status,200);
|
for(const id of [canonical,legacy])assert.equal((await fetch(base+'/explore/'+id)).status,200);
|
||||||
const old=(await api('/api/notes/'+legacy)).entry;assert.ok(old.archived&&old.editableMarkdown.includes(canonical));
|
const old=(await api('/api/notes/'+legacy)).entry;assert.ok(old.archived&&old.editableMarkdown.includes(canonical));
|
||||||
const category=await api('/api/explore-feed?category='+encodeURIComponent('文档入口'));
|
category=await api('/api/explore-feed?category='+encodeURIComponent('文档入口'));
|
||||||
assert.equal(category.total,3);assert.equal(category.nextCursor,null);
|
assert.equal(category.total,3);assert.equal(category.nextCursor,null);
|
||||||
assert.deepEqual(category.entries.map(e=>e.id).sort(),['3c98946754c33309d73d5284','4ce3283fd98bb03a8fb39a19',canonical].sort());
|
assert.deepEqual(category.entries.map(e=>e.id).sort(),['3c98946754c33309d73d5284','4ce3283fd98bb03a8fb39a19',canonical].sort());
|
||||||
|
}catch(error){documentFailure=error}
|
||||||
for(const item of results){const d=(await api('/api/studio/designs/'+item.id)).design;assert.ok(d.name.startsWith('API 验收'));assert.equal(d.postId,item.postId);if(!d.archived)await api('/api/studio/designs/'+d.id,{revision:d.revision},'DELETE');assert.equal((await api('/api/studio/designs/'+d.id)).design.archived,true)}
|
for(const item of results){const d=(await api('/api/studio/designs/'+item.id)).design;assert.ok(d.name.startsWith('API 验收'));assert.equal(d.postId,item.postId);if(!d.archived)await api('/api/studio/designs/'+d.id,{revision:d.revision},'DELETE');assert.equal((await api('/api/studio/designs/'+d.id)).design.archived,true)}
|
||||||
const final={canonical:base+'/explore/'+canonical,documentEntries:3,legacyCompatible:true,testRecordsArchived:results.length};
|
const final={canonical:base+'/explore/'+canonical,documentEntries:category?.total??null,legacyCompatible:!documentFailure,testRecordsArchived:results.length};
|
||||||
await writeFile('/tmp/studio-library/final-verification.json',JSON.stringify(final,null,2));console.log(JSON.stringify(final));
|
await writeFile('/tmp/studio-library/final-verification.json',JSON.stringify(final,null,2));console.log(JSON.stringify(final));if(documentFailure)throw documentFailure;
|
||||||
}else{
|
}else{
|
||||||
const catalog=await api('/studio/api/layouts');assert.equal(catalog.layouts.length,28);
|
const catalog=await api('/studio/api/layouts');assert.equal(catalog.layouts.length,28);
|
||||||
const note=(await api('/api/notes/8eb8c76500580f7a4b56ba3c')).entry;
|
const note=(await api('/api/notes/8eb8c76500580f7a4b56ba3c')).entry;
|
||||||
@@ -26,6 +29,8 @@ for(const layoutId of ['standard-01','ref-17']){
|
|||||||
const p={texts:{T01:{value:'API 验收 · 原生页面',fontFamily:'serif',fontWeight:600}},images:{I01:{assetId:asset,fit:'cover',cropX:35,cropY:65,zoom:1.2}},added:[{id:'user-api-check',kind:'text',role:'扩展正文',box:[10,120,60,9],direction:'horizontal',text:'通过 HTTP 保存并恢复',reading:'custom'}],layers:{'user-api-check':{z:20,rotation:2}}};
|
const p={texts:{T01:{value:'API 验收 · 原生页面',fontFamily:'serif',fontWeight:600}},images:{I01:{assetId:asset,fit:'cover',cropX:35,cropY:65,zoom:1.2}},added:[{id:'user-api-check',kind:'text',role:'扩展正文',box:[10,120,60,9],direction:'horizontal',text:'通过 HTTP 保存并恢复',reading:'custom'}],layers:{'user-api-check':{z:20,rotation:2}}};
|
||||||
let d=(await api('/api/studio/designs',{schemaVersion:1,layoutId,name:'API 验收 '+layoutId,parameters:p},'POST',201)).design;
|
let d=(await api('/api/studio/designs',{schemaVersion:1,layoutId,name:'API 验收 '+layoutId,parameters:p},'POST',201)).design;
|
||||||
const id=d.id,postId=d.postId;
|
const id=d.id,postId=d.postId;
|
||||||
|
results.push({layoutId,id,url:d.url,revision:d.revision,postId,parameters:p});
|
||||||
|
await writeFile('/tmp/studio-library/verification.json',JSON.stringify({results,preview:{asset,bytes,type:'image/webp'},pages:0},null,2));
|
||||||
assert.deepEqual((await api('/api/studio/designs/'+id)).design.parameters,d.parameters);
|
assert.deepEqual((await api('/api/studio/designs/'+id)).design.parameters,d.parameters);
|
||||||
const html=await fetch(base+d.url).then(r=>r.text());assert.ok(html.includes('API 验收'));assert.ok(html.includes('user-api-check'));assert.ok(html.includes('/api/preview?'));assert.ok(!html.includes('src="/api/media/'));
|
const html=await fetch(base+d.url).then(r=>r.text());assert.ok(html.includes('API 验收'));assert.ok(html.includes('user-api-check'));assert.ok(html.includes('/api/preview?'));assert.ok(!html.includes('src="/api/media/'));
|
||||||
d=(await api('/api/studio/designs/'+id,{name:'API 验收修订 '+layoutId,parameters:p,revision:d.revision},'PATCH')).design;
|
d=(await api('/api/studio/designs/'+id,{name:'API 验收修订 '+layoutId,parameters:p,revision:d.revision},'PATCH')).design;
|
||||||
@@ -36,7 +41,7 @@ for(const layoutId of ['standard-01','ref-17']){
|
|||||||
assert.deepEqual((await api('/api/studio/designs/'+id)).design.parameters,d.parameters);
|
assert.deepEqual((await api('/api/studio/designs/'+id)).design.parameters,d.parameters);
|
||||||
assert.ok((await api('/api/studio/designs?archived=true&layoutId='+layoutId)).designs.some(v=>v.id===id));
|
assert.ok((await api('/api/studio/designs?archived=true&layoutId='+layoutId)).designs.some(v=>v.id===id));
|
||||||
d=(await api('/api/studio/designs/'+id,{revision:3,archived:false},'POST')).design;assert.equal(d.revision,4);assert.equal(d.archived,false);assert.equal((await fetch(base+d.url)).status,200);
|
d=(await api('/api/studio/designs/'+id,{revision:3,archived:false},'POST')).design;assert.equal(d.revision,4);assert.equal(d.archived,false);assert.equal((await fetch(base+d.url)).status,200);
|
||||||
results.push({layoutId,id,url:d.url,revision:d.revision,postId,parameters:p});
|
Object.assign(results[results.length-1],{url:d.url,revision:d.revision});
|
||||||
// Restore tested URL for visual inspection, then archive only these clearly named test records later.
|
// Restore tested URL for visual inspection, then archive only these clearly named test records later.
|
||||||
}
|
}
|
||||||
for(const l of catalog.layouts){const r=await fetch(base+l.url);assert.equal(r.status,200,l.id);const html=await r.text();assert.ok(html.includes('data-layout-id="'+l.id+'"'));assert.ok(!/<img|data:image/.test(html));}
|
for(const l of catalog.layouts){const r=await fetch(base+l.url);assert.equal(r.status,200,l.id);const html=await r.text();assert.ok(html.includes('data-layout-id="'+l.id+'"'));assert.ok(!/<img|data:image/.test(html));}
|
||||||
|
|||||||
@@ -19,19 +19,8 @@ run_api(){
|
|||||||
-e AUTH_CONFIG_FILE=/auth/config.json -e AUTH_CHECK_BASE_URL=http://8.211.154.134:18131 \
|
-e AUTH_CONFIG_FILE=/auth/config.json -e AUTH_CHECK_BASE_URL=http://8.211.154.134:18131 \
|
||||||
--entrypoint node "$TEST_IMAGE" dist/auth-cli.cjs run "/delivery/scripts/$script" "$@"
|
--entrypoint node "$TEST_IMAGE" dist/auth-cli.cjs run "/delivery/scripts/$script" "$@"
|
||||||
}
|
}
|
||||||
# Clean only this task's explicitly named legacy temporary directories. Preserve test data via archive.
|
# Result files are uploaded by the workflow and removed after successful upload.
|
||||||
if [[ -f /tmp/studio-library/verification.json ]]; then
|
printf '{"temporaryOutputManagedByCI":true}\n' > "$RESULT_DIR/cleanup.json"
|
||||||
run_api /tmp/studio-library verify-studio-library.mjs --finalize
|
|
||||||
fi
|
|
||||||
if [[ -d /tmp/studio-library-source ]]; then
|
|
||||||
test -z "$(git -C /tmp/studio-library-source status --porcelain)" || { echo 'Temporary source has unexpected edits; preserved'; exit 1; }
|
|
||||||
git --git-dir=/tmp/studio-library-delivery.git worktree remove /tmp/studio-library-source
|
|
||||||
fi
|
|
||||||
rm -rf /tmp/studio-library-delivery.git /tmp/studio-library-evidence /tmp/studio-library
|
|
||||||
for old_path in /tmp/studio-library-source /tmp/studio-library-delivery.git /tmp/studio-library-evidence /tmp/studio-library; do
|
|
||||||
test ! -e "$old_path" || exit 1
|
|
||||||
done
|
|
||||||
printf '{"legacyTemporaryDirectoriesRemoved":true}\n' > "$RESULT_DIR/cleanup.json"
|
|
||||||
# Always archive only the UUIDs created by this run, including when visual checks fail.
|
# Always archive only the UUIDs created by this run, including when visual checks fail.
|
||||||
finish(){
|
finish(){
|
||||||
local status=$?
|
local status=$?
|
||||||
|
|||||||
Reference in New Issue
Block a user