Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 8 additions & 12 deletions action.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name: 'Garnet Runtime Visibility'
description: 'Runtime profiling and behavioral assertions for GitHub Actions'
name: "Garnet Runtime Visibility"
description: "Runtime profiling and behavioral assertions for GitHub Actions"
branding:
icon: 'activity'
color: 'purple'
icon: "activity"
color: "purple"
inputs:
api_token:
description: 'Your Garnet API token from app.garnet.ai'
description: "Your Garnet API token from app.garnet.ai"
required: true
github_token:
description: "GitHub token used for pull request comments"
Expand All @@ -23,21 +23,17 @@ inputs:
description: "Jibril version (v2.10.8, v0.0, or 'latest')"
required: false
default: ""
profiler_4fun:
description: "Enable profiler 4 fun mode"
required: false
default: "false"
debug:
description: "Enable debug mode"
required: false
default: "false"
outputs:
profile_result:
description: 'Assertion result for this run: pass or fail'
description: "Assertion result for this run: pass or fail"
report_url:
description: 'Link to the full run report on app.garnet.ai'
description: "Link to the full run report on app.garnet.ai"
agent_id:
description: 'Identifier for the Jibril sensor instance that ran'
description: "Identifier for the Jibril sensor instance that ran"
runs:
using: "node24"
main: "dist/main/index.js"
Expand Down
114 changes: 70 additions & 44 deletions dist/main/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4377,7 +4377,6 @@ function defaultFactory (origin, opts) {

class Agent extends DispatcherBase {
constructor ({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) {

if (typeof factory !== 'function') {
throw new InvalidArgumentError('factory must be a function.')
}
Expand Down Expand Up @@ -4985,29 +4984,71 @@ class Parser {

const offset = llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr

if (ret === constants.ERROR.PAUSED_UPGRADE) {
this.onUpgrade(data.slice(offset))
} else if (ret === constants.ERROR.PAUSED) {
this.paused = true
socket.unshift(data.slice(offset))
} else if (ret !== constants.ERROR.OK) {
const ptr = llhttp.llhttp_get_error_reason(this.ptr)
let message = ''
/* istanbul ignore else: difficult to make a test case for */
if (ptr) {
const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0)
message =
'Response does not match the HTTP/1.1 protocol (' +
Buffer.from(llhttp.memory.buffer, ptr, len).toString() +
')'
}
throw new HTTPParserError(message, constants.ERROR[ret], data.slice(offset))
if (ret !== constants.ERROR.OK) {
const body = data.subarray(offset)

if (ret === constants.ERROR.PAUSED_UPGRADE) {
this.onUpgrade(body)
} else if (ret === constants.ERROR.PAUSED) {
this.paused = true
socket.unshift(body)
} else {
throw this.createError(ret, body)
}
}
} catch (err) {
util.destroy(socket, err)
}
}

finish () {
assert(currentParser === null)
assert(this.ptr != null)
assert(!this.paused)

const { llhttp } = this

let ret

try {
currentParser = this
ret = llhttp.llhttp_finish(this.ptr)
} finally {
currentParser = null
}

if (ret === constants.ERROR.OK) {
return null
}

if (ret === constants.ERROR.PAUSED || ret === constants.ERROR.PAUSED_UPGRADE) {
this.paused = true
return null
}

return this.createError(ret, EMPTY_BUF)
}

createError (ret, data) {
const { llhttp, contentLength, bytesRead } = this

if (contentLength && bytesRead !== parseInt(contentLength, 10)) {
return new ResponseContentLengthMismatchError()
}

const ptr = llhttp.llhttp_get_error_reason(this.ptr)
let message = ''
if (ptr) {
const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0)
message =
'Response does not match the HTTP/1.1 protocol (' +
Buffer.from(llhttp.memory.buffer, ptr, len).toString() +
')'
}

return new HTTPParserError(message, constants.ERROR[ret], data)
}

destroy () {
assert(this.ptr != null)
assert(currentParser == null)
Expand Down Expand Up @@ -5379,8 +5420,11 @@ async function connectH1 (client, socket) {
// On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded
// to the user.
if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) {
// We treat all incoming data so for as a valid response.
parser.onMessageComplete()
const parserErr = parser.finish()
if (parserErr) {
this[kError] = parserErr
this[kClient][kOnError](parserErr)
}
return
}

Expand All @@ -5399,8 +5443,10 @@ async function connectH1 (client, socket) {
const parser = this[kParser]

if (parser.statusCode && !parser.shouldKeepAlive) {
// We treat all incoming data so far as a valid response.
parser.onMessageComplete()
const parserErr = parser.finish()
if (parserErr) {
util.destroy(this, parserErr)
}
return
}

Expand All @@ -5412,8 +5458,7 @@ async function connectH1 (client, socket) {

if (parser) {
if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) {
// We treat all incoming data so far as a valid response.
parser.onMessageComplete()
this[kError] = parser.finish() || this[kError]
}

this[kParser].destroy()
Expand Down Expand Up @@ -31519,9 +31564,8 @@ AI_TEMPERATURE=${getEnv("AI_TEMPERATURE", "0.3")}
# Runner information
RUNNER_ARCH=${getEnv("RUNNER_ARCH")}
RUNNER_OS=${getEnv("RUNNER_OS")}
# Jibril writes profile markdown to these files (one per printer)
# Jibril writes profile outputs to these files
JIBRIL_PROFILER_FILE=${getEnv("JIBRIL_PROFILER_FILE")}
JIBRIL_PROFILER4FUN_FILE=${getEnv("JIBRIL_PROFILER4FUN_FILE")}
JIBRIL_JSONPROFILER_FILE=${getEnv("JIBRIL_JSONPROFILER_FILE")}
# GitHub context
GITHUB_ACTION=${getEnv("GITHUB_ACTION", "__run")}
Expand Down Expand Up @@ -31981,16 +32025,6 @@ async function main() {
}

try {
// Save whether profiler4fun mode is enabled as a boolean.
const profiler4fun = getInput("profiler_4fun") === "true"

// Store as string for state passing to post.js.
saveState("profiler4fun", profiler4fun ? "true" : "")
saveState(
"selectedProfiler",
profiler4fun ? "profiler4fun" : "profiler",
)

// Save debug state for later retrieval.
const debug = getInput("debug") === "true"
saveState("debug", debug ? "true" : "")
Expand All @@ -32013,20 +32047,12 @@ async function main() {
// Set the default profiler printer file paths.
const profilerFile =
process.env.JIBRIL_PROFILER_FILE || "/var/log/jibril.profiler.out"
const profiler4funFile =
process.env.JIBRIL_PROFILER4FUN_FILE || "/var/log/jibril.profiler4fun.out"
const jsonProfilerFile =
process.env.JIBRIL_JSONPROFILER_FILE || "/var/log/jibril.profile.json"
process.env.JIBRIL_PROFILER_FILE = profilerFile
process.env.JIBRIL_PROFILER4FUN_FILE = profiler4funFile
process.env.JIBRIL_JSONPROFILER_FILE = jsonProfilerFile
saveState("profilerFile", profilerFile)
saveState("profiler4funFile", profiler4funFile)
saveState("jsonProfilerFile", jsonProfilerFile)
saveState(
"selectedProfilerFile",
profiler4fun ? profiler4funFile : profilerFile,
)

await run()
} catch (err) {
Expand Down
Loading
Loading