From a88f85f881b1ddd7d03d4ab0dc77e2883eff1d33 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Wed, 29 Nov 2023 13:24:39 -0500 Subject: [PATCH 1/2] Hash the event validation errors to avoid dupe sends (#46917) --- package-lock.json | 25 +++++++++++++++++++------ package.json | 1 + src/events/middleware.js | 34 ++++++++++++++++++++++++++-------- 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6d52dc1053..f1f4b02978 100644 --- a/package-lock.json +++ b/package-lock.json @@ -68,6 +68,7 @@ "ora": "^7.0.1", "parse5": "7.1.2", "port-used": "^2.0.8", + "quick-lru": "7.0.0", "react": "18.2.0", "react-dom": "18.2.0", "rehype-highlight": "^7.0.0", @@ -2370,9 +2371,9 @@ } }, "node_modules/@primer/react/node_modules/@oddbird/popover-polyfill": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@oddbird/popover-polyfill/-/popover-polyfill-0.3.2.tgz", - "integrity": "sha512-H0Q8JcFkXrOt2FrP0cUz2qomU5O+Dfc51UYLk5GtDWmVhdmvtV2FhgaCUh3TA6U5dogMZOFAf3QbwiGXhe9LXQ==" + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@oddbird/popover-polyfill/-/popover-polyfill-0.3.5.tgz", + "integrity": "sha512-NpbjRxlc99/w/fWhOLMYl0m314HTiEwBtWfAs3z65rEw8pCX+NgUomscG3Ao6bbxaT3tLtSXRkDLx3u6gazIBw==" }, "node_modules/@primer/view-components": { "version": "0.1.4", @@ -7578,6 +7579,17 @@ "node": ">=10.19.0" } }, + "node_modules/http2-wrapper/node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/human-signals": { "version": "2.1.0", "dev": true, @@ -12321,10 +12333,11 @@ "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" }, "node_modules/quick-lru": { - "version": "5.1.1", - "license": "MIT", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-7.0.0.tgz", + "integrity": "sha512-MX8gB7cVYTrYcFfAnfLlhRd0+Toyl8yX8uBx1MrX7K0jegiz9TumwOK27ldXrgDlHRdVi+MqU9Ssw6dr4BNreg==", "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" diff --git a/package.json b/package.json index 7536514afb..ad82120ba1 100644 --- a/package.json +++ b/package.json @@ -265,6 +265,7 @@ "ora": "^7.0.1", "parse5": "7.1.2", "port-used": "^2.0.8", + "quick-lru": "7.0.0", "react": "18.2.0", "react-dom": "18.2.0", "rehype-highlight": "^7.0.0", diff --git a/src/events/middleware.js b/src/events/middleware.js index 13e8031ed0..94f5313d35 100644 --- a/src/events/middleware.js +++ b/src/events/middleware.js @@ -2,6 +2,8 @@ import express from 'express' import { omit, without, mapValues } from 'lodash-es' import Ajv from 'ajv' import addFormats from 'ajv-formats' +import QuickLRU from 'quick-lru' + import { schemas, hydroNames } from './lib/schema.js' import catchMiddlewareError from '#src/observability/middleware/catch-middleware-error.js' import { noCacheControl } from '#src/frame/middleware/cache-control.js' @@ -28,6 +30,11 @@ async function publish(...args) { return await _publish(...args) } +const sentValidationErrors = new QuickLRU({ + maxSize: 10_000, + maxAge: 1000 * 60, +}) + router.post( '/', catchMiddlewareError(async function postEvents(req, res) { @@ -42,14 +49,25 @@ router.post( // Validate the data matches the corresponding data schema const validate = validations[type] if (!validate(req.body)) { - // Track validation errors in Hydro so that we can know if - // there's a widespread problem in events.ts - await publish( - formatErrors(validate.errors, req.body).map((error) => ({ - schema: hydroNames.validation, - value: error, - })), - ) + const hash = `${req.ip}:${validate.errors + .map((error) => error.message + error.instancePath) + .join(':')}` + // This protects so we don't bother sending the same validation + // error, per user, more than once (per time interval). + // This helps if we're bombarded with junk bot traffic. So it + // protects our Hydro instance from being overloaded with things + // that aren't helping anybody. + if (!sentValidationErrors.has(hash)) { + sentValidationErrors.set(hash, true) + // Track validation errors in Hydro so that we can know if + // there's a widespread problem in events.ts + await publish( + formatErrors(validate.errors, req.body).map((error) => ({ + schema: hydroNames.validation, + value: error, + })), + ) + } // We aren't helping bots spam us :) return res.status(400).json(isProd ? {} : validate.errors) } From 2261a2faba219a0932420a739f1b456550c9a4fe Mon Sep 17 00:00:00 2001 From: Rachael Sewell Date: Wed, 29 Nov 2023 10:35:28 -0800 Subject: [PATCH 2/2] Deprecate GHES 3.6 (#46924) --- src/ghes-releases/lib/deprecation-steps.md | 32 ++++++++----------- .../lib/enterprise-server-releases.js | 4 +-- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/ghes-releases/lib/deprecation-steps.md b/src/ghes-releases/lib/deprecation-steps.md index 2275d1389e..11c715645c 100644 --- a/src/ghes-releases/lib/deprecation-steps.md +++ b/src/ghes-releases/lib/deprecation-steps.md @@ -101,10 +101,12 @@ The dates we use for Enterprise releases and deprecations are stored in [release 1. Remove the temporarily created directory from your `github/docs-internal` checkout. -## Step 4: Test the archived static pages +## Step 4: Deprecate the GHES release in docs-internal - [ ] Completed step 4 ✅ +This step will remove the version from the drop-down picker, effectively deprecating the version from a user's perspective. The content for the deperecated release will still exist in the Markdown files. + 1. In your `docs-internal` checkout, create a new branch: `git checkout -b deprecate-`. 1. In your `docs-internal` checkout, edit `lib/enterprise-server-releases.js` by removing the version number to be deprecated from the `supported` array and move it to the `deprecatedWithFunctionalRedirects` array. @@ -120,27 +122,21 @@ The dates we use for Enterprise releases and deprecations are stored in [release - You should see a banner on the top of every deprecated page with the date that the version was deprecated. - You should see a banner at the top of every page for the oldes currently supported version with the date that it will be deprecated in the ~3 months. -## Step 5: Deprecate the version in docs-internal +1. If everything looks good, check in the changes to `lib/enterprise-server-releases.js` and create a pull request. + +1. Ensure that CI is passing or make any changes to content needed to get tests to pass. + +1. 🚢 Ship the change. + +## Step 5: Create a tag - [ ] ✅ Completed step 5 -1. In your `deprecate-` branch, create a new branch: `git checkout -b deprecate-`. -1. Ensure that CI is passing or make any changes to content needed to get tests to pass. -1. 🚢 Ship the change. - -The version is now effectively deprecated. 🎉 - -## Step 🎉: You can complete the remaining steps in any order. And get a snack, you deserve it! 🍪 - -## Step 6: Create a tag - -- [ ] ✅ Completed step 6 - 1. Create a new tag for the most recent commit on the `main` branch so that we can keep track of where in commit history we removed the GHES release. Create a tag called `enterprise--release`. To create only a tag and not a release, you can [create a new release](https://github.com/github/docs-internal/releases), which allows you to "Choose a tag." Select add a new tag and use the tag name as the release title. After creating the new release, you wil see the new tag as well. You can then delete the release. -## Step 7: Remove static files for the version +## Step 6: Remove static files for the version -- [ ] Completed step 7 ✅ +- [ ] Completed step 6 ✅ 1. In your `docs-internal` checkout, create a new branch: `git checkout -b remove--data-files`. @@ -152,9 +148,9 @@ The version is now effectively deprecated. 🎉 1. When the PR is approved, merge it in. 🚢 -## Step 8: Remove the liquid conditionals and content for the version +## Step 7: Remove the liquid conditionals and content for the version -- [] Completed step 8 ✅ +- [ ] Completed step 7 ✅ 1. In your `docs-internal` checkout, create a new branch `remove--markup` branch: `git checkout -b remove--markup`. diff --git a/src/versions/lib/enterprise-server-releases.js b/src/versions/lib/enterprise-server-releases.js index fa32583ce1..491d6903a7 100644 --- a/src/versions/lib/enterprise-server-releases.js +++ b/src/versions/lib/enterprise-server-releases.js @@ -12,7 +12,7 @@ export const dates = JSON.parse(await fs.readFile('src/ghes-releases/lib/enterpr export const next = '3.12' export const nextNext = '3.13' -export const supported = ['3.11', '3.10', '3.9', '3.8', '3.7', '3.6'] +export const supported = ['3.11', '3.10', '3.9', '3.8', '3.7'] // Edit this to `null` when it's no longer the release candidate export const releaseCandidate = '3.11' @@ -40,7 +40,7 @@ function isValidNext(v1, v2) { // When you're archiving a version, add the new archived number to this // array and you should never need to touch the `deprecated` array // on the line just below. -export const deprecatedWithFunctionalRedirects = ['3.5', '3.4', '3.3', '3.2', '3.1', '3.0'] +export const deprecatedWithFunctionalRedirects = ['3.6', '3.5', '3.4', '3.3', '3.2', '3.1', '3.0'] export const deprecated = [ ...deprecatedWithFunctionalRedirects, '2.22',