diff --git a/.github/workflows/open-enterprise-issue.yml b/.github/workflows/open-enterprise-issue.yml index a8e96be3f6..3e64fd65cb 100644 --- a/.github/workflows/open-enterprise-issue.yml +++ b/.github/workflows/open-enterprise-issue.yml @@ -5,6 +5,7 @@ name: Open Enterprise release or deprecation issue # **Who does it impact**: Docs engineering, docs content. on: + workflow_dispatch: schedule: - cron: '49 14 * * *' # At 14:49 UTC daily @@ -28,11 +29,11 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Update enterprise dates - if: steps.existingIssue.outputs.deprecationIssue == 'false' || steps.existingIssue.outputs.releaseIssue == 'false' + if: steps.existingIssue.outputs.deprecationIssue == 'false' || steps.existingIssue.outputs.releaseIssue == 'false' run: | script/update-enterprise-dates.js env: - GITHUB_TOKEN: ${{ secrets.DOCUBOT_FR_PROJECT_BOARD_WORKFLOWS_REPO_ORG_READ_SCOPES }} + GITHUB_TOKEN: ${{ secrets.DOCS_BOT }} - name: Create an enterprise release issue if: steps.existingIssue.outputs.releaseIssue == 'false' diff --git a/assets/images/help/settings/appearance-tab.png b/assets/images/help/settings/appearance-tab.png index 4b3d85b669..03862ad503 100644 Binary files a/assets/images/help/settings/appearance-tab.png and b/assets/images/help/settings/appearance-tab.png differ diff --git a/assets/images/help/settings/theme-choose-a-day-and-night-theme-to-sync-highcontrast.png b/assets/images/help/settings/theme-choose-a-day-and-night-theme-to-sync-highcontrast.png new file mode 100644 index 0000000000..2a03f91fb7 Binary files /dev/null and b/assets/images/help/settings/theme-choose-a-day-and-night-theme-to-sync-highcontrast.png differ diff --git a/assets/images/help/settings/theme-choose-a-single-theme-highcontrast.png b/assets/images/help/settings/theme-choose-a-single-theme-highcontrast.png new file mode 100644 index 0000000000..85115399d6 Binary files /dev/null and b/assets/images/help/settings/theme-choose-a-single-theme-highcontrast.png differ diff --git a/content/codespaces/getting-started-with-codespaces/getting-started-with-your-dotnet-project.md b/content/codespaces/getting-started-with-codespaces/getting-started-with-your-dotnet-project.md index 4660cd35f4..4313c49d8e 100644 --- a/content/codespaces/getting-started-with-codespaces/getting-started-with-your-dotnet-project.md +++ b/content/codespaces/getting-started-with-codespaces/getting-started-with-your-dotnet-project.md @@ -198,7 +198,7 @@ With your dev container added and a basic understanding of what everything does, ## Step 4: Run your application -In the previous section, you used the `postCreateCommand` to installing a set of packages via pip3. With our dependencies now installed, we can run our application. +In the previous section, you used the `postCreateCommand` to install a set of packages via the `dotnet restore` command. With our dependencies now installed, we can run our application. 1. Run your application by pressing `F5` or entering `dotnet watch run` in your terminal. diff --git a/content/github/setting-up-and-managing-your-github-user-account/managing-user-account-settings/managing-your-theme-settings.md b/content/github/setting-up-and-managing-your-github-user-account/managing-user-account-settings/managing-your-theme-settings.md index 3bcb71a1b3..fc19a611d4 100644 --- a/content/github/setting-up-and-managing-your-github-user-account/managing-user-account-settings/managing-your-theme-settings.md +++ b/content/github/setting-up-and-managing-your-github-user-account/managing-user-account-settings/managing-your-theme-settings.md @@ -9,18 +9,27 @@ redirect_from: - /github/setting-up-and-managing-your-github-user-account/managing-your-theme-settings shortTitle: Manage theme settings --- -For choice and flexibility in how and when you use {% data variables.product.product_name %}, you can configure theme settings to change how {% data variables.product.product_name %} looks to you. You can choose from themes that are light or dark, or you can configure {% data variables.product.product_name %} to follow your system settings. You may want to use a dark theme to reduce power consumption on certain devices, to reduce eye strain in low-light conditions, or because you prefer how the theme looks. + +For choice and flexibility in how and when you use {% data variables.product.product_name %}, you can configure theme settings to change how {% data variables.product.product_name %} looks to you. You can choose from themes that are light or dark, or you can configure {% data variables.product.product_name %} to follow your system settings. + +You may want to use a dark theme to reduce power consumption on certain devices, to reduce eye strain in low-light conditions, or because you prefer how the theme looks.{% ifversion fpt or ghae-issue-4618 %} People with visual impairment may benefit from the dark high contrast theme, with greater contrast between foreground and background elements.{% endif %} + +{% ifversion fpt %}{% note %} + +**Note:** The dark high contrast theme is currently available as a public beta. You can enable the dark high contrast theme using feature preview. For more information, see "[Exploring beta releases with feature preview](/get-started/using-github/exploring-early-access-releases-with-feature-preview#exploring-beta-releases-with-feature-preview)." + +{% endnote %}{% endif %} {% data reusables.user_settings.access_settings %} 1. In the user settings sidebar, click **Appearance**. !["Appearance" tab in user settings sidebar](/assets/images/help/settings/appearance-tab.png) 1. Under "Theme mode", select the drop-down menu, then click a theme preference. ![Drop-down menu under "Theme mode" for selection of theme preference](/assets/images/help/settings/theme-mode-drop-down-menu.png) -1. Click the theme you'd like to use. +1. Click the theme you'd like to use.{% ifversion fpt %} If you'd like to use the dark high contrast theme, you must enable the theme in feature preview. For more information, see "[Exploring beta releases with feature preview](/get-started/using-github/exploring-early-access-releases-with-feature-preview#exploring-beta-releases-with-feature-preview)."{% endif %} - If you chose a single theme, click a theme. - ![Radio buttons for the choice of a single theme](/assets/images/help/settings/theme-choose-a-single-theme.png) + {% ifversion fpt or ghae-issue-4618 %}![Radio buttons for the choice of a single theme](/assets/images/help/settings/theme-choose-a-single-theme-highcontrast.png){% else %}![Radio buttons for the choice of a single theme](/assets/images/help/settings/theme-choose-a-single-theme.png){% endif %} - If you chose to follow your system settings, click a day theme and a night theme. - ![Buttons for the choice of a theme to sync with the system setting](/assets/images/help/settings/theme-choose-a-day-and-night-theme-to-sync.png) + {% ifversion fpt or ghae-issue-4618 %}![Buttons for the choice of a theme to sync with the system setting](/assets/images/help/settings/theme-choose-a-day-and-night-theme-to-sync-highcontrast.png){% else %}![Buttons for the choice of a theme to sync with the system setting](/assets/images/help/settings/theme-choose-a-day-and-night-theme-to-sync.png){% endif %} ## Further reading diff --git a/content/rest/overview/libraries.md b/content/rest/overview/libraries.md index debdc5c1d9..6babe42c1e 100644 --- a/content/rest/overview/libraries.md +++ b/content/rest/overview/libraries.md @@ -102,7 +102,6 @@ Library name | Repository | metacpan Website for the Library Library name | Repository |---|---| **PHP GitHub API**|[KnpLabs/php-github-api](https://github.com/KnpLabs/php-github-api) -**GitHub API**|[yiiext/github-api](https://github.com/yiiext/github-api) **GitHub Joomla! Package**|[joomla-framework/github-api](https://github.com/joomla-framework/github-api) **GitHub bridge for Laravel**|[GrahamCampbell/Laravel-GitHub](https://github.com/GrahamCampbell/Laravel-GitHub) diff --git a/middleware/archived-enterprise-versions-assets.js b/middleware/archived-enterprise-versions-assets.js index 81ca646078..0f7a449951 100644 --- a/middleware/archived-enterprise-versions-assets.js +++ b/middleware/archived-enterprise-versions-assets.js @@ -32,6 +32,6 @@ module.exports = async function archivedEnterpriseVersionsAssets (req, res, next res.set('cache-control', `public, max-age=${ONE_DAY}`) return res.send(r.body) } catch (err) { - return next() + return next(404) } } diff --git a/middleware/archived-enterprise-versions.js b/middleware/archived-enterprise-versions.js index c599a49db1..799bfad607 100644 --- a/middleware/archived-enterprise-versions.js +++ b/middleware/archived-enterprise-versions.js @@ -6,7 +6,7 @@ const versionSatisfiesRange = require('../lib/version-satisfies-range') const isArchivedVersion = require('../lib/is-archived-version') const got = require('got') const readJsonFile = require('../lib/read-json-file') -const archvivedRedirects = readJsonFile('./lib/redirects/static/archived-redirects-from-213-to-217.json') +const archivedRedirects = readJsonFile('./lib/redirects/static/archived-redirects-from-213-to-217.json') const archivedFrontmatterFallbacks = readJsonFile('./lib/redirects/static/archived-frontmatter-fallbacks.json') // This module handles requests for deprecated GitHub Enterprise versions @@ -29,54 +29,49 @@ module.exports = async function archivedEnterpriseVersions (req, res, next) { // starting with 2.18, we updated the archival script to create a redirects.json file if (versionSatisfiesRange(requestedVersion, `>=${firstVersionDeprecatedOnNewSite}`) && versionSatisfiesRange(requestedVersion, `<=${lastVersionWithoutArchivedRedirectsFile}`)) { - const redirect = archvivedRedirects[req.path] + const redirect = archivedRedirects[req.path] if (redirect && redirect !== req.path) { return res.redirect(301, redirect) } } - let reqPath = req.path - let isRedirect = false if (versionSatisfiesRange(requestedVersion, `>${lastVersionWithoutArchivedRedirectsFile}`)) { try { - const res = await got(getProxyPath('redirects.json', requestedVersion)) - const redirectJson = JSON.parse(res.body) + const r = await got(getProxyPath('redirects.json', requestedVersion)) + const redirectJson = JSON.parse(r.body) + // make redirects found via redirects.json redirect with a 301 if (redirectJson[req.path]) { - isRedirect = true + res.set('x-robots-tag', 'noindex') + return res.redirect(301, redirectJson[req.path]) } - reqPath = redirectJson[req.path] || req.path } catch (err) { - // nooop + // noop } } try { - const r = await got(getProxyPath(reqPath, requestedVersion)) - res.set('content-type', r.headers['content-type']) + const r = await got(getProxyPath(req.path, requestedVersion)) res.set('x-robots-tag', 'noindex') - // make redirects found via redirects.json return 301 instead of 200 - if (isRedirect) { - res.status(301) - res.set('location', reqPath) - } - - // make stubbed redirect files (which exist in versions <2.13) return 301 instead of 200 + // make stubbed redirect files (which exist in versions <2.13) redirect with a 301 const staticRedirect = r.body.match(patterns.staticRedirect) if (staticRedirect) { - res.status(301) - res.set('location', staticRedirect[1]) + return res.redirect(301, staticRedirect[1]) } + res.set('content-type', r.headers['content-type']) return res.send(r.body) } catch (err) { for (const fallbackRedirect of getFallbackRedirects(req, requestedVersion) || []) { try { await got(getProxyPath(fallbackRedirect, requestedVersion)) return res.redirect(301, fallbackRedirect) - } catch (err) { } // noop + } catch (err) { + // noop + } } + return next() } } diff --git a/middleware/handle-next-data-path.js b/middleware/handle-next-data-path.js index 3d73b24bb6..4c9028f087 100644 --- a/middleware/handle-next-data-path.js +++ b/middleware/handle-next-data-path.js @@ -15,5 +15,5 @@ module.exports = async function handleNextDataPath (req, res, next) { req.pagePath = req.path } - next() + return next() } diff --git a/middleware/index.js b/middleware/index.js index e6198c1826..963bbb3f5f 100644 --- a/middleware/index.js +++ b/middleware/index.js @@ -160,6 +160,10 @@ module.exports = function (app) { })) app.use('/events', asyncMiddleware(instrument(events, './events'))) app.use('/search', asyncMiddleware(instrument(search, './search'))) + + // Check for a dropped connection before proceeding (again) + app.use(haltOnDroppedConnection) + app.use(asyncMiddleware(instrument(archivedEnterpriseVersions, './archived-enterprise-versions'))) app.use(instrument(robots, './robots')) app.use(/(\/.*)?\/early-access$/, instrument(earlyAccessLinks, './contextualizers/early-access-links')) diff --git a/middleware/is-next-request.js b/middleware/is-next-request.js index 21764b7ccf..8297471377 100644 --- a/middleware/is-next-request.js +++ b/middleware/is-next-request.js @@ -1,11 +1,11 @@ -const { FEATURE_NEXTJS } = process.env; +const { FEATURE_NEXTJS } = process.env -module.exports = function isNextRequest(req, res, next) { - req.renderWithNextjs = false; +module.exports = function isNextRequest (req, res, next) { + req.renderWithNextjs = false if (FEATURE_NEXTJS) { - req.renderWithNextjs = true; + req.renderWithNextjs = true } - next(); -}; + return next() +} diff --git a/middleware/next.js b/middleware/next.js index 6a11d796f2..d3622df2b5 100644 --- a/middleware/next.js +++ b/middleware/next.js @@ -15,7 +15,7 @@ function renderPageWithNext (req, res, next) { return nextHandleRequest(req, res) } - next() + return next() } renderPageWithNext.nextHandleRequest = nextHandleRequest diff --git a/middleware/search.js b/middleware/search.js index c79f3ee2a3..6254d3e9b2 100644 --- a/middleware/search.js +++ b/middleware/search.js @@ -27,10 +27,17 @@ router.get('/', async function postSearch (req, res, next) { const results = process.env.AIRGAP || req.cookies.AIRGAP ? await loadLunrResults({ version, language, query: `${query} ${filters || ''}`, limit }) : await loadAlgoliaResults({ version, language, query, filters, limit }) - return res.status(200).json(results) + + // Only reply if the headers have not been sent and the request was not aborted... + if (!res.headersSent && !req.aborted) { + return res.status(200).json(results) + } } catch (err) { console.error(err) - return res.status(400).json([]) + // Only reply if the headers have not been sent and the request was not aborted... + if (!res.headersSent && !req.aborted) { + return res.status(400).json([]) + } } }) diff --git a/tests/routing/redirects.js b/tests/routing/redirects.js index 70ee627186..445bd89c95 100644 --- a/tests/routing/redirects.js +++ b/tests/routing/redirects.js @@ -191,7 +191,7 @@ describe('redirects', () => { test('frontmatter redirect', async () => { const res = await get('/enterprise/2.12/user/articles/github-flavored-markdown') expect(res.statusCode).toBe(301) - expect(res.text).toContain('location=\'/enterprise/2.12/user/categories/writing-on-github/\'') + expect(res.headers.location).toBe('/enterprise/2.12/user/categories/writing-on-github/') }) })