Skip to content

Commit 13ac7de

Browse files
Copilotpelikhan
andauthored
fix: normalize INPUT_JOB_NAME hyphen form in OTLP span scripts (#24823)
Some GitHub Actions runner versions preserve the original hyphen in input env var names (INPUT_JOB-NAME) instead of converting to underscore (INPUT_JOB_NAME). This caused OTLP spans to fall back to the generic 'gh-aw.job.setup' / 'gh-aw.job.conclusion' names instead of using the actual job name. Apply the same two-key normalization already used for INPUT_TRACE_ID: - index.js: normalize INPUT_JOB_NAME at startup, pass to setup.sh env and set in process.env before calling action_setup_otlp.cjs - action_setup_otlp.cjs: normalize INPUT_JOB_NAME and canonicalize to underscore form so sendJobSetupSpan always finds the value - action_conclusion_otlp.cjs: normalize INPUT_JOB_NAME inline - setup.sh: explicitly pass INPUT_JOB_NAME to action_setup_otlp.cjs in script mode (alongside INPUT_TRACE_ID) Tests added for the hyphen form in action_conclusion_otlp.test.cjs and action_otlp.test.cjs. Agent-Logs-Url: https://github.com/github/gh-aw/sessions/099777bf-2d2a-4e33-b4a6-60eff2ca3d20 Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> Co-authored-by: Peli de Halleux <pelikhan@users.noreply.github.com>
1 parent d67c9c3 commit 13ac7de

File tree

6 files changed

+68
-2
lines changed

6 files changed

+68
-2
lines changed

actions/setup/index.js

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

actions/setup/js/action_conclusion_otlp.cjs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ async function run() {
4848
const rawJobStartMs = parseInt(process.env.GITHUB_AW_OTEL_JOB_START_MS || "0", 10);
4949
const startMs = rawJobStartMs > 0 ? rawJobStartMs : undefined;
5050

51-
const spanName = process.env.INPUT_JOB_NAME ? `gh-aw.${process.env.INPUT_JOB_NAME}.conclusion` : "gh-aw.job.conclusion";
51+
// Normalize job-name input: handle both INPUT_JOB_NAME (underscore, standard)
52+
// and INPUT_JOB-NAME (hyphen, used by some runner versions).
53+
const jobName = (process.env.INPUT_JOB_NAME || process.env["INPUT_JOB-NAME"] || "").trim();
54+
const spanName = jobName ? `gh-aw.${jobName}.conclusion` : "gh-aw.job.conclusion";
5255
console.log(`[otlp] sending conclusion span "${spanName}" to ${endpoint}`);
5356

5457
await sendOtlpSpan.sendJobConclusionSpan(spanName, { startMs });

actions/setup/js/action_conclusion_otlp.test.cjs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ describe("action_conclusion_otlp.cjs", () => {
2828
originalEnv = {
2929
OTEL_EXPORTER_OTLP_ENDPOINT: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
3030
INPUT_JOB_NAME: process.env.INPUT_JOB_NAME,
31+
"INPUT_JOB-NAME": process.env["INPUT_JOB-NAME"],
3132
GITHUB_AW_OTEL_JOB_START_MS: process.env.GITHUB_AW_OTEL_JOB_START_MS,
3233
};
3334
delete process.env.OTEL_EXPORTER_OTLP_ENDPOINT;
3435
delete process.env.INPUT_JOB_NAME;
36+
delete process.env["INPUT_JOB-NAME"];
3537
delete process.env.GITHUB_AW_OTEL_JOB_START_MS;
3638
});
3739

@@ -49,6 +51,11 @@ describe("action_conclusion_otlp.cjs", () => {
4951
} else {
5052
delete process.env.INPUT_JOB_NAME;
5153
}
54+
if (originalEnv["INPUT_JOB-NAME"] !== undefined) {
55+
process.env["INPUT_JOB-NAME"] = originalEnv["INPUT_JOB-NAME"];
56+
} else {
57+
delete process.env["INPUT_JOB-NAME"];
58+
}
5259
if (originalEnv.GITHUB_AW_OTEL_JOB_START_MS !== undefined) {
5360
process.env.GITHUB_AW_OTEL_JOB_START_MS = originalEnv.GITHUB_AW_OTEL_JOB_START_MS;
5461
} else {
@@ -113,6 +120,15 @@ describe("action_conclusion_otlp.cjs", () => {
113120
expect(mockSendJobConclusionSpan).toHaveBeenCalledWith("gh-aw.agent.conclusion", { startMs: undefined });
114121
});
115122

123+
it("should use job name from INPUT_JOB-NAME (hyphen form) when INPUT_JOB_NAME is not set", async () => {
124+
delete process.env.INPUT_JOB_NAME;
125+
process.env["INPUT_JOB-NAME"] = "agent";
126+
127+
await run();
128+
129+
expect(mockSendJobConclusionSpan).toHaveBeenCalledWith("gh-aw.agent.conclusion", { startMs: undefined });
130+
});
131+
116132
it("should log the full span name in the sending message", async () => {
117133
process.env.INPUT_JOB_NAME = "setup";
118134

actions/setup/js/action_otlp.test.cjs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,32 @@ describe("action_setup_otlp run()", () => {
152152
fetchSpy.mockRestore();
153153
});
154154

155+
it("uses job name from INPUT_JOB-NAME (hyphen form) in setup span when INPUT_JOB_NAME is not set", async () => {
156+
const tmpOut = path.join(path.dirname(__dirname), `action_setup_otlp_test_job_name_hyphen_${Date.now()}.txt`);
157+
try {
158+
process.env.OTEL_EXPORTER_OTLP_ENDPOINT = "http://localhost:14317";
159+
process.env["INPUT_JOB-NAME"] = "agent";
160+
delete process.env.INPUT_JOB_NAME;
161+
process.env.GITHUB_OUTPUT = tmpOut;
162+
process.env.GITHUB_ENV = tmpOut;
163+
164+
let capturedBody;
165+
const fetchSpy = vi.spyOn(global, "fetch").mockImplementation((_url, opts) => {
166+
capturedBody = opts?.body;
167+
return Promise.resolve(new Response(null, { status: 200 }));
168+
});
169+
170+
await runSetup();
171+
172+
const payload = JSON.parse(capturedBody);
173+
const spanName = payload?.resourceSpans?.[0]?.scopeSpans?.[0]?.spans?.[0]?.name;
174+
expect(spanName).toBe("gh-aw.agent.setup");
175+
fetchSpy.mockRestore();
176+
} finally {
177+
fs.rmSync(tmpOut, { force: true });
178+
}
179+
});
180+
155181
it("includes github.repository, github.run_id resource attributes in setup span", async () => {
156182
const tmpOut = path.join(path.dirname(__dirname), `action_setup_otlp_test_resource_attrs_${Date.now()}.txt`);
157183
try {

actions/setup/js/action_setup_otlp.cjs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,18 @@ async function run() {
5757
console.log("[otlp] INPUT_TRACE_ID not set, a new trace ID will be generated");
5858
}
5959

60+
// Normalize job-name input: handle both INPUT_JOB_NAME (underscore, standard)
61+
// and INPUT_JOB-NAME (hyphen, used by some runner versions). Mirror the same
62+
// two-key lookup that INPUT_TRACE_ID uses above so script-mode invocations
63+
// (setup.sh → node action_setup_otlp.cjs) always resolve the job name even
64+
// when the runner preserves the original hyphen in the env var name.
65+
const inputJobName = (process.env.INPUT_JOB_NAME || process.env["INPUT_JOB-NAME"] || "").trim();
66+
if (inputJobName) {
67+
// Normalise to the canonical underscore form so sendJobSetupSpan (which
68+
// reads process.env.INPUT_JOB_NAME) always finds the value.
69+
process.env.INPUT_JOB_NAME = inputJobName;
70+
}
71+
6072
if (!endpoint) {
6173
console.log("[otlp] OTEL_EXPORTER_OTLP_ENDPOINT not set, skipping setup span");
6274
} else {

actions/setup/setup.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ fi
407407
# Skipped when GH_AW_SKIP_SETUP_OTLP=1 because index.js will send the span itself.
408408
if [ -z "${GH_AW_SKIP_SETUP_OTLP}" ] && command -v node &>/dev/null && [ -f "${DESTINATION}/action_setup_otlp.cjs" ]; then
409409
debug_log "Sending OTLP setup span..."
410-
SETUP_START_MS="${SETUP_START_MS}" INPUT_TRACE_ID="${INPUT_TRACE_ID:-}" node "${DESTINATION}/action_setup_otlp.cjs" || true
410+
SETUP_START_MS="${SETUP_START_MS}" INPUT_TRACE_ID="${INPUT_TRACE_ID:-}" INPUT_JOB_NAME="${INPUT_JOB_NAME:-}" node "${DESTINATION}/action_setup_otlp.cjs" || true
411411
debug_log "OTLP setup span step complete"
412412
fi
413413

0 commit comments

Comments
 (0)