From 5a63615d7d8283dca835a5559c0ebd904e60da56 Mon Sep 17 00:00:00 2001 From: Rachael Rose Renk <91027132+rachaelrenk@users.noreply.github.com> Date: Wed, 26 Mar 2025 12:55:29 -0600 Subject: [PATCH 1/2] Improve GHES release templates (#54198) Co-authored-by: Kevin Heis --- .../lib/release-templates/release-steps-0.md | 6 +++--- .../lib/release-templates/release-steps-1.md | 4 +++- .../lib/release-templates/release-steps-2.md | 4 +++- .../lib/release-templates/release-steps-5.md | 14 ++++++++------ 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/ghes-releases/lib/release-templates/release-steps-0.md b/src/ghes-releases/lib/release-templates/release-steps-0.md index 0af6bcc4bb06..edce01ffb755 100644 --- a/src/ghes-releases/lib/release-templates/release-steps-0.md +++ b/src/ghes-releases/lib/release-templates/release-steps-0.md @@ -8,6 +8,7 @@ labels: - skip FR board - GHES {{ release-number }} - ghes-release-automation + - rhythm of docs operations --- This issue tracks Docs work for the GA release of GHES {{ release-number }}. @@ -26,11 +27,11 @@ This issue tracks Docs work for the GA release of GHES {{ release-number }}. ## Instructions for triage -- [ ] In the Enterprise project, adjust the "Cycle" field to the cycle containing the target date. +- [ ] Add this issue to the [Rhythm of Docs: Operations](https://github.com/orgs/github/projects/20190) project. +- [ ] For assignee: if needed, add this issue to your persona team project for tracking purposes.
-```[tasklist] # Tasks - [ ] {{ release-steps-1-url }} - [ ] {{ release-steps-2-url }} @@ -43,7 +44,6 @@ This issue tracks Docs work for the GA release of GHES {{ release-number }}. - [ ] After merging PR for RC, notify the API team in [#ecosystem-api](https://github.slack.com/archives/C1042T6MS) on Slack that they can now merge "Update OpenAPI 3.x Descriptions" PRs in [`github/rest-api-description`](https://github.com/github/rest-api-description/pulls), which you blocked as part of the issue for preparing OpenAPI assets. - [ ] Notify the Docs Content first responder (`@TBD`) that they can now merge OpenAPI PRs. - [ ] To close this issue, open a PR to complete [these steps](https://github.com/github/docs-content/issues/12972#issuecomment-1947981671). -``` ## Resources diff --git a/src/ghes-releases/lib/release-templates/release-steps-1.md b/src/ghes-releases/lib/release-templates/release-steps-1.md index a8eae61373d0..677df370f0c1 100644 --- a/src/ghes-releases/lib/release-templates/release-steps-1.md +++ b/src/ghes-releases/lib/release-templates/release-steps-1.md @@ -5,12 +5,14 @@ labels: - new-release - priority-0 - skip FR board + - rhythm of docs operations - GHES {{ release-number }} --- ## Instructions for triage -- [ ] In the Enterprise project, adjust the "Cycle" field to the cycle containing the target date. +- [ ] Add this issue to the [Rhythm of Docs: Operations](https://github.com/orgs/github/projects/20190) project. +- [ ] For assignee: if needed, add this issue to your persona team project for tracking purposes. ## Instructions for assignee diff --git a/src/ghes-releases/lib/release-templates/release-steps-2.md b/src/ghes-releases/lib/release-templates/release-steps-2.md index 45c2c15840b7..93f61b3e4551 100644 --- a/src/ghes-releases/lib/release-templates/release-steps-2.md +++ b/src/ghes-releases/lib/release-templates/release-steps-2.md @@ -6,11 +6,13 @@ labels: - priority-0 - skip FR board - GHES {{ release-number }} + - rhythm of docs operations --- ## Instructions for triage -- [ ] In the Enterprise project, adjust the "Cycle" field to the cycle **four weeks** before the target date. +- [ ] Add this issue to the [Rhythm of Docs: Operations](https://github.com/orgs/github/projects/20190) project. +- [ ] For assignee: if needed, add this issue to your persona team project for tracking purposes. ## Instructions for assignee diff --git a/src/ghes-releases/lib/release-templates/release-steps-5.md b/src/ghes-releases/lib/release-templates/release-steps-5.md index 0bc799d1e533..5ddfa696f2ba 100644 --- a/src/ghes-releases/lib/release-templates/release-steps-5.md +++ b/src/ghes-releases/lib/release-templates/release-steps-5.md @@ -6,11 +6,13 @@ labels: - new-release - priority-0 - skip FR board + - rhythm of docs operations --- ## Instructions for triage -- [ ] In the Enterprise focus area's project, adjust the "Cycle" field for this issue to the cycle four weeks before the target date. +- [ ] Add this issue to the [Rhythm of Docs: Operations](https://github.com/orgs/github/projects/20190) project. +- [ ] For assignee: if needed, add this issue to your persona team project for tracking purposes. ## Instructions for assignee @@ -83,7 +85,7 @@ To prepare for publication, create a PR in `github/github` that publishes the sc - [ ] Create a PR. -- [ ] Get the necessary reviews, but **do not deploy and merge the PR**. You'll merge this PR closer to the RC's release date, while Docs' repositories are frozen. +- [ ] Get the necessary reviews, but **do not deploy and merge the PR yet**. You'll merge this PR closer to the RC's release date.
@@ -92,19 +94,19 @@ To prepare for publication, create a PR in `github/github` that publishes the sc To trigger creation of an OpenAPI PR with the updated schema for the RC, merge your publication PR in `github/github`. -- [ ] On the Thursday after you begin the freeze of Docs' repositories per {{ release-steps-0-url }}, merge the publication PR you [prepared in `github/github`](#publication-preparation). +- [ ] 2-3 days before the RC release date, merge the publication PR you [prepared in `github/github`](#publication-preparation). -- [ ] In [#ecosystem-api](https://github.slack.com/archives/C1042T6MS) on Slack, update and then post the following message to notify the team of the upcoming release. Replace VERSION with the version we're releasing. +- [ ] In [#api-platform](https://github.slack.com/archives/C1042T6MS) on Slack, update and then post the following message to notify the team of the upcoming release. Replace VERSION with the version we're releasing. > 👋 Hi from Docs! We have just marked `published` for the GHES VERSION release configuration to `true`. Please **do not** merge subsequent "Update OpenAPI 3.x Descriptions" PRs [in github/rest-api-description](https://github.com/github/rest-api-description/pulls) until further notice. Thanks! -- [ ] On the Friday during the freeze, locate the latest "Update OpenAPI 3.x Descriptions" PRs [in `github/rest-api-description`](https://github.com/github/rest-api-description/pulls). +- [ ] Locate the latest "Update OpenAPI 3.x Descriptions" PRs [in `github/rest-api-description`](https://github.com/github/rest-api-description/pulls). - [ ] On each new PR, leave a review that requests changes with the following comment. > This PR contains changes for the upcoming GHES RC. Please do not merge this or subsequent PRs until further notice in #ecosystem-api. Thanks! -- [ ] From now until after the freeze, all [existing "Update OpenAPI Description" PRs](https://github.com/github/docs-internal/labels/github-openapi-bot) in `github/docs-internal` can be closed. +- [ ] From now until the RC ships, all [existing "Update OpenAPI Description" PRs](https://github.com/github/docs-internal/labels/github-openapi-bot) in `github/docs-internal` can be closed. To get the latest changes from the latest "Update OpenAPI 3.x Descriptions" PR in the `github/rest-api-description` repository into your PR to close {{ release-steps-1-url }}, you can use one of two methods. From c6b1250734bac7d41178f5287167ba4da4beea33 Mon Sep 17 00:00:00 2001 From: Evan Bonsignori Date: Wed, 26 Mar 2025 13:01:01 -0700 Subject: [PATCH 2/2] add diagnostics to ai search route (#55008) --- src/search/lib/ai-search-proxy.ts | 46 ++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/src/search/lib/ai-search-proxy.ts b/src/search/lib/ai-search-proxy.ts index 3eebf7ba3dbf..54d3d28146fb 100644 --- a/src/search/lib/ai-search-proxy.ts +++ b/src/search/lib/ai-search-proxy.ts @@ -1,12 +1,14 @@ import { Request, Response } from 'express' +import statsd from '@/observability/lib/statsd' import got from 'got' import { getHmacWithEpoch } from '@/search/lib/helpers/get-cse-copilot-auth' -import { getCSECopilotSource } from '#src/search/lib/helpers/cse-copilot-docs-versions.js' +import { getCSECopilotSource } from '@/search/lib/helpers/cse-copilot-docs-versions' const memoryCache = new Map() export const aiSearchProxy = async (req: Request, res: Response) => { const { query, version, language } = req.body + const errors = [] // Validate request body @@ -34,13 +36,25 @@ export const aiSearchProxy = async (req: Request, res: Response) => { return } + const diagnosticTags = [ + `version:${version}`.slice(0, 200), + `language:${language}`.slice(0, 200), + `queryLength:${query.length}`.slice(0, 200), + ] + statsd.increment('ai-search.call', 1, diagnosticTags) + + // TODO: Caching here may cause an issue if the cache grows too large. Additionally, the cache will be inconsistent across pods const cacheKey = `${query}:${version}:${language}` if (memoryCache.has(cacheKey)) { + statsd.increment('ai-search.cache_hit', 1, diagnosticTags) res.setHeader('Content-Type', 'application/x-ndjson') res.send(memoryCache.get(cacheKey)) return } + const startTime = Date.now() + let totalChars = 0 + const body = { chat_context: 'docs', docs_source: docsSource, @@ -57,22 +71,19 @@ export const aiSearchProxy = async (req: Request, res: Response) => { }, }) - const chunks: Buffer[] = [] - stream.on('data', (chunk) => { - chunks.push(chunk) + // Listen for data events to count characters + stream.on('data', (chunk: Buffer | string) => { + // Ensure we have a string for proper character count + const dataStr = typeof chunk === 'string' ? chunk : chunk.toString() + totalChars += dataStr.length }) // Handle the upstream response before piping stream.on('response', (upstreamResponse) => { - // When cse-copilot returns a 204, it means the backend received the request - // but was unable to answer the question. So we return a 400 to the client to be handled. - if (upstreamResponse.statusCode === 204) { - return res - .status(400) - .json({ errors: [{ message: 'Sorry I am unable to answer this question.' }] }) - } else if (upstreamResponse.statusCode !== 200) { + if (upstreamResponse.statusCode !== 200) { const errorMessage = `Upstream server responded with status code ${upstreamResponse.statusCode}` console.error(errorMessage) + statsd.increment('ai-search.stream_response_error', 1, diagnosticTags) res.status(500).json({ errors: [{ message: errorMessage }] }) stream.destroy() } else { @@ -95,6 +106,8 @@ export const aiSearchProxy = async (req: Request, res: Response) => { .json({ errors: [{ message: 'Sorry I am unable to answer this question.' }] }) } + statsd.increment('ai-search.stream_error', 1, diagnosticTags) + if (!res.headersSent) { res.status(500).json({ errors: [{ message: 'Internal server error' }] }) } else { @@ -106,12 +119,19 @@ export const aiSearchProxy = async (req: Request, res: Response) => { } }) - // Ensure response ends when stream ends + // Calculate metrics on stream end stream.on('end', () => { - memoryCache.set(cacheKey, Buffer.concat(chunks as Uint8Array[])) + const totalResponseTime = Date.now() - startTime // in ms + const charPerMsRatio = totalResponseTime > 0 ? totalChars / totalResponseTime : 0 // chars per ms + + statsd.gauge('ai-search.total_response_time', totalResponseTime, diagnosticTags) + statsd.gauge('ai-search.response_chars_per_ms', charPerMsRatio, diagnosticTags) + + statsd.increment('ai-search.success_stream_end', 1, diagnosticTags) res.end() }) } catch (error) { + statsd.increment('ai-search.route_error', 1, diagnosticTags) console.error('Error posting /answers to cse-copilot:', error) res.status(500).json({ errors: [{ message: 'Internal server error' }] }) }