feat(github): add orchestration ID to user-agent in getOctokitOptions#2364
Conversation
When ACTIONS_ORCHESTRATION_ID is set, appends
actions_orchestration_id/{sanitizedId} to the user-agent string.
- Add getUserAgentWithOrchestrationId() to internal/utils.ts
- Wire into getOctokitOptions() so all getOctokit() calls include it
- Re-export helper from @actions/github/lib/utils for downstream consumers
- 14 deterministic unit tests covering helper, integration, edge cases
There was a problem hiding this comment.
Pull request overview
This PR adds support for propagating the ACTIONS_ORCHESTRATION_ID into the Octokit user-agent via getOctokitOptions, aligning @actions/github with existing orchestration tracking behavior in other toolkit packages.
Changes:
- Added
getUserAgentWithOrchestrationId(baseUserAgent?)helper to read/sanitizeACTIONS_ORCHESTRATION_IDand append it to a user-agent string. - Updated
getOctokitOptions()to automatically apply the orchestration ID user-agent suffix when present. - Added unit tests covering helper behavior,
getOctokitOptionsintegration, and the public re-export; updated release notes.
Show a summary per file
| File | Description |
|---|---|
| packages/github/src/utils.ts | Re-exports the helper and appends orchestration ID to opts.userAgent in getOctokitOptions. |
| packages/github/src/internal/utils.ts | Introduces getUserAgentWithOrchestrationId (env read + sanitization + formatting). |
| packages/github/tests/orchestration.test.ts | Adds coverage for helper, re-export wiring, and getOctokitOptions behavior. |
| packages/github/RELEASES.md | Documents the new 9.1.0 behavior and export. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 4/4 changed files
- Comments generated: 1
| export {getUserAgentWithOrchestrationId} from './internal/utils.js' | ||
|
|
||
| /** | ||
| * Convience function to correctly format Octokit Options to pass into the constructor. |
There was a problem hiding this comment.
Spelling: "Convience" should be "Convenience" in the JSDoc comment to avoid propagating the typo into generated docs/search results.
| * Convience function to correctly format Octokit Options to pass into the constructor. | |
| * Convenience function to correctly format Octokit Options to pass into the constructor. |
There was a problem hiding this comment.
was already there, not related to change, good thing to fix tho
| if (orchId) { | ||
| const sanitizedId = orchId.replace(/[^a-z0-9_.-]/gi, '_') | ||
| const ua = baseUserAgent ? `${baseUserAgent} ` : '' | ||
| return `${ua}actions_orchestration_id/${sanitizedId}` |
There was a problem hiding this comment.
will concat the string together cause invalid user-agent format?
There was a problem hiding this comment.
The concatenation should be fine — the User-Agent spec (RFC 9110 §10.1.5) is just space-separated product/version tokens, and actions_orchestration_id/<sanitizedId> fits that since the ID is sanitized to [a-z0-9_.-].
Octokit already concatenates the same way internally (${options.userAgent} ${userAgentTrail}), so the final header ends up looking like:
actions_orchestration_id/abc123 octokit-core.js/6.1.3 Node.js/20
Also worth noting this is the same approach used by @actions/http-client and @actions/attest already in the toolkit.
| baseUserAgent?: string | ||
| ): string | undefined { | ||
| const orchId = process.env['ACTIONS_ORCHESTRATION_ID']?.trim() | ||
| if (orchId) { |
There was a problem hiding this comment.
should we check if base user agent already contains the orchestration ID? Or is that unlikely?
salmanmkc
left a comment
There was a problem hiding this comment.
Good catch — since getUserAgentWithOrchestrationId is exported as public API, downstream consumers (e.g., github-script) could call it directly while also using getOctokitOptions() which already appends the ID. A simple .includes() guard prevents double-appending.
Add idempotency check to getUserAgentWithOrchestrationId — if the tag is already present in baseUserAgent, return it unchanged. This prevents doubling when both the exported helper and getOctokitOptions run for the same client.
Summary
Appends
actions_orchestration_id/{sanitizedId}to the user-agent string when theACTIONS_ORCHESTRATION_IDenvironment variable is set. This follows the same pattern already used in@actions/http-clientand@actions/attest.Changes
packages/github/src/internal/utils.tsgetUserAgentWithOrchestrationId(baseUserAgent?)— reads env var, sanitizes with/[^a-z0-9_.-]/gi, appends to user-agent. Trims whitespace-only values.packages/github/src/utils.tsgetOctokitOptions()now calls the helper to include orchestration ID automaticallygetUserAgentWithOrchestrationIdfor downstream consumers (e.g.actions/github-script) via@actions/github/lib/utilspackages/github/__tests__/orchestration.test.tsgetOctokitOptionsintegration (auto-append, preserve caller UA, no mutation)packages/github/RELEASES.mdWhy
Actions orchestration needs to track which orchestration triggered API calls. The http-client and attest packages already do this —
@actions/githubwas the missing piece. This unblocks actions/github-script#708 from needing a local workaround.Testing
All 14 tests pass. No existing tests affected.