@sreetej510/pi-shipd-checks 0.10.2 → 0.10.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fargate-worker.mjs +2 -1
- package/dist/index.js +57 -57
- package/package.json +1 -1
package/dist/fargate-worker.mjs
CHANGED
|
@@ -2366,7 +2366,8 @@ Options:
|
|
|
2366
2366
|
`),xOi="commandcode";function Ku(t){let e=process.env[t];if(!e)throw new Error(`Missing worker environment variable ${t}.`);return e}function SOi(t){return t.length>cNn?t.slice(t.length-cNn):t}function COi(){let t=JSON.parse(bY("/tmp/shipd-bootstrap.json","utf-8")),e=t.mode;if(e!=="solver"&&e!=="patch-precheck")throw new Error("Invalid Fargate bootstrap mode.");process.env.SHIPD_MODE=e;let r=(e==="solver"?["bucket","region","sourceKey","authKey","resultKey"]:["bucket","region","sourceKey","resultKey"]).every(a=>typeof t[a]=="string"&&t[a]),i=["planB64","resourceProfile",...e==="solver"?["provider","modelId","thinkingLevel"]:[]],s={planB64:"SHIPD_PLAN_B64",provider:"SHIPD_PROVIDER",modelId:"SHIPD_MODEL_ID",thinkingLevel:"SHIPD_THINKING_LEVEL",resourceProfile:"SHIPD_RESOURCE_PROFILE"};if(r){let a=[["bucket","SHIPD_S3_BUCKET"],["region","SHIPD_S3_REGION"],["sourceKey","SHIPD_S3_SOURCE_KEY"],...e==="solver"?[["authKey","SHIPD_S3_AUTH_KEY"]]:[],["resultKey","SHIPD_S3_RESULT_KEY"]];for(let[c,u]of a){let l=t[c];if(typeof l!="string"||l.length===0)throw new Error(`Invalid Fargate bootstrap field: ${c}.`);process.env[u]=l}}else{let a=[["sourceUrl","SHIPD_SOURCE_URL"],...e==="solver"?[["authUrl","SHIPD_AUTH_URL"]]:[],["resultPutUrl","SHIPD_RESULT_PUT_URL"],["resultGetUrl","SHIPD_RESULT_GET_URL"]];for(let[c,u]of a){let l=t[c];if(typeof l!="string"||l.length===0)throw new Error(`Invalid Fargate bootstrap field: ${c}.`);process.env[u]=l}}for(let a of i){let c=t[a];if(typeof c!="string"||c.length===0)throw new Error(`Invalid Fargate bootstrap field: ${a}.`);process.env[s[a]]=c}let o=[["timeoutMinutes","SHIPD_TIMEOUT_MINUTES"],...e==="solver"?[["solverCount","SHIPD_SOLVER_COUNT"]]:[]];for(let[a,c]of o){let u=t[a];if(typeof u!="number"||!Number.isFinite(u))throw new Error(`Invalid Fargate bootstrap field: ${a}.`);process.env[c]=String(u)}return e}function TOi(){let t=Ku("SHIPD_PLAN_B64");return JSON.parse(Buffer.from(t,"base64url").toString("utf-8"))}function IOi(t){let e={...process.env};for(let[n,r]of Object.entries(t.env))e[n]=r.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}|\$([A-Za-z_][A-Za-z0-9_]*)/g,(i,s,o)=>e[s??o]??"");return e}async function fNn(t,e){let n=await fetch(t);if(!n.ok)throw new Error(`Download failed (${n.status}) for ${e}.`);W3(e,Buffer.from(await n.arrayBuffer()))}function H3(){return!!process.env.SHIPD_S3_BUCKET}function j9e(){return new tD.S3Client({region:Ku("SHIPD_S3_REGION"),credentials:(0,dNn.defaultProvider)()})}async function hNn(t,e,n){let i=await(await j9e().send(new tD.GetObjectCommand({Bucket:t,Key:e}))).Body?.transformToByteArray();if(!i)throw new Error(`S3 object was empty: s3://${t}/${e}`);W3(n,Buffer.from(i))}async function iEe(t,e){let n=JSON.stringify(e);if(H3()){await j9e().send(new tD.PutObjectCommand({Bucket:Ku("SHIPD_S3_BUCKET"),Key:Ku("SHIPD_S3_RESULT_KEY"),Body:n,ContentType:"application/json"}));return}let r=await fetch(t,{method:"PUT",headers:{"content-type":"application/json"},body:n});if(!r.ok){let i=(await r.text()).trim();throw new Error(`Result upload failed (${r.status})${i?`: ${i.slice(0,1e3)}`:"."}`)}}async function j3(t,e,n,r){return await new Promise((i,s)=>{let o=EOi("/bin/bash",["-c",t],{cwd:e,env:n,stdio:["ignore","pipe","pipe"],detached:process.platform!=="win32"}),a="",c="",u=!1,l,p=d=>{u||(u=!0,l&&clearTimeout(l),i(d))};o.stdout.on("data",d=>{a+=d.toString()}),o.stderr.on("data",d=>{c+=d.toString()}),o.once("error",d=>{u||(u=!0,l&&clearTimeout(l),s(new Error(`${d instanceof Error?d.message:String(d)} (cwd=${e} exists=${sEe(e)})`)))}),o.once("close",d=>p({code:d??1,stdout:a,stderr:c})),l=setTimeout(()=>{process.platform!=="win32"&&o.pid?process.kill(-o.pid,"SIGTERM"):o.kill("SIGTERM"),setTimeout(()=>{u||(process.platform!=="win32"&&o.pid?process.kill(-o.pid,"SIGKILL"):o.kill("SIGKILL"))},5e3)},r)})}async function gR(t,e,n,r){let i=await j3(t,e,n,r);if(i.code!==0)throw new Error([i.stderr.trim(),i.stdout.trim(),`Remote command: ${t}`].filter(Boolean).join(`
|
|
2367
2367
|
`));return i}function q9e(t,e){if(!t)return null;let n=t.match(new RegExp(`\\b${e}=["']([0-9]+(?:\\.[0-9]+)?)["']`,"i"))?.[1];if(n===void 0)return null;let r=Number(n);return Number.isFinite(r)?r:null}function W9e(t,e){return t.match(new RegExp(`\\b${e}=["']([^"']*)["']`,"i"))?.[1]}function tEe(t,e){let n=W9e(t,"name")??`testcase-${e+1}`,r=W9e(t,"classname");return r?`${r}::${n}`:n}function wOi(t){if(!/<error\b/i.test(t))return!1;let e=t.match(/<error\b[^>]*>/i)?.[0]??"",n=W9e(t,"classname");return/collection\s+failure/i.test(e)||n===void 0||n.trim().length===0}function vOi(t){let e=t.indexOf("::");return e<0?t:`${t.slice(0,e).replace(/\\/g,"/").replace(/^\.\//,"").replace(/\.py$/,"").replace(/\//g,".")}::${t.slice(e+2)}`}function ROi(t){return[...t.matchAll(/^\s*(.+?)\s+PASSED(?:\s+\[[^\]]+\])?\s*$/gim)].map(e=>vOi(e[1]?.trim()??""))}function kOi(t){try{let e=bY(t,"utf-8"),n=e.match(/<testsuites\b[^>]*>/i)?.[0],r=[...e.matchAll(/<testsuite\b[^>]*>/gi)].map(R=>R[0]),i=[...e.matchAll(/<testcase\b[^>]*(?:\/>|>[\s\S]*?<\/testcase\s*>)/gi)].map(R=>R[0]),s=i.length,o=i.flatMap((R,O)=>/<failure\b/i.test(R)?[tEe(R,O)]:[]),a=i.flatMap((R,O)=>/<error\b/i.test(R)?[tEe(R,O)]:[]),c=i.flatMap((R,O)=>/<failure\b|<error\b|<skipped\b/i.test(R)?[]:[tEe(R,O)]),u=o.length,l=a.length,p=i.flatMap((R,O)=>wOi(R)?[tEe(R,O)]:[]),d=p.length,m=i.filter(R=>/<skipped\b/i.test(R)).length,h=[...e.matchAll(/<failure\b/gi)].length,f=[...e.matchAll(/<error\b/gi)].length,g=i.reduce((R,O)=>R+[...O.matchAll(/<error\b/gi)].length,0),y=[...e.matchAll(/<skipped\b/gi)].length,b=(R,O)=>{let G=r.map($=>q9e($,R)).filter($=>$!==null);return G.length>0?G.reduce(($,U)=>$+U,0):O},E=(R,O,G)=>Math.max(q9e(n,R)??b(R,G),O),_=q9e(n,"tests")??b("tests",s),x=E("failures",h,u),S=E("errors",f,l),T=E("skipped",y,m),w=_>=x+S+T?_-x-S-T:null;return{tests:_,testcases:s,failures:x,failedTestcases:u,passedTestcases:w,errors:S,erroredTestcases:l,suiteErrors:Math.max(0,f-g),collectionErrors:d,skipped:T,skippedTestcases:m,failedTestNames:o,erroredTestNames:a,passedTestNames:c,collectionErrorNames:p}}catch{return{tests:null,testcases:null,failures:null,failedTestcases:null,passedTestcases:null,errors:null,erroredTestcases:null,suiteErrors:null,collectionErrors:null,skipped:null,skippedTestcases:null,failedTestNames:[],erroredTestNames:[],passedTestNames:[],collectionErrorNames:[]}}}function POi(t,e){return t.tests===null||t.testcases===null||t.failures===null||t.failedTestcases===null||t.passedTestcases===null||t.errors===null||t.erroredTestcases===null||t.suiteErrors===null||t.collectionErrors===null||t.skipped===null||t.skippedTestcases===null||t.tests<=0||t.testcases<=0||t.testcases>t.tests||t.skipped!==0||t.skippedTestcases!==0||t.failures+t.errors+t.skipped+t.passedTestcases!==t.tests||t.suiteErrors!==0||t.collectionErrors!==0?!1:e==="all-pass"?t.failures===0&&t.failedTestcases===0&&t.errors===0&&t.erroredTestcases===0&&t.suiteErrors===0:t.passedTestcases===0&&t.failedTestcases+t.erroredTestcases>0&&t.failures+t.errors>0}async function nEe(t,e,n,r,i,s){let o=`/tmp/shipd-${t}.xml`,a=`./test.sh --output_path ${jr(o)} ${e}`,c={...i,SHIPD_WORKSPACE_ROOT:r,PATH:`${Vl(r,".shipd-bin")}:${i.PATH??""}`};await j3(`rm -f ${jr(o)}`,r,c,3e4);let u=await j3(a,r,c,s),l=kOi(o),p=[...new Set([...l.passedTestNames,...ROi(`${u.stdout}
|
|
2368
2368
|
${u.stderr}`)])];return{phase:t,exitCode:u.code,tests:l.tests,testcases:l.testcases,failures:l.failures,failedTestcases:l.failedTestcases,passedTestcases:l.passedTestcases,errors:l.errors,erroredTestcases:l.erroredTestcases,suiteErrors:l.suiteErrors,collectionErrors:l.collectionErrors,skipped:l.skipped,skippedTestcases:l.skippedTestcases,failedTestNames:l.failedTestNames,erroredTestNames:l.erroredTestNames,passedTestNames:p,collectionErrorNames:l.collectionErrorNames,passed:POi(l,n)}}function NOi(t){switch(t){case"base-before-solution":return"base tests before solution";case"new-before-solution":return"new tests before solution";case"base-after-solution":return"base tests after solution";case"new-after-solution":return"new tests after solution"}}function OOi(t){if(t.phase==="new-before-solution")return t.passedTestcases!==null&&t.passedTestcases>0?"Fix test.patch: add an assertion inside each passing new test for behavior introduced by the solution, so it fails before the solution and passes only after it. Do not remove tests.":t.collectionErrors!==null&&t.collectionErrors>0||t.passedTestcases===0&&t.failedTestcases===0&&t.erroredTestcases===0?"Fix test.patch: each new test must fail or error individually before the solution. Do not rely on a whole-file, module, or import error; move solution-dependent imports or setup into each test (lazy import) so every testcase is collected and reports its own failure or error. Do not remove tests.":"Fix test.patch so every collected new test fails or errors individually before the solution; no new test may pass. Do not remove tests.";switch(t.phase){case"base-before-solution":return"Modify test.sh to exclude the pre solution failing tests, so every base test passes before the solution with no failures or errors.";case"base-after-solution":return"Base-test regression: fix solution.patch so every existing base test still passes after the solution. Do not delete, skip, deselect, weaken, or exclude base tests.";case"new-after-solution":return t.skippedTestcases!==null&&t.skippedTestcases>0?"Fix solution.patch so every new test executes and passes after the solution. Do not skip, xfail, deselect, delete, or weaken new tests.":"Fix solution.patch so every new test passes after the solution with no failures or errors."}}function DOi(t){return[`phase: ${NOi(t.phase)}`,`instruction: ${OOi(t)}`,`passed tests: ${t.passedTestcases??"unknown"}`,`skipped tests: ${t.skippedTestcases??"unknown"}`,...t.phase==="new-before-solution"&&(t.passedTestcases??0)>0?[`passing tests: ${t.passedTestNames.length>0?t.passedTestNames.join(", "):"unknown"}`]:[`failed tests: ${t.failedTestNames.length>0?t.failedTestNames.join(", "):"none"}`,`errored tests: ${t.erroredTestNames.length>0?t.erroredTestNames.join(", "):"none"}`],`collection errors: ${t.collectionErrorNames.length>0?t.collectionErrorNames.join(", "):"none"}`].join(`
|
|
2369
|
-
`)}async function lNn(t,e,n,r){try{await gR(`git -C ${jr(n)} apply --recount ${jr(t)}`,"/work",r,15*6e4)}catch
|
|
2369
|
+
`)}async function lNn(t,e,n,r){try{await gR(`git -C ${jr(n)} apply --recount ${jr(t)}`,"/work",r,15*6e4)}catch(i){let s=i instanceof Error?i.message:String(i);throw new Error(`${e} patch could not be applied.${s?`
|
|
2370
|
+
${s}`:""}`)}}async function uNn(t,e){let n=await Promise.allSettled([t,e]),r=n[0],i=n[1];if(r.status==="rejected")throw r.reason;if(i.status==="rejected")throw i.reason;return[r.value,i.value]}async function pNn(t,e,n){let r=Vl(e,".shipd-bin"),i=Vl(r,"python");await gR(["set -euo pipefail",`rm -rf ${jr(e)}`,`mkdir -p ${jr(e)} ${jr(r)}`,`tar -cf - -C ${jr(t)} . | tar --no-same-owner -xf - -C ${jr(e)}`,`git config --global --add safe.directory ${jr(e)}`,`chmod +x ${jr(Vl(e,"test.sh"))}`,`printf %s ${jr(_Oi)} > ${jr(i)}`,`cp ${jr(i)} ${jr(Vl(r,"python3"))}`,`cp ${jr(i)} ${jr(Vl(r,"python3.12"))}`,`chmod +x ${jr(i)} ${jr(Vl(r,"python3"))} ${jr(Vl(r,"python3.12"))}`].join(`
|
|
2370
2371
|
`),"/work",n,15*6e4)}async function MOi(t,e,n){let r=Date.now(),i=[],s=t.workdir,o=Vl(s,"test.patch"),a="/tmp/shipd-precheck-without-solution",c="/tmp/shipd-precheck-with-solution",u=Math.max(6e4,n*6e4),l=(p,d)=>({platform:"linux",status:"failed",passed:!1,phases:d,durationMs:Date.now()-r,error:DOi(p)});try{await lNn(o,"test",s,e),await gR(`chmod +x ${jr(Vl(s,"test.sh"))}`,"/work",e,3e4),await pNn(s,a,e),await pNn(s,c,e),await lNn(Vl(c,"solution.patch"),"solution",c,e);let[p,d]=await uNn(nEe("base-before-solution","base","all-pass",a,e,u),nEe("base-after-solution","base","all-pass",c,e,u));if(i.push(p,d),!p.passed)return l(p,i);if(!d.passed)return l(d,i);let[m,h]=await uNn(nEe("new-before-solution","new","all-fail",a,e,u),nEe("new-after-solution","new","all-pass",c,e,u));return i.length=0,i.push(p,m,d,h),m.passed?h.passed?{platform:"linux",status:"ok",passed:!0,phases:i,durationMs:Date.now()-r}:l(h,i):l(m,i)}catch(p){return{platform:"linux",status:"error",passed:!1,phases:i,durationMs:Date.now()-r,error:p instanceof Error?p.message:String(p)}}finally{await j3(`rm -rf ${jr(a)} ${jr(c)}`,"/work",e,3e4).catch(()=>{})}}function LOi(t){let e=t.trim().replace(/["']/g,"");return/^chmod\s+\S+\s+(?:\S*\/)?test\.sh$/.test(e)}async function BOi(t,e){let n="/tmp/shipd-source.tar.gz";H3()?await hNn(Ku("SHIPD_S3_BUCKET"),Ku("SHIPD_S3_SOURCE_KEY"),n):await fNn(Ku("SHIPD_SOURCE_URL"),n),rEe(t.workdir,{recursive:!0});let r=t.workdir==="/"?":":`find ${jr(t.workdir)} -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +`;await gR(`set -eu
|
|
2371
2372
|
${r}
|
|
2372
2373
|
tar --overwrite -xzf ${jr(n)} -C ${jr(t.workdir)}`,"/work",e,900*1e3);let i=[`git config --global --add safe.directory ${jr(t.workdir)}`,`git -C ${jr(t.workdir)} init -q`,`git -C ${jr(t.workdir)} config user.email solvergap@shipd-checks.local`,`git -C ${jr(t.workdir)} config user.name shipd-checks-source`,`git -C ${jr(t.workdir)} add -A`,`git -C ${jr(t.workdir)} commit -q -m source --allow-empty`].join(`
|