@skyramp/testbot-core 0.12.0-v3.13 → 0.12.0-v3.16
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/main.js +2 -2
- package/dist/post.js +1 -1
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -409,7 +409,7 @@ ${OS}`,Kle=pn.join($,"testbot-comment.md");nr.writeFileSync(Kle,ert),we=Kle}}}G.
|
|
|
409
409
|
`),{[e]:Od.relative(t.runDir,s)}}function Jo(t,e){return{name:t,verify(r,n){let{errors:s}=e(r,n);return s.length===0?{name:this.name,passed:!0}:Fe(this.name,s,{fatal:!0})}}}function MKe(t,e){return{...t,name:e}}function Xs(t,e){return Od.relative(t,Od.resolve(t,e)).replace(/\/+$/,"")}function eT(t){return t.replace(/\s+/g," ").trim()}function Uh(t){return Od.basename(t).replace(/\.[^.]+$/,"").toLowerCase()}var EE=new RegExp("(^|/)("+["test_[^/]+\\.py","[^/]+_test\\.py","[^/]+\\.(spec|test)\\.[cm]?[jt]sx?","[^/]+_test\\.go","[^/]+Tests?\\.(java|kts?)","[^/]+_(test|spec)\\.rb","[^/]+\\.feature","[^/]+Tests?\\.cs","[^/]+_test\\.rs","tests/[^/]+\\.rs","[^/]+Test\\.php","[^/]+(Test|Spec|Suite)\\.scala","[^/]+Tests?\\.swift","[^/]+_test\\.exs","[^/]+_test\\.dart","[^/]+_test\\.(c|cc|cpp|cxx)","test_[^/]+\\.(c|cc|cpp|cxx)","[^/]+(Spec|Test)\\.groovy"].join("|")+")$","i");function WC(t){if(!t.inputs.skyrampMcp?.command)return!1;for(let e of Object.values(t.state.stages))for(let r of e.attempts??[]){let n=r.mcpServers?.skyramp;if(n!==void 0&&n!=="connected")return!1}return!0}function On(t,e=0){return tT(t,e)}var OKe=t=>" ".repeat(t);function tT(t,e){let r=q8t(t);switch(r._def.typeName){case"ZodObject":{let s=r.shape,i=Object.keys(s).filter(a=>!s[a].description?.startsWith("[derived]"));return i.length===0?"{}":`{
|
|
410
410
|
${i.map((a,c)=>{let l=s[a],u=l.isOptional()?" (optional)":"",d=l.description?` // ${l.description}`:"",p=tT(l,e+2);return`${OKe(e+2)}"${a}": ${p}${c<i.length-1?",":""}${u}${d}`}).join(`
|
|
411
411
|
`)}
|
|
412
|
-
${OKe(e)}}`}case"ZodArray":{let s=r.element;return`[ ${tT(s,e)}, \u2026 ]`}case"ZodEnum":return r.options.map(s=>JSON.stringify(s)).join(" | ");case"ZodNativeEnum":return Object.values(r.enum).map(s=>JSON.stringify(s)).join(" | ");case"ZodLiteral":return JSON.stringify(r.value);case"ZodString":return'"\u2026"';case"ZodNumber":return"<number>";case"ZodBoolean":return"true | false";case"ZodNull":return"null";case"ZodUnion":return r.options.map(s=>tT(s,e)).join(" | ");case"ZodRecord":return`{ "<key>": ${tT(r.valueSchema,e)} }`;default:return"<value>"}}function q8t(t){let e=t;for(;;){let r=e._def;if(r.typeName==="ZodOptional"||r.typeName==="ZodNullable"||r.typeName==="ZodDefault"){if(r.typeName==="ZodNullable")return R.union([r.innerType,R.null()]);e=r.innerType}else if(r.typeName==="ZodEffects")e=r.schema;else return e}}function H8t(t){return t.issues.map(e=>{let r=e.path.map(s=>typeof s=="number"?`[${s}]`:`.${s}`).join("").replace(/^\./,""),n=r||"output";if(!/^(Expected |Required$|Invalid |String must|Array must|Number must)/.test(e.message))return`${n} ${e.message}`;switch(e.code){case"invalid_type":return r?e.expected==="object"?`${n} must be an object`:e.received==="undefined"?`${n} is required`:`${n} must be ${e.expected}, got ${e.received}`:"output is not a JSON object";case"invalid_enum_value":{let s=JSON.stringify(e.received),i=e.options.find(a=>typeof a=="string"&&typeof e.received=="string"&&e.received.startsWith(a)),o=i?` \u2014 you sent ${s}; the value must be exactly ${JSON.stringify(i)}, with any qualifier moved to a field that takes free text`:` \u2014 you sent ${s}`;return`${n} must be one of: ${e.options.join(", ")}${o}`}case"invalid_literal":return`${n} must be ${JSON.stringify(e.expected)}`;case"too_small":return e.type==="string"?`${n} must be a non-empty string`:`${n} must have at least ${e.minimum} item(s)`;case"unrecognized_keys":return`${n} has unknown key(s): ${e.keys.join(", ")}`;default:return`${n}: ${e.message}`}})}function Eo(t,e){let r=t.safeParse(e);return r.success?{value:r.data,errors:[]}:{errors:H8t(r.error)}}function YC(t,e,r){let n=Eo(t,r),s=r&&typeof r=="object"&&!Array.isArray(r)?r:void 0,i=[...n.errors,...s?e(s):[]];return i.length?{errors:i}:{value:n.value,errors:[]}}var LKe=H(require("path"));var ece="outputs/preflight.json",bE="pr-diff.txt";function JC(t,e){return[...t.changedFiles.map(r=>({repository:e,path:r.path})),...(t.relatedChanges??[]).flatMap(r=>r.changedFiles.map(n=>({repository:r.repository,path:n.path})))]}function KC(t,e,r){return t.some(n=>n.path===r&&n.repository.toLowerCase()===e.toLowerCase())}function Nl(t){if(t.outputsDir)return yE(LKe.join(t.outputsDir,"preflight.json"))}var yH=H(require("path"));var UKe=require("child_process"),hH=H(require("fs")),XC=H(require("path"));var rT=(r=>(r.Sufficient="sufficient",r.Insufficient="insufficient",r))(rT||{}),mH=(
|
|
412
|
+
${OKe(e)}}`}case"ZodArray":{let s=r.element;return`[ ${tT(s,e)}, \u2026 ]`}case"ZodEnum":return r.options.map(s=>JSON.stringify(s)).join(" | ");case"ZodNativeEnum":return Object.values(r.enum).map(s=>JSON.stringify(s)).join(" | ");case"ZodLiteral":return JSON.stringify(r.value);case"ZodString":return'"\u2026"';case"ZodNumber":return"<number>";case"ZodBoolean":return"true | false";case"ZodNull":return"null";case"ZodUnion":return r.options.map(s=>tT(s,e)).join(" | ");case"ZodRecord":return`{ "<key>": ${tT(r.valueSchema,e)} }`;default:return"<value>"}}function q8t(t){let e=t;for(;;){let r=e._def;if(r.typeName==="ZodOptional"||r.typeName==="ZodNullable"||r.typeName==="ZodDefault"){if(r.typeName==="ZodNullable")return R.union([r.innerType,R.null()]);e=r.innerType}else if(r.typeName==="ZodEffects")e=r.schema;else return e}}function H8t(t){return t.issues.map(e=>{let r=e.path.map(s=>typeof s=="number"?`[${s}]`:`.${s}`).join("").replace(/^\./,""),n=r||"output";if(!/^(Expected |Required$|Invalid |String must|Array must|Number must)/.test(e.message))return`${n} ${e.message}`;switch(e.code){case"invalid_type":return r?e.expected==="object"?`${n} must be an object`:e.received==="undefined"?`${n} is required`:`${n} must be ${e.expected}, got ${e.received}`:"output is not a JSON object";case"invalid_enum_value":{let s=JSON.stringify(e.received),i=e.options.find(a=>typeof a=="string"&&typeof e.received=="string"&&e.received.startsWith(a)),o=i?` \u2014 you sent ${s}; the value must be exactly ${JSON.stringify(i)}, with any qualifier moved to a field that takes free text`:` \u2014 you sent ${s}`;return`${n} must be one of: ${e.options.join(", ")}${o}`}case"invalid_literal":return`${n} must be ${JSON.stringify(e.expected)}`;case"too_small":return e.type==="string"?`${n} must be a non-empty string`:`${n} must have at least ${e.minimum} item(s)`;case"unrecognized_keys":return`${n} has unknown key(s): ${e.keys.join(", ")}`;default:return`${n}: ${e.message}`}})}function Eo(t,e){let r=t.safeParse(e);return r.success?{value:r.data,errors:[]}:{errors:H8t(r.error)}}function YC(t,e,r){let n=Eo(t,r),s=r&&typeof r=="object"&&!Array.isArray(r)?r:void 0,i=[...n.errors,...s?e(s):[]];return i.length?{errors:i}:{value:n.value,errors:[]}}var LKe=H(require("path"));var ece="outputs/preflight.json",bE="pr-diff.txt";function JC(t,e){return[...t.changedFiles.map(r=>({repository:e,path:r.path})),...(t.relatedChanges??[]).flatMap(r=>r.changedFiles.map(n=>({repository:r.repository,path:n.path})))]}function KC(t,e,r){return t.some(n=>n.path===r&&n.repository.toLowerCase()===e.toLowerCase())}function Nl(t){if(t.outputsDir)return yE(LKe.join(t.outputsDir,"preflight.json"))}var yH=H(require("path"));var UKe=require("child_process"),hH=H(require("fs")),XC=H(require("path"));var rT=(r=>(r.Sufficient="sufficient",r.Insufficient="insufficient",r))(rT||{}),mH=(d=>(d.RelatedChangeConflict="related_change_conflict",d.ReferenceOutsideTarget="reference_outside_target",d.SourceAccessLost="source_access_lost",d.ConfigurationIncomplete="configuration_incomplete",d.CredentialUnavailable="credential_unavailable",d.WorkflowBindingUnverified="workflow_binding_unverified",d.WorkflowRefUnprotected="workflow_ref_unprotected",d.DeploymentReview="deployment_review",d.SutRevisionMismatch="sut_revision_mismatch",d.IsolationUnavailable="isolation_unavailable",d.EvidenceInsufficient="evidence_insufficient",d))(mH||{}),qh=(i=>(i.CiCheck="ci_check",i.TestReport="test_report",i.StaticAnalysis="static_analysis",i.CodeReview="code_review",i.Other="other",i))(qh||{});wc();var gH="ci-evidence.json",fH=(t,e)=>(0,UKe.execFileSync)("git",e,{cwd:t,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim(),$8t=/^Merge ([0-9a-f]{40}) into [0-9a-f]{40}$/;function z8t(t){try{let e=fH(t,["rev-parse","HEAD"]);if(fH(t,["rev-list","--parents","-n","1","HEAD"]).split(/\s+/).slice(1).length===2){let n=$8t.exec(fH(t,["log","-1","--format=%s","HEAD"]));if(n)return n[1]}return e}catch{return}}function AH(t){let e="";try{e=fH(t,["remote","get-url","origin"])}catch{}let r=/[:/]([A-Za-z0-9._-]+)\/([A-Za-z0-9._-]+?)(?:\.git)?\/?$/.exec(e);return r&&!e.startsWith("/")&&!e.startsWith(".")?`${r[1]}/${r[2]}`:`local/${XC.basename(XC.resolve(t)).replace(/[^A-Za-z0-9._-]/g,"-")||"repo"}`}var G8t=new Set(Object.values(qh));function j8t(t){let e=[];for(let r of t??[]){let n=r.trim();if(!n)continue;let s=n.lastIndexOf("="),i=s>0?n.slice(s+1).trim():"",o=G8t.has(i),c=(o?n.slice(0,s).trim():n).split("*").map(l=>l.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*");e.push({pattern:new RegExp(`^${c}$`,"i"),kind:o?i:"ci_check"})}return e}var V8t=new Set(["failure","timed_out","action_required","error","startup_failure"]);function FKe(t,e){let r=new Map(e.revisions.map(s=>[s.repository.toLowerCase(),s])),n=[];for(let s of t){if(s.name.startsWith(xs))continue;let i=r.get((s.repository??e.primary).toLowerCase());if(!i)continue;let o=e.trusted.find(l=>l.pattern.test(s.name)),a=s.conclusion??s.status,c=o?s.headSha.toLowerCase()!==i.revision.toLowerCase()?"stale":s.status!=="completed"?"pending":s.conclusion==="success"?"accepted":V8t.has(s.conclusion??"")?"failing":"inconclusive":"untrusted";n.push({id:`ci-${n.length+1}`,repository:i.repository,revision:i.revision,checkSha:s.headSha,name:s.name,kind:o?.kind??"ci_check",status:c,conclusion:a,reference:s.url||`${i.repository}@${s.headSha.slice(0,12)} ${s.name}`,summary:(s.summary||`${s.name}: ${a}`).slice(0,300)})}return n}var W8t=R.object({checks:R.array(R.object({repository:R.string().optional(),name:R.string().min(1),headSha:R.string().regex(/^[0-9a-f]{40}$|^[0-9a-f]{64}$/i),status:R.string().default("completed"),conclusion:R.string().nullable().optional(),url:R.string().optional(),summary:R.string().optional()}))});function Y8t(t){let e=W8t.safeParse(JSON.parse(hH.readFileSync(t,"utf-8")));if(!e.success)throw new Error(`${t} is not a CI evidence file: ${e.error.issues[0]?.message??"invalid"}`);return e.data.checks}function J8t(t){let e=[{path:t.inputs.repositoryPath,slug:t.inputs.repositorySlug},...(t.inputs.relatedRepos??[]).map(n=>({path:n.path,slug:n.slug}))],r=[];for(let n of e){let s=z8t(n.path);s&&r.push({repository:n.slug??AH(n.path),revision:s})}return r}async function qKe(t){let e=J8t(t),r=e[0]?.repository??AH(t.inputs.repositoryPath),n=j8t(t.inputs.trustedChecks),s;try{if(t.inputs.ciEvidenceFile){let i=Y8t(t.inputs.ciEvidenceFile);s={source:"file",revisions:e,items:FKe(i,{revisions:e,primary:r,trusted:n})}}else if(t.platform?.listCommitChecks){let i=[];for(let o of e)i.push(...await t.platform.listCommitChecks(o)??[]);s={source:"platform",revisions:e,items:FKe(i,{revisions:e,primary:r,trusted:n})}}else s={source:"none",revisions:e,items:[],note:"this platform keeps no CI results"}}catch(i){s={source:"none",revisions:e,items:[],note:`CI results could not be read: ${i instanceof Error?i.message:String(i)}`}}return s.items.length>0&&n.length===0&&(s.note="no trustedChecks were configured, so no CI result counts as evidence"),hH.writeFileSync(XC.join(t.outputsDir,gH),JSON.stringify(s,null,2)+`
|
|
413
413
|
`),s}var K8t=8e3,tce=new Map;function X8t(t){return t.repositorySlug?t.repositorySlug:(tce.has(t.repositoryPath)||tce.set(t.repositoryPath,AH(t.repositoryPath)),tce.get(t.repositoryPath))}function hr(t){return[{slug:X8t(t),path:t.repositoryPath,writable:!0,working:!0},...(t.relatedRepos??[]).map(e=>({slug:e.slug,path:e.path,writable:e.writable===!0,working:!1}))]}function vl(t){return hr(t)[0]}function EH(t,e){return[...hr(t)].sort((r,n)=>n.path.length-r.path.length).find(r=>{let n=yH.relative(r.path,e);return!n.startsWith("..")&&!yH.isAbsolute(n)})}var Z8t=(t,e)=>t.toLowerCase()===e.toLowerCase();function xE(t,e){return e?.trim()?t.find(r=>Z8t(r.slug,e.trim())):t[0]}function gi(t,e){return xE(hr(t),e)}var HKe=(t,e)=>`${e} is not a repository of this run (${hr(t).map(r=>r.slug).join(", ")})`;function Ko(t,e){let r=gi(t,e);if(!r)throw new Error(HKe(t,e));return r.path}function Ld(t,e){let r=gi(t,e);return r?r.writable?{source:r}:{error:`${r.slug} is read-only in this run: tests are written only to ${hr(t).filter(n=>n.writable).map(n=>n.slug).join(", ")}`}:{error:HKe(t,e)}}function $r(t,e){return rce(hr(t),e)}function rce(t,e){return t.length<2?"":`${xE(t,e)?.slug??e}: `}function Fd(t){return(t.relatedRepos??[]).map(e=>e.path)}function Ud(t){let e=hr(t);if(e.length<2)return[];let r=n=>n.working?"your working directory; writable":n.writable?"writable":"read-only: read it, never write a test there";return["",`This run has ${e.length} checkouts, and none is primary. Every test, maintained test and result lives in exactly one of`,'them: name it by "repository" (owner/repo), with its path relative to that checkout. Place a test in the',"checkout whose test tree it belongs to, which need not be the checkout the change is in.",...e.map(n=>` - ${n.slug}: ${n.path} (${r(n)})`)]}function ZC(t){let e=t.pullRequests??[];return e.length===0?[...t.prTitle||t.prDescription?[""]:[],...t.prTitle?[`PR title: ${t.prTitle}`]:[],...t.prDescription?[`PR description: ${t.prDescription}`]:[]]:["",`This change is ${e.length>1?`${e.length} pull requests`:"1 pull request"}. Read every description: each states part of what the change must do.`,...e.flatMap(n=>[`--- ${[`${n.repository}#${n.number}`,n.title].filter(Boolean).join(": ")} ---`,n.note?`(${n.note})`:n.body?.slice(0,K8t)||"(no description)"])]}var bH=H(require("fs")),$Ke=H(require("path"));function eKt(t){let e=new Map,r,n;for(let s of t.split(`
|
|
414
414
|
`)){let i=/^diff --git a\/.+ b\/(.+)$/.exec(s);if(i){r=i[1],n=void 0,e.has(r)||e.set(r,[]);continue}let o=/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(s);if(o){n=Number(o[1]);continue}!r||n===void 0||(s.startsWith("+")?e.get(r).push([n,n++]):s.startsWith("-")?e.get(r).push([n,n]):s.startsWith(" ")&&n++)}return e}function zKe(t){let e=$Ke.join(t.runDir,bE);if(bH.existsSync(e))return eKt(bH.readFileSync(e,"utf-8"))}function tKt(t){let e=/([\w./@+-]+\.[\w]+)(?::(\d+)(?:-(\d+))?)?/.exec(t);if(!e)return{};let r=e[1].replace(/^\.\//,"");if(!e[2])return{file:r};let n=Number(e[2]);return{file:r,lines:[n,e[3]?Number(e[3]):n]}}function GKe(t,e){if(!e)return!0;let{file:r,lines:n}=tKt(t);if(!r)return!0;let s=e.get(r)??[...e].find(([i])=>i.endsWith(`/${r}`)||r.endsWith(`/${i}`))?.[1];return s?n?s.some(([i,o])=>n[0]<=o&&n[1]>=i):!0:!1}var Xo=["-c","core.fsmonitor=false"],rKt=new Set(["GH_TOKEN","GITHUB_TOKEN","GH_ENTERPRISE_TOKEN","GITHUB_ENTERPRISE_TOKEN","ACTIONS_RUNTIME_TOKEN","ACTIONS_ID_TOKEN_REQUEST_TOKEN","ACTIONS_ID_TOKEN_REQUEST_URL","SSH_AUTH_SOCK","GIT_SSH","GIT_SSH_COMMAND"]),nKt=new Set(["ANTHROPIC_API_KEY","ANTHROPIC_AUTH_TOKEN","CLAUDE_CODE_OAUTH_TOKEN","AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_SESSION_TOKEN","AWS_BEARER_TOKEN_BEDROCK","AWS_PROFILE","AWS_WEB_IDENTITY_TOKEN_FILE","AWS_ROLE_ARN","AWS_ROLE_SESSION_NAME","AWS_CONTAINER_CREDENTIALS_FULL_URI","AWS_CONTAINER_CREDENTIALS_RELATIVE_URI","AWS_CONTAINER_AUTHORIZATION_TOKEN","AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE"]);function mr(t=process.env,e,r="repo-command"){let n={};for(let[s,i]of Object.entries(t))r==="repo-command"&&nKt.has(s)||(n[s]=i);Object.assign(n,e??{});for(let s of Object.keys(n))(rKt.has(s)||s.startsWith("INPUT_"))&&delete n[s];return n}var cce=require("child_process"),$h=H(require("path"));var xH=H(require("fs")),jKe=H(require("path")),sKt=/[;|`$<>(){}\n\r]|(?<!&)&(?!&)|\|\|/;function nT(t){let e=(t??"").trim();if(!e)return{kind:"empty",reason:"the command is empty"};if(sKt.test(e))return{kind:"shell-syntax",reason:"it uses shell syntax (pipe, redirect, substitution, or backgrounding), and this is re-executed WITHOUT a shell so the recorded string cannot be interpreted \u2014 put the logic in a script and record the script invocation instead"};let r=[],n=[],s="",i,o=!1,a=()=>{(s||o)&&n.push(s),s="",o=!1},c=()=>{a(),n.length>0&&r.push(n),n=[]};for(let u=0;u<e.length;u++){let d=e[u];if(i){d===i?i=void 0:s+=d;continue}if(d==='"'||d==="'"){i=d,o=!0;continue}if(d==="&"&&e[u+1]==="&"){c(),u+=1;continue}if(/\s/.test(d)){a();continue}s+=d}if(i)return{kind:"unterminated-quote",reason:"it has an unterminated quote"};if(c(),r.length===0)return{kind:"empty",reason:"the command is empty"};if(r.some(u=>u.length===0))return{kind:"empty-step",reason:"it has an empty step between && operators"};let l=r.find(u=>["cd","export","source","."].includes(u[0]));return l?{kind:"builtin",reason:`it runs the shell builtin "${l[0]}", which cannot be executed as a program \u2014 record a script that does this instead`}:{argv:r[0],steps:r}}function wH(t,e,r){let n=(t??"").trim(),{steps:s,kind:i}=nT(n);if(!s&&!(i!=="shell-syntax"&&i!=="builtin")){try{xH.mkdirSync(jKe.dirname(e),{recursive:!0}),xH.writeFileSync(e,`#!/usr/bin/env bash
|
|
415
415
|
# Written by ${r}: the recorded command, which needed a shell to run.
|
|
@@ -713,7 +713,7 @@ ${ctt(s,{order:t.stages.map(o=>o.name),wallMinutes:q$(s)})}
|
|
|
713
713
|
`)?`
|
|
714
714
|
`:""}${i.join(`
|
|
715
715
|
`)}
|
|
716
|
-
`)}var Htr="https://testbot.skyramp.dev",ag={attemptId:"v3AttemptId",origin:"v3Origin",deadlineAt:"v3DeadlineAt",reportUploaded:"v3ReportUploaded",recipeUploaded:"v3RecipeUploaded",cause:"v3Cause"},$tr="skyramp-sources",ztr=3e4;function Gtr(t){let e=t.ACTIONS_ID_TOKEN_REQUEST_URL,r=t.ACTIONS_ID_TOKEN_REQUEST_TOKEN;return delete t.ACTIONS_ID_TOKEN_REQUEST_URL,delete t.ACTIONS_ID_TOKEN_REQUEST_TOKEN,async n=>{if(!e||!r)throw new Error("The job cannot request an OIDC token. Give it the `id-token: write` permission.");let s=new URL(e);s.searchParams.set("audience",n);let i=await fetch(s,{headers:{Authorization:`Bearer ${r}`,Accept:"application/json"},redirect:"error",signal:AbortSignal.timeout(ztr)});if(!i.ok)throw new Error(`GitHub refused the OIDC token request: ${i.status}`);let o=(await i.json().catch(()=>({}))).value;if(typeof o!="string"||!o)throw new Error("GitHub's OIDC token response carried no token");return Ct(o),o}}function jtr(t,e){return{origin:t,idToken:e,mask:r=>Ct(r),log:r=>ee(r)}}function Om(t){VI(ag.attemptId)&&!VI(ag.cause)&&In(ag.cause,t)}function ZT(){Om("setup_failed")}function qtt(){Om("timed_out")}var Wle={cancelled:"Skyramp cancelled this run",expired:"this attempt passed its deadline in Skyramp",ended:"Skyramp already ended this attempt"},Htt={cancelled:"cancelled",expired:"timed_out",ended:"agent_failed"};function $tt(t){return e=>Rtt(t.attempt,r=>{Om(Htt[r]),J(`Testbot V3: ${Wle[r]}; stopping the run, and uploading nothing.`),e("attempt-closed",Wle[r])})}async function ztt(t){let e=await Itt(t.attempt);return e?(Om(Htt[e]),J(`Testbot V3: ${Wle[e]}, so nothing is uploaded.`),!0):!1}function Gtt(t){return[...t.attempt.manifest.credentials.map(e=>process.env[e.name]??""),t.attempt.license?.runToken??"",...t.heldInputs??[]].filter(Boolean)}function jtt(t){return!t||t.includes("generate")?{}:{stages:["analyze","recommend"],planOnly:!0}}async function z$(t){t.cancelWatch?.stop();let e=await t.attempt.revokeTokens();for(let r of e)J(`Testbot V3: could not revoke a scoped GitHub token (${r}); it stays valid until it expires.`)}function Vtr(t){let e=["SIGINT","SIGTERM"],r=()=>{n(),z$({attempt:t})},n=()=>{for(let s of e)process.removeListener(s,r)};for(let s of e)process.on(s,r);return{stop:n}}async function Vtt(t){let e=Gtr(process.env),r=Ue("skyrampAppOrigin").trim()||Htr,n=await Ctt(t,process.env,jtr(r,e)),s=Vtr(n);In(ag.attemptId,n.attemptId),In(ag.origin,r),In(ag.deadlineAt,n.deadlineAt.toISOString()),ee(`Testbot V3: attempt ${n.attemptNumber} of Validation Run ${t}, deadline ${n.deadlineAt.toISOString()}`);try{return{...await Wtr(n),cancelWatch:s}}catch(i){throw await z$({attempt:n,cancelWatch:s}),i}}async function Wtr(t){let e=Ftt(t.manifest,process.env);if(e.length>0)throw Om("credential_missing"),new Error(`The workflow does not supply the required credential${e.length>1?"s":""} ${e.join(", ")}. Add ${e.length>1?"them":"it"} to the Testbot step's env.`);let r;try{r=await vtt(t,{workspace:DS.join(process.env.GITHUB_WORKSPACE||process.cwd(),$tr)})}catch(o){throw ZT(),o}for(let o of r)ee(`Testbot V3: ${o.slug} at ${o.revision}`);await Ytr({attempt:t,sources:r});let n=Ptt(r);ee(`Testbot V3: working checkout ${n.repositorySlug}`);let s=Ttt(t.manifest,r);s&&ee(`Testbot V3: the pull request is ${s.repository}#${s.number}`);let i=await Btt(t);for(let o of i)ee([`Testbot V3: Change Set ${o.repository}#${o.number}`,o.note].filter(Boolean).join(": "));return{attempt:t,sources:r,layout:n,pullRequests:i,pullRequest:s}}async function Ytr(t){for(let e of t.sources)jle(e.path);Yle(t)||await Jtr(t)}async function Jtr(t){let e=t.sources[0],r;try{r=await Qtt(t.attempt)}catch(n){if(!(n instanceof UE&&n.status===404))throw ZT(),n;J(`Testbot V3: this Skyramp app does not serve the stored SUT recipe (${n.message}); deploy uses a source's own recipe, if one has it.`);return}if(!r){ee("Testbot V3: no stored SUT recipe for this Target yet; deploy uses a source's own recipe, if one has it.");return}Utt(e.path,r.files),ee(`Testbot V3: SUT recipe version ${r.version}, ${r.files.length} files, for ${e.slug} (uncommitted)`)}function Wtt(t){try{let e=JSON.parse(QS.readFileSync(DS.join(t,"@skyramp","mcp","package.json"),"utf-8")).version;return typeof e=="string"&&/^[0-9A-Za-z.+-]{1,64}$/.test(e)?e:"unknown"}catch{return"unknown"}}async function Ytt(t,e,r){e.aborted?Om("cancelled"):e.timedOut&&Om("timed_out");let n=e.outputsDir?DS.join(e.outputsDir,"report.json"):void 0;if(!n||!QS.existsSync(n)){J("Testbot V3: the run wrote no report, so Skyramp records it as an infrastructure error.");return}if(!await ztt(t))try{let s=JSON.parse(QS.readFileSync(n,"utf-8"));await _tt(t.attempt,{report:s,sources:t.sources,workingSlug:t.layout.repositorySlug,delivery:Ltt(e.outputsDir,t.sources,s,t.layout.repositorySlug),producer:{testbot:nH().version,mcp:Wtt(r)},secrets:Gtt(t)}),In(ag.reportUploaded,"true"),ee("Testbot V3: report uploaded; Skyramp derives the outcome.")}catch(s){J(`Testbot V3: the report upload failed: ${s instanceof Error?s.message:String(s)}`)}}function Yle(t){return t.attempt.manifest.trigger.kind==="sut_setup"}async function Jtt(t){let{capture:e}=await Dtt(t.attempt);return ile(e.settings.target.environment,"the run's SUT / Environment settings")}var Ktr={onboard:"onboard",deploy:"deploy"};function Ktt(t){return({stage:e,event:r,status:n})=>{let s=Ktr[e];if(!s)return;let i=r==="finished",o=n==="aborted"?"skipped":n;Mtt(t.attempt,{schemaVersion:1,stage:s,event:i?"finished":"started",...i&&o?{status:o}:{}}).catch(a=>J(`Testbot V3: could not report ${e} ${r}: ${a instanceof Error?a.message:String(a)}`))}}var Vle=t=>{try{return JSON.parse(QS.readFileSync(t,"utf-8"))}catch{return}};async function Xtt(t,e,r){e.aborted?Om("cancelled"):e.timedOut&&Om("timed_out");let n=e.outputsDir?Vle(DS.join(e.outputsDir,"onboard.json")):void 0;if(!n){J("Testbot V3: onboard wrote no answer, so there is no SUT recipe to send; Skyramp records the run as an infrastructure error.");return}if(await ztt(t))return;let s=Vle(DS.join(e.outputsDir,"deploy.json")),o=(e.stateFilePath?Vle(e.stateFilePath):void 0)?.stages.deploy?.attempts?.reduce((a,c)=>a+(c.totalMs??c.durationMs??0),0);try{let a=sZe(n,s,{deployDurationSeconds:o?Math.round(o/1e3):void 0,recipeFiles:s?ole(t.layout.repositoryPath):void 0});await Ott(t.attempt,{recipe:a,sources:t.sources,producer:{testbot:nH().version,mcp:Wtt(r)},secrets:Gtt(t)}),In(ag.recipeUploaded,"true"),ee(`Testbot V3: SUT recipe uploaded (${a.status}); Skyramp derives the outcome.`)}catch(a){J(`Testbot V3: the SUT recipe upload failed: ${a instanceof Error?a.message:String(a)}`)}}function Xtr(t){let e=t.split(/[\n,]/).map(r=>r.trim()).filter(Boolean);return e.length?e:void 0}function Ztr(t){if((t("testRepoPath")??"").trim())return"testRepoPath is not supported by the staged pipeline (pipeline: staged) \u2014 it writes tests into the application checkout only, and the Action's token has no write access to another repository. Use pipeline: classic for cross-repository delivery, or remove the input."}async function err(t,e,r,n=process.env.GITHUB_WORKSPACE||process.cwd()){let s=(t("relatedRepoPaths")??"").trim();if(!s)return[];let i=[];for(let o of s.split(/[\n,]/).map(a=>a.trim()).filter(Boolean)){let a=cg.resolve(n,o);if(!yo(n,o)){r(`relatedRepoPaths: ${o} is outside the workspace \u2014 skipping`);continue}if(!MS.existsSync(a)){r(`relatedRepoPaths: no checkout at ${o} \u2014 skipping`);continue}let c=await e(a);if(!c){r(`relatedRepoPaths: could not resolve owner/repo for ${o} (no origin remote?) \u2014 skipping`);continue}i.push({slug:c,path:a})}return i}async function trr(t,e,r=process.env){let n=r.GITHUB_REPOSITORY_ID,s=r.GITHUB_REPOSITORY;return!n||!s?void 0:(await e(t).catch(()=>{}))?.toLowerCase()===s.toLowerCase()?{[n]:s}:void 0}async function Ztt(){let t=J1();delete process.env.INPUT_SKYRAMPLICENSEFILE;let e=dtt(process.env),r=Ue("skyrampRunId").trim(),n=r?await Vtt(r):void 0;try{await rrr(t,e,n)}finally{n&&await z$(n)}}async function rrr(t,e,r){let n=r!==void 0&&Yle(r);r&&(r.heldInputs=[t.skyrampLicenseFile].filter(Boolean));let s=r?r.layout.repositoryPath:cg.resolve(t.workingDirectory||"."),i=r?()=>r.attempt.token():ptt(),o=r?void 0:e;o&&Ct(o);let a=ltt(),c=new FH({repositoryPath:r?.pullRequest?.path??s,prNumber:a.prNumber,tokenProvider:i,githubToken:o,repoSlug:r?r.pullRequest?.repository??r.layout.repositorySlug:void 0,allowedAuthors:!n&&t.allowedAuthors?.length?t.allowedAuthors:void 0,log:q=>ee(q)});a=utt(a,await c.resolveContext().catch(()=>({}))),ee(`Staged pipeline \u2014 event: ${a.eventName??"?"}${a.action?`/${a.action}`:""}${a.prNumber?`, PR #${a.prNumber}`:""}${a.headRef?` (${a.headRef} \u2192 ${a.baseRef??"?"})`:""}`);let l=id(),u=cg.join(l,"staged");if(a.eventName==="pull_request"&&a.action==="closed"){let q=a.merged===!1,Z=q?`PR #${a.prNumber} was closed without merging`:`PR #${a.prNumber} was merged`;if(q&&a.headRef){let G=await c.closeTestsPr({branch:Ole(a.headRef,Ue("deliverBranch")||void 0),reason:`Closing: the pull request this tests PR targeted (#${a.prNumber}) was closed without being merged.`});G.closed&&(Z+=`; closed the tests PR ${G.url??""}`.trimEnd())}ee(`Staged pipeline \u2014 ${Z}; nothing to run.`);for(let[G,M]of Object.entries(XT({admission:{admit:!1,reason:Z}},{skippedPrClosed:q})))dt(G,M);In("completed","true");return}let d=await c.admitRun();if(!d.admit){ee(`Staged pipeline \u2014 run skipped: ${d.reason}`);for(let[q,Z]of Object.entries(XT({admission:d},{skippedSelfTrigger:!0})))dt(q,Z);In("completed","true");return}let p=r?r.layout.relatedRepos:await err(q=>Ue(q),q=>vm(q),q=>J(q)),m=Ztr(q=>Ue(q));if(m)throw new Error(m);let h=n||Ue("onboard").toLowerCase()==="true",f=ntt(Ue("sutGuidance"),"sutGuidance input"),A;try{A=n?await Jtt(r):CZe(Ue("sutEnvironment"),"sutEnvironment input")}catch(q){throw r&&ZT(),q}for(let q of d$(A))Ct(q);let x=r?Object.fromEntries(r.sources.map(q=>[q.repository.providerRepositoryId,q.slug])):await trr(s,q=>vm(q)),E,C,S=r?.attempt.license?.runToken,v;try{if(e||i){let Z=process.env.GITHUB_WORKSPACE,G=[...new Set([s,...p.map(F=>F.path),...Z?lXe(Z):[]].map(F=>cg.resolve(F)))],M;for(let F of G){let ne=F===cg.resolve(s)?re=>{/^\s*authorization\s*:/i.test(re)&&(M??=re)}:void 0,ye=aXe(F,void 0,ne);ye.length&&ee(`Removed the persisted checkout credential from ${F} (${ye.length} entr${ye.length===1?"y":"ies"}).`)}let $=cXe();$.length&&ee(`Removed ${$.length} persisted checkout credential(s) from RUNNER_TEMP.`),M&&(Ct(M.replace(/^AUTHORIZATION:\s*\S+\s+/i,"")),c.adoptCheckoutAuthHeader(M),ee("Deliver pushes with the credential the checkout was made with."))}else J("No githubToken or GitHub App credentials: the checkout's persisted git credential (if any) is left in place, and the stage sessions can reach it. Set persist-credentials: false on actions/checkout, or pass githubToken.");if(MS.mkdirSync(l,{recursive:!0}),!S){if(v=cg.join(l,"skyramp_license.lic"),!t.skyrampLicenseFile)throw new Error("skyrampLicenseFile input is required");MS.writeFileSync(v,t.skyrampLicenseFile,{mode:384})}let q=await jv(t);E=await tH(q,t,l),C=oU("claude",{model:t.model||void 0,useLocalAuth:t.useLocalAuth&&!t.useBedrock}),await iH(C),await oH(C),C.setupAgentEnv(t,q)}catch(q){r&&ZT();let Z=q instanceof Error?q.message:String(q);await c.createProgressSink().render(OH(Z,{runUrl:c.runUrl})).catch(()=>{}),await c.endRun({status:"failure",summary:`could not start: ${Z}`});for(let[G,M]of Object.entries(XT({admission:{admit:!0},startupError:q instanceof Error?q:new Error(Z)})))dt(G,M);In("completed","true"),Kc(`Skyramp Testbot could not start: ${Z}`);return}t.generatedTestsMode!=="separate-branch"&&J(`pipeline: staged delivers only as a separate tests PR; generatedTestsMode=${t.generatedTestsMode} means nothing is committed or pushed this run`);let B=r?r.attempt.budgetMs(new Date):(t.testbotTimeout||60)*6e4;if(B<=0)throw qtt(),new Error("Testbot V3: setup used the run's whole budget; no time is left before the attempt deadline");let{stages:N,planOnly:Q}=r&&!n?jtt(r.attempt.license?.entitlements):{};Q&&ee("Testbot V3: the organization's entitlements do not include generate; this run is plan-only (analyze and recommend).");let L=await Jet({admission:d,platform:c,watch:r?$tt(r):void 0,log:O$,skipReport:n,run:{runDir:u,fresh:!0,budgetMs:B,...n?{stages:["onboard","deploy"],skipReport:!0,onStageEvent:Ktt(r)}:{},...N?{stages:N}:{},model:Ue("model").trim()||void 0,resolveModel:mtt(t),inputs:{repositoryPath:s,repositorySlug:r?.layout.repositorySlug,pullRequestRepository:r?.pullRequest?.repository,baseBranch:!r&&a.baseRef?`origin/${a.baseRef}`:void 0,relatedRepos:p,headBranch:r?void 0:a.headRef,prTitle:a.title,prDescription:a.body,...r?.pullRequests?.length?{pullRequests:r.pullRequests}:{},planOnly:Q,skyrampMcp:{command:E.command,args:E.args.split(" ").filter(Boolean),licensePath:v,runToken:S},deliver:t.generatedTestsMode==="separate-branch"&&!Q,deliverBranch:Ue("deliverBranch")||void 0,trustedChecks:Xtr(Ue("trustedChecks")),deliverMode:a.eventName==="issue_comment"?"append":"replace",provisionRuntime:!0,runnerPlatform:"github",onboard:h&&!Q,sutGuidance:f,sutEnvironment:A,repositoryIds:x},sessionRunner:ttt(C.binary),sutAuth:{tokenCommand:t.authTokenCommand||void 0,uiCredentials:t.uiCredentials||void 0,sessionEnv:Het(Ue("sessionEnv")),maskSecret:q=>Ct(q),attempts:t.authTokenRetries,retryDelaySec:t.authTokenRetryDelay}}});r&&n?await Xtt(r,L.summary??{},E.nodeModulesDir):r&&await Ytt(r,L.summary??{},E.nodeModulesDir),L.admission.admit&&await ftt(u);let W=XT(L,{skippedSelfTrigger:!L.admission.admit});for(let[q,Z]of Object.entries(W))dt(q,Z);if(In("completed","true"),L.summary){await htt(L.summary,L.outcome),ee(`Staged run ${L.summary.runId}: ${L.outcome?.summary} (state: ${L.summary.stateFilePath})`);let q=U$(L.summary.stateFilePath);q&&(Ds("Stage breakdown (time / cost / context)"),ee(att(q,{order:L.summary.stages.map(Z=>Z.name),wallMinutes:q$(q)})),Sn())}L.startupError?Kc(`Skyramp Testbot could not start: ${L.startupError.message}`):L.outcome&&L.outcome.status==="failure"&&Kc(`Skyramp Testbot: ${L.outcome.summary}`)}var nrr=Ue("pipeline").trim().toLowerCase(),srr=nrr==="staged"?Ztt:kKe;srr().catch(async t=>{Kc(t instanceof Error?t.message:String(t))});
|
|
716
|
+
`)}var Htr="https://testbot.skyramp.dev",ag={attemptId:"v3AttemptId",origin:"v3Origin",deadlineAt:"v3DeadlineAt",reportUploaded:"v3ReportUploaded",recipeUploaded:"v3RecipeUploaded",cause:"v3Cause"},$tr="skyramp-sources",ztr=3e4;function Gtr(t){let e=t.ACTIONS_ID_TOKEN_REQUEST_URL,r=t.ACTIONS_ID_TOKEN_REQUEST_TOKEN;return delete t.ACTIONS_ID_TOKEN_REQUEST_URL,delete t.ACTIONS_ID_TOKEN_REQUEST_TOKEN,async n=>{if(!e||!r)throw new Error("The job cannot request an OIDC token. Give it the `id-token: write` permission.");let s=new URL(e);s.searchParams.set("audience",n);let i=await fetch(s,{headers:{Authorization:`Bearer ${r}`,Accept:"application/json"},redirect:"error",signal:AbortSignal.timeout(ztr)});if(!i.ok)throw new Error(`GitHub refused the OIDC token request: ${i.status}`);let o=(await i.json().catch(()=>({}))).value;if(typeof o!="string"||!o)throw new Error("GitHub's OIDC token response carried no token");return Ct(o),o}}function jtr(t,e){return{origin:t,idToken:e,mask:r=>Ct(r),log:r=>ee(r)}}function Om(t){VI(ag.attemptId)&&!VI(ag.cause)&&In(ag.cause,t)}function ZT(){Om("setup_failed")}function qtt(){Om("timed_out")}var Wle={cancelled:"Skyramp cancelled this run",expired:"this attempt passed its deadline in Skyramp",ended:"Skyramp already ended this attempt"},Htt={cancelled:"cancelled",expired:"timed_out",ended:"agent_failed"};function $tt(t){return e=>Rtt(t.attempt,r=>{Om(Htt[r]),J(`Testbot V3: ${Wle[r]}; stopping the run, and uploading nothing.`),e("attempt-closed",Wle[r])})}async function ztt(t){let e=await Itt(t.attempt);return e?(Om(Htt[e]),J(`Testbot V3: ${Wle[e]}, so nothing is uploaded.`),!0):!1}function Gtt(t){return[...t.attempt.manifest.credentials.map(e=>process.env[e.name]??""),t.attempt.license?.runToken??"",...t.heldInputs??[]].filter(Boolean)}function jtt(t){return!t||t.includes("generate")?{}:{stages:["analyze","recommend"],planOnly:!0}}async function z$(t){t.cancelWatch?.stop();let e=await t.attempt.revokeTokens();for(let r of e)J(`Testbot V3: could not revoke a scoped GitHub token (${r}); it stays valid until it expires.`)}function Vtr(t){let e=["SIGINT","SIGTERM"],r=()=>{n(),z$({attempt:t})},n=()=>{for(let s of e)process.removeListener(s,r)};for(let s of e)process.on(s,r);return{stop:n}}async function Vtt(t){let e=Gtr(process.env),r=Ue("skyrampAppOrigin").trim()||Htr,n=await Ctt(t,process.env,jtr(r,e)),s=Vtr(n);In(ag.attemptId,n.attemptId),In(ag.origin,r),In(ag.deadlineAt,n.deadlineAt.toISOString()),ee(`Testbot V3: attempt ${n.attemptNumber} of Validation Run ${t}, deadline ${n.deadlineAt.toISOString()}`);try{return{...await Wtr(n),cancelWatch:s}}catch(i){throw await z$({attempt:n,cancelWatch:s}),i}}async function Wtr(t){let e=Ftt(t.manifest,process.env);if(e.length>0)throw Om("credential_missing"),new Error(`The workflow does not supply the required credential${e.length>1?"s":""} ${e.join(", ")}. Add ${e.length>1?"them":"it"} to the Testbot step's env.`);let r;try{r=await vtt(t,{workspace:DS.join(process.env.GITHUB_WORKSPACE||process.cwd(),$tr)})}catch(o){throw ZT(),o}for(let o of r)ee(`Testbot V3: ${o.slug} at ${o.revision}`);await Ytr({attempt:t,sources:r});let n=Ptt(r);ee(`Testbot V3: working checkout ${n.repositorySlug}`);let s=Ttt(t.manifest,r);s&&ee(`Testbot V3: the pull request is ${s.repository}#${s.number}`);let i=await Btt(t);for(let o of i)ee([`Testbot V3: Change Set ${o.repository}#${o.number}`,o.note].filter(Boolean).join(": "));return{attempt:t,sources:r,layout:n,pullRequests:i,pullRequest:s}}async function Ytr(t){for(let e of t.sources)jle(e.path);Yle(t)||await Jtr(t)}async function Jtr(t){let e=t.sources[0],r;try{r=await Qtt(t.attempt)}catch(n){if(!(n instanceof UE&&n.status===404))throw ZT(),n;J(`Testbot V3: this Skyramp app does not serve the stored SUT recipe (${n.message}); deploy uses a source's own recipe, if one has it.`);return}if(!r){ee("Testbot V3: no stored SUT recipe for this Target yet; deploy uses a source's own recipe, if one has it.");return}Utt(e.path,r.files),ee(`Testbot V3: SUT recipe version ${r.version}, ${r.files.length} files, for ${e.slug} (uncommitted)`)}function Wtt(t){try{let e=JSON.parse(QS.readFileSync(DS.join(t,"@skyramp","mcp","package.json"),"utf-8")).version;return typeof e=="string"&&/^[0-9A-Za-z.+-]{1,64}$/.test(e)?e:"unknown"}catch{return"unknown"}}async function Ytt(t,e,r){e.aborted?Om("cancelled"):e.timedOut&&Om("timed_out");let n=e.outputsDir?DS.join(e.outputsDir,"report.json"):void 0;if(!n||!QS.existsSync(n)){J("Testbot V3: the run wrote no report, so Skyramp records it as an infrastructure error.");return}if(!await ztt(t))try{let s=JSON.parse(QS.readFileSync(n,"utf-8"));await _tt(t.attempt,{report:s,sources:t.sources,workingSlug:t.layout.repositorySlug,delivery:Ltt(e.outputsDir,t.sources,s,t.layout.repositorySlug),producer:{testbot:nH().version,mcp:Wtt(r)},secrets:Gtt(t)}),In(ag.reportUploaded,"true"),ee("Testbot V3: report uploaded; Skyramp derives the outcome.")}catch(s){J(`Testbot V3: the report upload failed: ${s instanceof Error?s.message:String(s)}`)}}function Yle(t){return t.attempt.manifest.trigger.kind==="sut_setup"}async function Jtt(t){let{capture:e}=await Dtt(t.attempt);return ile(e.settings.target.environment,"the run's SUT / Environment settings")}var Ktr={onboard:"onboard",deploy:"deploy"};function Ktt(t){return({stage:e,event:r,status:n})=>{let s=Ktr[e];if(!s)return;let i=r==="finished",o=n==="aborted"?"skipped":n;Mtt(t.attempt,{schemaVersion:1,stage:s,event:i?"finished":"started",...i&&o?{status:o}:{}}).catch(a=>J(`Testbot V3: could not report ${e} ${r}: ${a instanceof Error?a.message:String(a)}`))}}var Vle=t=>{try{return JSON.parse(QS.readFileSync(t,"utf-8"))}catch{return}};async function Xtt(t,e,r){e.aborted?Om("cancelled"):e.timedOut&&Om("timed_out");let n=e.outputsDir?Vle(DS.join(e.outputsDir,"onboard.json")):void 0;if(!n){J("Testbot V3: onboard wrote no answer, so there is no SUT recipe to send; Skyramp records the run as an infrastructure error.");return}if(await ztt(t))return;let s=Vle(DS.join(e.outputsDir,"deploy.json")),o=(e.stateFilePath?Vle(e.stateFilePath):void 0)?.stages.deploy?.attempts?.reduce((a,c)=>a+(c.totalMs??c.durationMs??0),0);try{let a=sZe(n,s,{deployDurationSeconds:o?Math.round(o/1e3):void 0,recipeFiles:s?ole(t.layout.repositoryPath):void 0});await Ott(t.attempt,{recipe:a,sources:t.sources,producer:{testbot:nH().version,mcp:Wtt(r)},secrets:Gtt(t)}),In(ag.recipeUploaded,"true"),ee(`Testbot V3: SUT recipe uploaded (${a.status}); Skyramp derives the outcome.`)}catch(a){J(`Testbot V3: the SUT recipe upload failed: ${a instanceof Error?a.message:String(a)}`)}}function Xtr(t){let e=t.split(/[\n,]/).map(r=>r.trim()).filter(Boolean);return e.length?e:void 0}function Ztr(t){if((t("testRepoPath")??"").trim())return"testRepoPath is not supported by the staged pipeline (pipeline: staged) \u2014 it writes tests into the application checkout only, and the Action's token has no write access to another repository. Use pipeline: classic for cross-repository delivery, or remove the input."}async function err(t,e,r,n=process.env.GITHUB_WORKSPACE||process.cwd()){let s=(t("relatedRepoPaths")??"").trim();if(!s)return[];let i=[];for(let o of s.split(/[\n,]/).map(a=>a.trim()).filter(Boolean)){let a=cg.resolve(n,o);if(!yo(n,o)){r(`relatedRepoPaths: ${o} is outside the workspace \u2014 skipping`);continue}if(!MS.existsSync(a)){r(`relatedRepoPaths: no checkout at ${o} \u2014 skipping`);continue}let c=await e(a);if(!c){r(`relatedRepoPaths: could not resolve owner/repo for ${o} (no origin remote?) \u2014 skipping`);continue}i.push({slug:c,path:a})}return i}async function trr(t,e,r=process.env){let n=r.GITHUB_REPOSITORY_ID,s=r.GITHUB_REPOSITORY;return!n||!s?void 0:(await e(t).catch(()=>{}))?.toLowerCase()===s.toLowerCase()?{[n]:s}:void 0}async function Ztt(){let t=J1();delete process.env.INPUT_SKYRAMPLICENSEFILE;let e=dtt(process.env),r=Ue("skyrampRunId").trim(),n=r?await Vtt(r):void 0;try{await rrr(t,e,n)}finally{n&&await z$(n)}}async function rrr(t,e,r){let n=r!==void 0&&Yle(r);r&&(r.heldInputs=[t.skyrampLicenseFile].filter(Boolean));let s=r?r.layout.repositoryPath:cg.resolve(t.workingDirectory||"."),i=r?()=>r.attempt.token():ptt(),o=r?void 0:e;o&&Ct(o);let a=ltt(),c=new FH({repositoryPath:r?.pullRequest?.path??s,prNumber:a.prNumber,tokenProvider:i,githubToken:o,repoSlug:r?r.pullRequest?.repository??r.layout.repositorySlug:void 0,allowedAuthors:!n&&t.allowedAuthors?.length?t.allowedAuthors:void 0,log:q=>ee(q)});a=utt(a,await c.resolveContext().catch(()=>({}))),ee(`Staged pipeline \u2014 event: ${a.eventName??"?"}${a.action?`/${a.action}`:""}${a.prNumber?`, PR #${a.prNumber}`:""}${a.headRef?` (${a.headRef} \u2192 ${a.baseRef??"?"})`:""}`);let l=id(),u=cg.join(l,"staged");if(a.eventName==="pull_request"&&a.action==="closed"){let q=a.merged===!1,Z=q?`PR #${a.prNumber} was closed without merging`:`PR #${a.prNumber} was merged`;if(q&&a.headRef){let G=await c.closeTestsPr({branch:Ole(a.headRef,Ue("deliverBranch")||void 0),reason:`Closing: the pull request this tests PR targeted (#${a.prNumber}) was closed without being merged.`});G.closed&&(Z+=`; closed the tests PR ${G.url??""}`.trimEnd())}ee(`Staged pipeline \u2014 ${Z}; nothing to run.`);for(let[G,M]of Object.entries(XT({admission:{admit:!1,reason:Z}},{skippedPrClosed:q})))dt(G,M);In("completed","true");return}let d=await c.admitRun();if(!d.admit){ee(`Staged pipeline \u2014 run skipped: ${d.reason}`);for(let[q,Z]of Object.entries(XT({admission:d},{skippedSelfTrigger:!0})))dt(q,Z);In("completed","true");return}let p=r?r.layout.relatedRepos:await err(q=>Ue(q),q=>vm(q),q=>J(q)),m=Ztr(q=>Ue(q));if(m)throw new Error(m);let h=n||Ue("onboard").toLowerCase()==="true",f=ntt(Ue("sutGuidance"),"sutGuidance input"),A;try{A=n?await Jtt(r):CZe(Ue("sutEnvironment"),"sutEnvironment input")}catch(q){throw r&&ZT(),q}for(let q of d$(A))Ct(q);let x=r?Object.fromEntries(r.sources.map(q=>[q.repository.providerRepositoryId,q.slug])):await trr(s,q=>vm(q)),E,C,S=r?.attempt.license?.runToken,v;try{if(e||i){let Z=process.env.GITHUB_WORKSPACE,G=[...new Set([s,...p.map(F=>F.path),...Z?lXe(Z):[]].map(F=>cg.resolve(F)))],M;for(let F of G){let ne=F===cg.resolve(s)?re=>{/^\s*authorization\s*:/i.test(re)&&(M??=re)}:void 0,ye=aXe(F,void 0,ne);ye.length&&ee(`Removed the persisted checkout credential from ${F} (${ye.length} entr${ye.length===1?"y":"ies"}).`)}let $=cXe();$.length&&ee(`Removed ${$.length} persisted checkout credential(s) from RUNNER_TEMP.`),M&&(Ct(M.replace(/^AUTHORIZATION:\s*\S+\s+/i,"")),c.adoptCheckoutAuthHeader(M),ee("Deliver pushes with the credential the checkout was made with."))}else J("No githubToken or GitHub App credentials: the checkout's persisted git credential (if any) is left in place, and the stage sessions can reach it. Set persist-credentials: false on actions/checkout, or pass githubToken.");if(MS.mkdirSync(l,{recursive:!0}),!S){if(v=cg.join(l,"skyramp_license.lic"),!t.skyrampLicenseFile)throw new Error("skyrampLicenseFile input is required");MS.writeFileSync(v,t.skyrampLicenseFile,{mode:384})}let q=await jv(t);E=await tH(q,t,l),C=oU("claude",{model:t.model||void 0,useLocalAuth:t.useLocalAuth&&!t.useBedrock}),await iH(C),await oH(C),C.setupAgentEnv(t,q)}catch(q){r&&ZT();let Z=q instanceof Error?q.message:String(q);await c.createProgressSink().render(OH(Z,{runUrl:c.runUrl})).catch(()=>{}),await c.endRun({status:"failure",summary:`could not start: ${Z}`});for(let[G,M]of Object.entries(XT({admission:{admit:!0},startupError:q instanceof Error?q:new Error(Z)})))dt(G,M);In("completed","true"),Kc(`Skyramp Testbot could not start: ${Z}`);return}t.generatedTestsMode!=="separate-branch"&&J(`pipeline: staged delivers only as a separate tests PR; generatedTestsMode=${t.generatedTestsMode} means nothing is committed or pushed this run`);let B=r?r.attempt.budgetMs(new Date):(t.testbotTimeout||60)*6e4;if(B<=0)throw qtt(),new Error("Testbot V3: setup used the run's whole budget; no time is left before the attempt deadline");let{stages:N,planOnly:Q}=r&&!n?jtt(r.attempt.license?.entitlements):{};Q&&ee("Testbot V3: this organization's plan does not include test generation, so this run only analyzes the change and recommends tests.");let L=await Jet({admission:d,platform:c,watch:r?$tt(r):void 0,log:O$,skipReport:n,run:{runDir:u,fresh:!0,budgetMs:B,...n?{stages:["onboard","deploy"],skipReport:!0,onStageEvent:Ktt(r)}:{},...N?{stages:N}:{},model:Ue("model").trim()||void 0,resolveModel:mtt(t),inputs:{repositoryPath:s,repositorySlug:r?.layout.repositorySlug,pullRequestRepository:r?.pullRequest?.repository,baseBranch:!r&&a.baseRef?`origin/${a.baseRef}`:void 0,relatedRepos:p,headBranch:r?void 0:a.headRef,prTitle:a.title,prDescription:a.body,...r?.pullRequests?.length?{pullRequests:r.pullRequests}:{},planOnly:Q,skyrampMcp:{command:E.command,args:E.args.split(" ").filter(Boolean),licensePath:v,runToken:S},deliver:t.generatedTestsMode==="separate-branch"&&!Q,deliverBranch:Ue("deliverBranch")||void 0,trustedChecks:Xtr(Ue("trustedChecks")),deliverMode:a.eventName==="issue_comment"?"append":"replace",provisionRuntime:!0,runnerPlatform:"github",onboard:h&&!Q,sutGuidance:f,sutEnvironment:A,repositoryIds:x},sessionRunner:ttt(C.binary),sutAuth:{tokenCommand:t.authTokenCommand||void 0,uiCredentials:t.uiCredentials||void 0,sessionEnv:Het(Ue("sessionEnv")),maskSecret:q=>Ct(q),attempts:t.authTokenRetries,retryDelaySec:t.authTokenRetryDelay}}});r&&n?await Xtt(r,L.summary??{},E.nodeModulesDir):r&&await Ytt(r,L.summary??{},E.nodeModulesDir),L.admission.admit&&await ftt(u);let W=XT(L,{skippedSelfTrigger:!L.admission.admit});for(let[q,Z]of Object.entries(W))dt(q,Z);if(In("completed","true"),L.summary){await htt(L.summary,L.outcome),ee(`Staged run ${L.summary.runId}: ${L.outcome?.summary} (state: ${L.summary.stateFilePath})`);let q=U$(L.summary.stateFilePath);q&&(Ds("Stage breakdown (time / cost / context)"),ee(att(q,{order:L.summary.stages.map(Z=>Z.name),wallMinutes:q$(q)})),Sn())}L.startupError?Kc(`Skyramp Testbot could not start: ${L.startupError.message}`):L.outcome&&L.outcome.status==="failure"&&Kc(`Skyramp Testbot: ${L.outcome.summary}`)}var nrr=Ue("pipeline").trim().toLowerCase(),srr=nrr==="staged"?Ztt:kKe;srr().catch(async t=>{Kc(t instanceof Error?t.message:String(t))});
|
|
717
717
|
/*! Bundled license information:
|
|
718
718
|
|
|
719
719
|
undici/lib/web/fetch/body.js:
|
package/dist/post.js
CHANGED
|
@@ -212,7 +212,7 @@ ${o?Ar().abandonedBody:Ar().cancelledBody}
|
|
|
212
212
|
${s.join(`
|
|
213
213
|
`)}
|
|
214
214
|
|
|
215
|
-
<sub>[${Ar().workflowRunLinkLabel}](${e})</sub>`}t0();t0();t0();oy();function mU(t,e){if(process.env.GITHUB_ACTIONS)return new sh(t,rue,e);throw new Error("Unrecognized CI environment. Set GITHUB_ACTIONS=true for GitHub Actions, or use EvalPlatform directly for eval/testing.")}at();var r0=(r=>(r.Sufficient="sufficient",r.Insufficient="insufficient",r))(r0||{}),gU=(u=>(u.RelatedChangeConflict="related_change_conflict",u.ReferenceOutsideTarget="reference_outside_target",u.SourceAccessLost="source_access_lost",u.ConfigurationIncomplete="configuration_incomplete",u.CredentialUnavailable="credential_unavailable",u.WorkflowBindingUnverified="workflow_binding_unverified",u.DeploymentReview="deployment_review",u.SutRevisionMismatch="sut_revision_mismatch",u.IsolationUnavailable="isolation_unavailable",u.EvidenceInsufficient="evidence_insufficient",u))(gU||{}),yU=(s=>(s.CiCheck="ci_check",s.TestReport="test_report",s.StaticAnalysis="static_analysis",s.CodeReview="code_review",s.Other="other",s))(yU||{});var ay=(r=>(r.Ready="ready",r.Blocked="blocked",r))(ay||{}),Fs=T.string().trim().min(1),S4e=T.object({name:Fs,repository:Fs.describe("owner/repo of the repository the component is built from"),healthy:T.boolean()}),R4e=T.object({component:Fs,problem:Fs,evidence:Fs.describe("the exact command and output that shows it"),fix:Fs.describe("what the user must provide, and where")}),T4e=T.object({framework:Fs,file:Fs.describe("the test file run, relative to its repository root"),result:T.enum(["pass","fail","error"])}),N4e=T.object({input:Fs.describe("the part of the user's SUT input, as given"),reason:Fs}),iue=T.object({schemaVersion:T.literal(1),status:T.nativeEnum(ay).describe("ready only if every component came up healthy and the recipe is written"),components:T.array(S4e),suites:T.array(T4e).default([]).describe("one run per test suite the Target's repositories have; empty when they have none"),inputsUsed:T.array(Fs).default([]).describe("the parts of the user's SUT input the recipe used"),inputsNotUsed:T.array(N4e).default([]).describe("the parts it did not use, and why"),blockers:T.array(R4e).describe("required (non-empty) when status is blocked")});var cy=64*1024,ly=512*1024,EU=/[\u0000-\u0008\u000b\u000e-\u001f\u007f]|[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/;var sue=Ae(require("path"));var bU=(i=>(i.Clean="clean",i.RecipeDrift="recipe-drift",i.ChangeBrokeBringup="change-broke-bringup",i.BringupFailed="bringup-failed",i))(bU||{}),uy=T.string().trim().min(1),Q4e=T.object({url:T.string().optional().describe("the URL probed, if the check is an HTTP request"),command:T.string().optional().describe("the command run, if the check is a script \u2014 preferred when auth is needed"),headers:T.record(T.string()).optional(),status:T.union([T.number(),T.string()]).optional().describe("expected HTTP status for a url check (default 200)"),output:uy.describe("what the check returned, VERBATIM \u2014 the bytes, nothing appended; this gate RE-RUNS the check")}),_0t=T.object({schemaVersion:T.literal(1),baseUrls:T.record(T.string()).optional().describe("service \u2192 base URL of the running app; omit on a failed bring-up, never invent one"),health:Q4e.optional(),teardown:uy.describe("command that tears the SUT down"),dependencies:T.record(T.boolean()).optional().describe("EVERY backing service: true = really deployed, false = mocked; REQUIRED when the app came up"),outcome:T.nativeEnum(bU).describe("clean | recipe-drift (you corrected the recipe) | change-broke-bringup (the PR broke it) | bringup-failed (environment, not the PR)"),recipeFixes:T.array(T.string()).optional().describe("required when outcome is recipe-drift: what was corrected"),bringupError:T.object({command:uy,output:uy}).optional().describe("required when bring-up failed: the exact failing command and what it printed"),suspectFiles:T.array(T.string()).optional().describe("required for change-broke-bringup: files THIS PR changed that the failure points at, relative to your working directory (a file in another checkout of the run: its absolute path)"),seeded:T.boolean(),startedAt:uy.describe("ISO timestamp")});var Si=T.string().trim().min(1),oue=T.object({schemaVersion:T.literal(1),status:T.enum(["ready","blocked"]),components:T.array(T.object({name:Si,repository:Si.describe("owner/repo"),healthy:T.boolean(),url:T.string().min(1).nullable()}).strict()),suites:T.array(T.object({framework:Si,file:Si,result:T.enum(["pass","fail","error"])}).strict()),inputsUsed:T.array(Si),inputsNotUsed:T.array(T.object({input:Si,reason:Si}).strict()),blockers:T.array(T.object({component:Si,problem:Si,evidence:Si,fix:Si}).strict()),replay:T.object({outcome:Si,durationSeconds:T.number().nonnegative().nullable()}).strict().nullable(),files:T.array(T.object({path:Si,content:T.string()}).strict())}).strict(),L0t=["clean","recipe-drift"];function n0(t){let e=sue.posix.normalize(t);return e===t&&(e===".skyramp/workspace.yml"||e.startsWith(".skyramp/sut/")&&e.length>13)}var o0=(e=>(e.GitHub="github",e))(o0||{}),CU=(s=>(s.Trigger="TRIGGER",s.Baseline="BASELINE",s.AuthoritativeRelatedChange="AUTHORITATIVE_RELATED_CHANGE",s.ConfiguredSharedDependency="CONFIGURED_SHARED_DEPENDENCY",s.ManualOverride="MANUAL_OVERRIDE",s))(CU||{}),wU=(s=>(s.PullRequest="pull_request",s.ReadyForReview="ready_for_review",s.Schedule="schedule",s.Manual="manual",s.SutSetup="sut_setup",s))(wU||{}),v4e=["sut_setup"],k4e=["sut_setup"];var IU=(e=>(e.PullRequest="pull_request",e))(IU||{}),a0=(i=>(i.ModelProvider="model_provider",i.SutAccess="sut_access",i.Skyramp="skyramp",i.Other="other",i))(a0||{});var c0=(i=>(i.ReportUploaded="report_uploaded",i.NoReport="no_report",i.Cancelled="cancelled",i.RecipeUploaded="recipe_uploaded",i))(c0||{}),cue=(r=>(r.Running="running",r.Ended="ended",r))(cue||{}),l0=(s=>(s.TimedOut="timed_out",s.AgentFailed="agent_failed",s.SetupFailed="setup_failed",s.CredentialMissing="credential_missing",s.RunnerLost="runner_lost",s))(l0||{}),BU=(r=>(r.Onboard="onboard",r.Deploy="deploy",r))(BU||{}),xU=(r=>(r.Started="started",r.Finished="finished",r))(xU||{}),SU=(n=>(n.Passed="passed",n.Failed="failed",n.Skipped="skipped",n))(SU||{}),pl=T.string().regex(/^[1-9][0-9]{0,18}$/),i0=T.string().regex(/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/),Wa=T.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/),oh=T.string().regex(/^[0-9a-f]{64}$/),s0=T.object({id:Wa,revision:pl}).strict(),ld=T.object({provider:T.nativeEnum(o0),providerAccountId:pl,providerRepositoryId:pl}).strict(),lue=ld.extend({namespace:T.string().min(1),name:T.string().min(1)}).strict(),_4e=T.object({repository:lue,revision:i0,ref:T.string().nullable(),reason:T.nativeEnum(CU),change:T.object({kind:T.nativeEnum(IU),number:pl,base:T.object({ref:T.string().min(1),revision:i0}).strict().optional()}).strict().nullable()}).strict(),P4e=T.object({schemaVersion:T.literal(1),runId:Wa,skyrampOrgId:Wa,target:s0,policy:s0.nullable(),trigger:T.object({kind:T.nativeEnum(wU),requestedAt:T.string().datetime()}).strict(),configuration:T.object({captureId:Wa,revision:pl.nullable(),hash:oh}).strict(),baseline:T.object({confirmedRunId:Wa.nullable()}).strict(),sources:T.array(_4e).min(1),execution:T.object({provider:T.nativeEnum(o0),repository:lue,workflowPath:T.string(),ref:T.string()}).strict(),credentials:T.array(T.object({name:T.string(),purpose:T.nativeEnum(a0),required:T.boolean()}).strict())}).strict().superRefine((t,e)=>{let r=t.trigger.kind,n=v4e.includes(r);n!==(t.policy===null)&&e.addIssue({code:T.ZodIssueCode.custom,path:["policy"],message:n?`a ${r} run has no policy`:"names the policy revision"}),k4e.includes(r)&&t.sources.forEach((i,s)=>{i.reason!=="BASELINE"&&e.addIssue({code:T.ZodIssueCode.custom,path:["sources",s,"reason"],message:`a ${r} run selects only BASELINE sources`})})});var z0t=T.object({schemaVersion:T.literal(1),attempt:T.object({id:Wa,number:T.number().int().positive(),deadlineAt:T.string().datetime()}).strict(),manifest:P4e,manifestHash:oh,entitlements:T.array(T.string()).optional(),runToken:T.string().min(1).optional()}).strict(),V0t=T.object({schemaVersion:T.literal(1),runId:Wa,execution:T.object({provider:T.nativeEnum(o0),repository:ld,providerRunId:pl,providerRunAttempt:T.number().int().positive(),workflowRef:T.string().min(1)}).strict()}).strict(),aue=T.object({repository:ld,number:pl}).strict(),D4e=T.discriminatedUnion("status",[T.object({status:T.literal("none")}).strict(),T.object({status:T.literal("delivered"),pullRequests:T.array(aue).min(1)}).strict(),T.object({status:T.literal("partial"),pullRequests:T.array(aue).min(1),failures:T.array(T.object({repository:ld,message:T.string()}).strict()).min(1)}).strict(),T.object({status:T.literal("failed"),message:T.string()}).strict()]),M4e=T.object({sufficiency:T.nativeEnum(r0),rationale:T.string().min(1),gaps:T.array(T.string().min(1)),acceptedEvidence:T.array(T.object({kind:T.nativeEnum(yU),repository:T.string().min(1),revision:i0,reference:T.string().min(1),summary:T.string().min(1)}).strict()),actionRequired:T.array(T.nativeEnum(gU))}).strict().superRefine((t,e)=>{t.sufficiency==="sufficient"!=(t.gaps.length===0)&&e.addIssue({code:T.ZodIssueCode.custom,path:["gaps"],message:"sufficient evidence has no gaps, and insufficient evidence names at least one"}),new Set(t.actionRequired).size!==t.actionRequired.length&&e.addIssue({code:T.ZodIssueCode.custom,path:["actionRequired"],message:"a reason appears twice"})}),F4e=T.object({testResults:T.array(T.object({resultId:T.string().regex(/^[^\u0000-\u001f]{1,512}$/),repository:T.string().regex(/^[A-Za-z0-9._-]{1,100}\/[A-Za-z0-9._-]{1,100}$/),testType:T.string(),endpoint:T.string(),status:T.enum(["Pass","Fail","Skipped"]),details:T.string(),fileName:T.string().optional()}).strict()),validation:M4e}).passthrough().superRefine((t,e)=>{let r=new Set;t.testResults.forEach((n,i)=>{let s=["testResults",i,"resultId"],o=n.resultId.slice(`${n.repository}:${n.testType}:`.length);(!n.resultId.startsWith(`${n.repository}:${n.testType}:`)||o===""||o.startsWith("/")||o.startsWith("#"))&&e.addIssue({code:T.ZodIssueCode.custom,path:s,message:"is not repository:testType:path for this result"}),r.has(n.resultId)&&e.addIssue({code:T.ZodIssueCode.custom,path:s,message:"stable identity repeated"}),r.add(n.resultId)})});var L4e=T.object({schemaVersion:T.literal(1),run:T.object({runId:Wa,attemptNumber:T.number().int().positive(),manifestHash:oh}).strict(),target:s0,policy:s0,provenance:T.object({sources:T.array(T.object({repository:ld,revision:i0}).strict())}).strict(),delivery:T.object({generatedTests:D4e}).strict(),producer:T.object({testbot:T.string().regex(/^[0-9A-Za-z.+-]{1,64}$/),mcp:T.string().regex(/^[0-9A-Za-z.+-]{1,64}$/)}).strict(),report:F4e}).strict(),Y0t=L4e.pick({schemaVersion:!0,run:!0,target:!0,provenance:!0,producer:!0}).extend({recipe:oue}).strict().superRefine(({recipe:t},e)=>{let r=(s,o)=>e.addIssue({code:T.ZodIssueCode.custom,path:["recipe",...s],message:o});t.status==="blocked"&&t.blockers.length===0&&r(["blockers"],"a blocked recipe names at least one blocker");let n=new Set,i=0;t.files.forEach((s,o)=>{n0(s.path)||r(["files",o,"path"],"is not .skyramp/workspace.yml or a file under .skyramp/sut/"),n.has(s.path)&&r(["files",o,"path"],"file repeated"),n.add(s.path),EU.test(s.content)&&r(["files",o,"content"],"is not text");let a=Buffer.byteLength(s.content,"utf8");i+=a,a>cy&&r(["files",o,"content"],`larger than ${cy} bytes`)}),i>ly&&r(["files"],`recipe text over ${ly} bytes in total`)}),O4e=T.object({schemaVersion:T.literal(1),stage:T.nativeEnum(BU),event:T.nativeEnum(xU),status:T.nativeEnum(SU).optional()}).strict().refine(t=>t.status===void 0||t.event==="finished",{path:["status"],message:"only a finished stage has a status"}),U4e=T.object({schemaVersion:T.literal(1),configuration:T.object({captureId:Wa,revision:pl.nullable(),hash:oh}).strict(),capture:T.object({schemaVersion:T.literal(1),settings:T.object({target:T.object({environment:T.unknown()}).passthrough(),timeoutMinutes:T.number().int().positive()}).passthrough(),provenance:T.object({}).passthrough(),hash:oh}).strict()}).strict(),q4e=T.object({schemaVersion:T.literal(1),runtimePlan:T.object({version:T.number().int().positive(),contentHash:oh,files:T.array(T.object({path:T.string().refine(n0,"not a recipe file path"),content:T.string()}).strict()).min(1)}).strict().nullable()}).strict(),G4e=T.object({schemaVersion:T.literal(1),state:T.nativeEnum(cue),ending:T.nativeEnum(c0).nullable(),cause:T.nativeEnum(l0).nullable(),deadlineAt:T.string().datetime()}).strict();function uue(t){return t.reportUploaded?{schemaVersion:1,reason:"report_uploaded",cause:null}:t.recipeUploaded?{schemaVersion:1,reason:"recipe_uploaded",cause:null}:t.cancelled?{schemaVersion:1,reason:"cancelled",cause:null}:{schemaVersion:1,reason:"no_report",cause:H4e(t)}}function H4e(t){return t.credentialMissing?"credential_missing":t.setupFailed?"setup_failed":t.timedOut?"timed_out":"agent_failed"}at();fU();oy();var due;(function(t){t[t.lineFeed=10]="lineFeed",t[t.carriageReturn=13]="carriageReturn",t[t.space=32]="space",t[t._0=48]="_0",t[t._1=49]="_1",t[t._2=50]="_2",t[t._3=51]="_3",t[t._4=52]="_4",t[t._5=53]="_5",t[t._6=54]="_6",t[t._7=55]="_7",t[t._8=56]="_8",t[t._9=57]="_9",t[t.a=97]="a",t[t.b=98]="b",t[t.c=99]="c",t[t.d=100]="d",t[t.e=101]="e",t[t.f=102]="f",t[t.g=103]="g",t[t.h=104]="h",t[t.i=105]="i",t[t.j=106]="j",t[t.k=107]="k",t[t.l=108]="l",t[t.m=109]="m",t[t.n=110]="n",t[t.o=111]="o",t[t.p=112]="p",t[t.q=113]="q",t[t.r=114]="r",t[t.s=115]="s",t[t.t=116]="t",t[t.u=117]="u",t[t.v=118]="v",t[t.w=119]="w",t[t.x=120]="x",t[t.y=121]="y",t[t.z=122]="z",t[t.A=65]="A",t[t.B=66]="B",t[t.C=67]="C",t[t.D=68]="D",t[t.E=69]="E",t[t.F=70]="F",t[t.G=71]="G",t[t.H=72]="H",t[t.I=73]="I",t[t.J=74]="J",t[t.K=75]="K",t[t.L=76]="L",t[t.M=77]="M",t[t.N=78]="N",t[t.O=79]="O",t[t.P=80]="P",t[t.Q=81]="Q",t[t.R=82]="R",t[t.S=83]="S",t[t.T=84]="T",t[t.U=85]="U",t[t.V=86]="V",t[t.W=87]="W",t[t.X=88]="X",t[t.Y=89]="Y",t[t.Z=90]="Z",t[t.asterisk=42]="asterisk",t[t.backslash=92]="backslash",t[t.closeBrace=125]="closeBrace",t[t.closeBracket=93]="closeBracket",t[t.colon=58]="colon",t[t.comma=44]="comma",t[t.dot=46]="dot",t[t.doubleQuote=34]="doubleQuote",t[t.minus=45]="minus",t[t.openBrace=123]="openBrace",t[t.openBracket=91]="openBracket",t[t.plus=43]="plus",t[t.slash=47]="slash",t[t.formFeed=12]="formFeed",t[t.tab=9]="tab"})(due||(due={}));var V4e=new Array(20).fill(0).map((t,e)=>" ".repeat(e)),ah=200,Y4e={" ":{"\n":new Array(ah).fill(0).map((t,e)=>`
|
|
215
|
+
<sub>[${Ar().workflowRunLinkLabel}](${e})</sub>`}t0();t0();t0();oy();function mU(t,e){if(process.env.GITHUB_ACTIONS)return new sh(t,rue,e);throw new Error("Unrecognized CI environment. Set GITHUB_ACTIONS=true for GitHub Actions, or use EvalPlatform directly for eval/testing.")}at();var r0=(r=>(r.Sufficient="sufficient",r.Insufficient="insufficient",r))(r0||{}),gU=(d=>(d.RelatedChangeConflict="related_change_conflict",d.ReferenceOutsideTarget="reference_outside_target",d.SourceAccessLost="source_access_lost",d.ConfigurationIncomplete="configuration_incomplete",d.CredentialUnavailable="credential_unavailable",d.WorkflowBindingUnverified="workflow_binding_unverified",d.WorkflowRefUnprotected="workflow_ref_unprotected",d.DeploymentReview="deployment_review",d.SutRevisionMismatch="sut_revision_mismatch",d.IsolationUnavailable="isolation_unavailable",d.EvidenceInsufficient="evidence_insufficient",d))(gU||{}),yU=(s=>(s.CiCheck="ci_check",s.TestReport="test_report",s.StaticAnalysis="static_analysis",s.CodeReview="code_review",s.Other="other",s))(yU||{});var ay=(r=>(r.Ready="ready",r.Blocked="blocked",r))(ay||{}),Fs=T.string().trim().min(1),S4e=T.object({name:Fs,repository:Fs.describe("owner/repo of the repository the component is built from"),healthy:T.boolean()}),R4e=T.object({component:Fs,problem:Fs,evidence:Fs.describe("the exact command and output that shows it"),fix:Fs.describe("what the user must provide, and where")}),T4e=T.object({framework:Fs,file:Fs.describe("the test file run, relative to its repository root"),result:T.enum(["pass","fail","error"])}),N4e=T.object({input:Fs.describe("the part of the user's SUT input, as given"),reason:Fs}),iue=T.object({schemaVersion:T.literal(1),status:T.nativeEnum(ay).describe("ready only if every component came up healthy and the recipe is written"),components:T.array(S4e),suites:T.array(T4e).default([]).describe("one run per test suite the Target's repositories have; empty when they have none"),inputsUsed:T.array(Fs).default([]).describe("the parts of the user's SUT input the recipe used"),inputsNotUsed:T.array(N4e).default([]).describe("the parts it did not use, and why"),blockers:T.array(R4e).describe("required (non-empty) when status is blocked")});var cy=64*1024,ly=512*1024,EU=/[\u0000-\u0008\u000b\u000e-\u001f\u007f]|[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/;var sue=Ae(require("path"));var bU=(i=>(i.Clean="clean",i.RecipeDrift="recipe-drift",i.ChangeBrokeBringup="change-broke-bringup",i.BringupFailed="bringup-failed",i))(bU||{}),uy=T.string().trim().min(1),Q4e=T.object({url:T.string().optional().describe("the URL probed, if the check is an HTTP request"),command:T.string().optional().describe("the command run, if the check is a script \u2014 preferred when auth is needed"),headers:T.record(T.string()).optional(),status:T.union([T.number(),T.string()]).optional().describe("expected HTTP status for a url check (default 200)"),output:uy.describe("what the check returned, VERBATIM \u2014 the bytes, nothing appended; this gate RE-RUNS the check")}),_0t=T.object({schemaVersion:T.literal(1),baseUrls:T.record(T.string()).optional().describe("service \u2192 base URL of the running app; omit on a failed bring-up, never invent one"),health:Q4e.optional(),teardown:uy.describe("command that tears the SUT down"),dependencies:T.record(T.boolean()).optional().describe("EVERY backing service: true = really deployed, false = mocked; REQUIRED when the app came up"),outcome:T.nativeEnum(bU).describe("clean | recipe-drift (you corrected the recipe) | change-broke-bringup (the PR broke it) | bringup-failed (environment, not the PR)"),recipeFixes:T.array(T.string()).optional().describe("required when outcome is recipe-drift: what was corrected"),bringupError:T.object({command:uy,output:uy}).optional().describe("required when bring-up failed: the exact failing command and what it printed"),suspectFiles:T.array(T.string()).optional().describe("required for change-broke-bringup: files THIS PR changed that the failure points at, relative to your working directory (a file in another checkout of the run: its absolute path)"),seeded:T.boolean(),startedAt:uy.describe("ISO timestamp")});var Si=T.string().trim().min(1),oue=T.object({schemaVersion:T.literal(1),status:T.enum(["ready","blocked"]),components:T.array(T.object({name:Si,repository:Si.describe("owner/repo"),healthy:T.boolean(),url:T.string().min(1).nullable()}).strict()),suites:T.array(T.object({framework:Si,file:Si,result:T.enum(["pass","fail","error"])}).strict()),inputsUsed:T.array(Si),inputsNotUsed:T.array(T.object({input:Si,reason:Si}).strict()),blockers:T.array(T.object({component:Si,problem:Si,evidence:Si,fix:Si}).strict()),replay:T.object({outcome:Si,durationSeconds:T.number().nonnegative().nullable()}).strict().nullable(),files:T.array(T.object({path:Si,content:T.string()}).strict())}).strict(),L0t=["clean","recipe-drift"];function n0(t){let e=sue.posix.normalize(t);return e===t&&(e===".skyramp/workspace.yml"||e.startsWith(".skyramp/sut/")&&e.length>13)}var o0=(e=>(e.GitHub="github",e))(o0||{}),CU=(s=>(s.Trigger="TRIGGER",s.Baseline="BASELINE",s.AuthoritativeRelatedChange="AUTHORITATIVE_RELATED_CHANGE",s.ConfiguredSharedDependency="CONFIGURED_SHARED_DEPENDENCY",s.ManualOverride="MANUAL_OVERRIDE",s))(CU||{}),wU=(s=>(s.PullRequest="pull_request",s.ReadyForReview="ready_for_review",s.Schedule="schedule",s.Manual="manual",s.SutSetup="sut_setup",s))(wU||{}),v4e=["sut_setup"],k4e=["sut_setup"];var IU=(e=>(e.PullRequest="pull_request",e))(IU||{}),a0=(i=>(i.ModelProvider="model_provider",i.SutAccess="sut_access",i.Skyramp="skyramp",i.Other="other",i))(a0||{});var c0=(i=>(i.ReportUploaded="report_uploaded",i.NoReport="no_report",i.Cancelled="cancelled",i.RecipeUploaded="recipe_uploaded",i))(c0||{}),cue=(r=>(r.Running="running",r.Ended="ended",r))(cue||{}),l0=(s=>(s.TimedOut="timed_out",s.AgentFailed="agent_failed",s.SetupFailed="setup_failed",s.CredentialMissing="credential_missing",s.RunnerLost="runner_lost",s))(l0||{}),BU=(r=>(r.Onboard="onboard",r.Deploy="deploy",r))(BU||{}),xU=(r=>(r.Started="started",r.Finished="finished",r))(xU||{}),SU=(n=>(n.Passed="passed",n.Failed="failed",n.Skipped="skipped",n))(SU||{}),pl=T.string().regex(/^[1-9][0-9]{0,18}$/),i0=T.string().regex(/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/),Wa=T.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/),oh=T.string().regex(/^[0-9a-f]{64}$/),s0=T.object({id:Wa,revision:pl}).strict(),ld=T.object({provider:T.nativeEnum(o0),providerAccountId:pl,providerRepositoryId:pl}).strict(),lue=ld.extend({namespace:T.string().min(1),name:T.string().min(1)}).strict(),_4e=T.object({repository:lue,revision:i0,ref:T.string().nullable(),reason:T.nativeEnum(CU),change:T.object({kind:T.nativeEnum(IU),number:pl,base:T.object({ref:T.string().min(1),revision:i0}).strict().optional()}).strict().nullable()}).strict(),P4e=T.object({schemaVersion:T.literal(1),runId:Wa,skyrampOrgId:Wa,target:s0,policy:s0.nullable(),trigger:T.object({kind:T.nativeEnum(wU),requestedAt:T.string().datetime()}).strict(),configuration:T.object({captureId:Wa,revision:pl.nullable(),hash:oh}).strict(),baseline:T.object({confirmedRunId:Wa.nullable()}).strict(),sources:T.array(_4e).min(1),execution:T.object({provider:T.nativeEnum(o0),repository:lue,workflowPath:T.string(),ref:T.string()}).strict(),credentials:T.array(T.object({name:T.string(),purpose:T.nativeEnum(a0),required:T.boolean()}).strict())}).strict().superRefine((t,e)=>{let r=t.trigger.kind,n=v4e.includes(r);n!==(t.policy===null)&&e.addIssue({code:T.ZodIssueCode.custom,path:["policy"],message:n?`a ${r} run has no policy`:"names the policy revision"}),k4e.includes(r)&&t.sources.forEach((i,s)=>{i.reason!=="BASELINE"&&e.addIssue({code:T.ZodIssueCode.custom,path:["sources",s,"reason"],message:`a ${r} run selects only BASELINE sources`})})});var z0t=T.object({schemaVersion:T.literal(1),attempt:T.object({id:Wa,number:T.number().int().positive(),deadlineAt:T.string().datetime()}).strict(),manifest:P4e,manifestHash:oh,entitlements:T.array(T.string()).optional(),runToken:T.string().min(1).optional()}).strict(),V0t=T.object({schemaVersion:T.literal(1),runId:Wa,execution:T.object({provider:T.nativeEnum(o0),repository:ld,providerRunId:pl,providerRunAttempt:T.number().int().positive(),workflowRef:T.string().min(1)}).strict()}).strict(),aue=T.object({repository:ld,number:pl}).strict(),D4e=T.discriminatedUnion("status",[T.object({status:T.literal("none")}).strict(),T.object({status:T.literal("delivered"),pullRequests:T.array(aue).min(1)}).strict(),T.object({status:T.literal("partial"),pullRequests:T.array(aue).min(1),failures:T.array(T.object({repository:ld,message:T.string()}).strict()).min(1)}).strict(),T.object({status:T.literal("failed"),message:T.string()}).strict()]),M4e=T.object({sufficiency:T.nativeEnum(r0),rationale:T.string().min(1),gaps:T.array(T.string().min(1)),acceptedEvidence:T.array(T.object({kind:T.nativeEnum(yU),repository:T.string().min(1),revision:i0,reference:T.string().min(1),summary:T.string().min(1)}).strict()),actionRequired:T.array(T.nativeEnum(gU))}).strict().superRefine((t,e)=>{t.sufficiency==="sufficient"!=(t.gaps.length===0)&&e.addIssue({code:T.ZodIssueCode.custom,path:["gaps"],message:"sufficient evidence has no gaps, and insufficient evidence names at least one"}),new Set(t.actionRequired).size!==t.actionRequired.length&&e.addIssue({code:T.ZodIssueCode.custom,path:["actionRequired"],message:"a reason appears twice"})}),F4e=T.object({testResults:T.array(T.object({resultId:T.string().regex(/^[^\u0000-\u001f]{1,512}$/),repository:T.string().regex(/^[A-Za-z0-9._-]{1,100}\/[A-Za-z0-9._-]{1,100}$/),testType:T.string(),endpoint:T.string(),status:T.enum(["Pass","Fail","Skipped"]),details:T.string(),fileName:T.string().optional()}).strict()),validation:M4e}).passthrough().superRefine((t,e)=>{let r=new Set;t.testResults.forEach((n,i)=>{let s=["testResults",i,"resultId"],o=n.resultId.slice(`${n.repository}:${n.testType}:`.length);(!n.resultId.startsWith(`${n.repository}:${n.testType}:`)||o===""||o.startsWith("/")||o.startsWith("#"))&&e.addIssue({code:T.ZodIssueCode.custom,path:s,message:"is not repository:testType:path for this result"}),r.has(n.resultId)&&e.addIssue({code:T.ZodIssueCode.custom,path:s,message:"stable identity repeated"}),r.add(n.resultId)})});var L4e=T.object({schemaVersion:T.literal(1),run:T.object({runId:Wa,attemptNumber:T.number().int().positive(),manifestHash:oh}).strict(),target:s0,policy:s0,provenance:T.object({sources:T.array(T.object({repository:ld,revision:i0}).strict())}).strict(),delivery:T.object({generatedTests:D4e}).strict(),producer:T.object({testbot:T.string().regex(/^[0-9A-Za-z.+-]{1,64}$/),mcp:T.string().regex(/^[0-9A-Za-z.+-]{1,64}$/)}).strict(),report:F4e}).strict(),Y0t=L4e.pick({schemaVersion:!0,run:!0,target:!0,provenance:!0,producer:!0}).extend({recipe:oue}).strict().superRefine(({recipe:t},e)=>{let r=(s,o)=>e.addIssue({code:T.ZodIssueCode.custom,path:["recipe",...s],message:o});t.status==="blocked"&&t.blockers.length===0&&r(["blockers"],"a blocked recipe names at least one blocker");let n=new Set,i=0;t.files.forEach((s,o)=>{n0(s.path)||r(["files",o,"path"],"is not .skyramp/workspace.yml or a file under .skyramp/sut/"),n.has(s.path)&&r(["files",o,"path"],"file repeated"),n.add(s.path),EU.test(s.content)&&r(["files",o,"content"],"is not text");let a=Buffer.byteLength(s.content,"utf8");i+=a,a>cy&&r(["files",o,"content"],`larger than ${cy} bytes`)}),i>ly&&r(["files"],`recipe text over ${ly} bytes in total`)}),O4e=T.object({schemaVersion:T.literal(1),stage:T.nativeEnum(BU),event:T.nativeEnum(xU),status:T.nativeEnum(SU).optional()}).strict().refine(t=>t.status===void 0||t.event==="finished",{path:["status"],message:"only a finished stage has a status"}),U4e=T.object({schemaVersion:T.literal(1),configuration:T.object({captureId:Wa,revision:pl.nullable(),hash:oh}).strict(),capture:T.object({schemaVersion:T.literal(1),settings:T.object({target:T.object({environment:T.unknown()}).passthrough(),timeoutMinutes:T.number().int().positive()}).passthrough(),provenance:T.object({}).passthrough(),hash:oh}).strict()}).strict(),q4e=T.object({schemaVersion:T.literal(1),runtimePlan:T.object({version:T.number().int().positive(),contentHash:oh,files:T.array(T.object({path:T.string().refine(n0,"not a recipe file path"),content:T.string()}).strict()).min(1)}).strict().nullable()}).strict(),G4e=T.object({schemaVersion:T.literal(1),state:T.nativeEnum(cue),ending:T.nativeEnum(c0).nullable(),cause:T.nativeEnum(l0).nullable(),deadlineAt:T.string().datetime()}).strict();function uue(t){return t.reportUploaded?{schemaVersion:1,reason:"report_uploaded",cause:null}:t.recipeUploaded?{schemaVersion:1,reason:"recipe_uploaded",cause:null}:t.cancelled?{schemaVersion:1,reason:"cancelled",cause:null}:{schemaVersion:1,reason:"no_report",cause:H4e(t)}}function H4e(t){return t.credentialMissing?"credential_missing":t.setupFailed?"setup_failed":t.timedOut?"timed_out":"agent_failed"}at();fU();oy();var due;(function(t){t[t.lineFeed=10]="lineFeed",t[t.carriageReturn=13]="carriageReturn",t[t.space=32]="space",t[t._0=48]="_0",t[t._1=49]="_1",t[t._2=50]="_2",t[t._3=51]="_3",t[t._4=52]="_4",t[t._5=53]="_5",t[t._6=54]="_6",t[t._7=55]="_7",t[t._8=56]="_8",t[t._9=57]="_9",t[t.a=97]="a",t[t.b=98]="b",t[t.c=99]="c",t[t.d=100]="d",t[t.e=101]="e",t[t.f=102]="f",t[t.g=103]="g",t[t.h=104]="h",t[t.i=105]="i",t[t.j=106]="j",t[t.k=107]="k",t[t.l=108]="l",t[t.m=109]="m",t[t.n=110]="n",t[t.o=111]="o",t[t.p=112]="p",t[t.q=113]="q",t[t.r=114]="r",t[t.s=115]="s",t[t.t=116]="t",t[t.u=117]="u",t[t.v=118]="v",t[t.w=119]="w",t[t.x=120]="x",t[t.y=121]="y",t[t.z=122]="z",t[t.A=65]="A",t[t.B=66]="B",t[t.C=67]="C",t[t.D=68]="D",t[t.E=69]="E",t[t.F=70]="F",t[t.G=71]="G",t[t.H=72]="H",t[t.I=73]="I",t[t.J=74]="J",t[t.K=75]="K",t[t.L=76]="L",t[t.M=77]="M",t[t.N=78]="N",t[t.O=79]="O",t[t.P=80]="P",t[t.Q=81]="Q",t[t.R=82]="R",t[t.S=83]="S",t[t.T=84]="T",t[t.U=85]="U",t[t.V=86]="V",t[t.W=87]="W",t[t.X=88]="X",t[t.Y=89]="Y",t[t.Z=90]="Z",t[t.asterisk=42]="asterisk",t[t.backslash=92]="backslash",t[t.closeBrace=125]="closeBrace",t[t.closeBracket=93]="closeBracket",t[t.colon=58]="colon",t[t.comma=44]="comma",t[t.dot=46]="dot",t[t.doubleQuote=34]="doubleQuote",t[t.minus=45]="minus",t[t.openBrace=123]="openBrace",t[t.openBracket=91]="openBracket",t[t.plus=43]="plus",t[t.slash=47]="slash",t[t.formFeed=12]="formFeed",t[t.tab=9]="tab"})(due||(due={}));var V4e=new Array(20).fill(0).map((t,e)=>" ".repeat(e)),ah=200,Y4e={" ":{"\n":new Array(ah).fill(0).map((t,e)=>`
|
|
216
216
|
`+" ".repeat(e)),"\r":new Array(ah).fill(0).map((t,e)=>"\r"+" ".repeat(e)),"\r\n":new Array(ah).fill(0).map((t,e)=>`\r
|
|
217
217
|
`+" ".repeat(e))}," ":{"\n":new Array(ah).fill(0).map((t,e)=>`
|
|
218
218
|
`+" ".repeat(e)),"\r":new Array(ah).fill(0).map((t,e)=>"\r"+" ".repeat(e)),"\r\n":new Array(ah).fill(0).map((t,e)=>`\r
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skyramp/testbot-core",
|
|
3
|
-
"version": "0.12.0-v3.
|
|
3
|
+
"version": "0.12.0-v3.16",
|
|
4
4
|
"description": "Skyramp Testbot engine: AI-powered deterministic test generation, execution and maintenance",
|
|
5
5
|
"main": "dist/main.js",
|
|
6
6
|
"//files": "An explicit allowlist, never a glob. `dist/` is gitignored, so without this key npm's .gitignore fallback would publish a package with no engine in it; with a glob it would publish the sourcemaps, whose sourcesContent embeds every src/*.ts verbatim. eval-entry.js is a development entry and must not ship.",
|