From a4fb8bb237c14648f70371695d575f5d571935fc Mon Sep 17 00:00:00 2001 From: Ramya Parimi <33761166+ramyaparimi@users.noreply.github.com> Date: Thu, 4 Nov 2021 15:54:55 -0500 Subject: [PATCH 1/4] Added versioning to the new content to fix broken links (#22621) * Update contexts.md * Update contexts.md * Update content/actions/learn-github-actions/contexts.md Co-authored-by: Sarita Iyer <66540150+saritai@users.noreply.github.com> * Update contexts.md added versioning to input context * Update contexts.md Co-authored-by: Sarita Iyer <66540150+saritai@users.noreply.github.com> --- content/actions/learn-github-actions/contexts.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/content/actions/learn-github-actions/contexts.md b/content/actions/learn-github-actions/contexts.md index fc138e59ba68..00cc525a76b8 100644 --- a/content/actions/learn-github-actions/contexts.md +++ b/content/actions/learn-github-actions/contexts.md @@ -41,7 +41,7 @@ Contexts are a way to access information about workflow runs, runner environment | `strategy` | `object` | Enables access to the configured strategy parameters and information about the current job. Strategy parameters include `fail-fast`, `job-index`, `job-total`, and `max-parallel`. | | `matrix` | `object` | Enables access to the matrix parameters you configured for the current job. For example, if you configure a matrix build with the `os` and `node` versions, the `matrix` context object includes the `os` and `node` versions of the current job. | | `needs` | `object` | Enables access to the outputs of all jobs that are defined as a dependency of the current job. For more information, see [`needs` context](#needs-context). | -| `inputs` | `object` | Enables access to the inputs of reusable workflow. For more information, see [`inputs` context](#inputs-context). | +{% ifversion fpt or ghec or ghes > 3.3 or ghae-issue-4757 %}| `inputs` | `object` | Enables access to the inputs of reusable workflow. For more information, see [`inputs` context](#inputs-context). |{% endif %} As part of an expression, you may access context information using one of two syntaxes. - Index syntax: `github['sha']` @@ -149,6 +149,7 @@ The `needs` context contains outputs from all jobs that are defined as a depende | `needs..outputs.` | `string` | The value of a specific output for a job that the current job depends on. | | `needs..result` | `string` | The result of a job that the current job depends on. Possible values are `success`, `failure`, `cancelled`, or `skipped`. | +{% ifversion fpt or ghec or ghes > 3.3 or ghae-issue-4757 %} ### `inputs` context The `inputs` context contains information about the inputs of reusable workflow. The inputs are defined in [`workflow_call` event configuration](/actions/learn-github-actions/events-that-trigger-workflows#workflow-reuse-events). These inputs are passed from [`jobs..with`](/actions/learn-github-actions/workflow-syntax-for-github-actions#jobsjob_idwith) in an external workflow. @@ -159,6 +160,7 @@ For more information, see "[Reusing workflows](/actions/learn-github-actions/reu |---------------|------|-------------| | `inputs` | `object` | This context is only available when it is [a reusable workflow](/actions/learn-github-actions/reusing-workflows). | | `inputs.` | `string` or `number` or `boolean` | Each input value passed from an external workflow. | +{% endif %} #### Example printing context information to the log file From cbcd38332352178c4f1377d3be19dad3083383da Mon Sep 17 00:00:00 2001 From: Rachael Sewell Date: Thu, 4 Nov 2021 14:05:11 -0700 Subject: [PATCH 2/4] add search QA tests (#22593) --- script/search/search-qa-data.json | 206 ++++++++++++++++++++++++++++++ script/search/search-qa-test.js | 93 ++++++++++++++ 2 files changed, 299 insertions(+) create mode 100644 script/search/search-qa-data.json create mode 100755 script/search/search-qa-test.js diff --git a/script/search/search-qa-data.json b/script/search/search-qa-data.json new file mode 100644 index 000000000000..107b9d9b7d78 --- /dev/null +++ b/script/search/search-qa-data.json @@ -0,0 +1,206 @@ +[ + { + "query": "interactions", + "href": "/rest/reference/interactions" + }, + { + "query": "repositories", + "href": "/rest/reference/repos" + }, + { + "query": "workflow_run", + "href": "/developers/webhooks-and-events/webhooks/webhook-events-and-payloads" + }, + { + "query": "workflow_dispatch", + "href": "/developers/webhooks-and-events/webhooks/webhook-events-and-payloads" + }, + { + "query": "pull_request", + "href": "/developers/webhooks-and-events/webhooks/webhook-events-and-payloads" + }, + { + "query": "workflow_run", + "href": "/actions/learn-github-actions/events-that-trigger-workflows" + }, + { + "query": "workflow_dispatch", + "href": "/actions/learn-github-actions/events-that-trigger-workflows" + }, + { + "query": "register for an account", + "href": "/get-started/signing-up-for-github/signing-up-for-a-new-github-account" + }, + { + "query": "registering on GitHub", + "href": "/get-started/signing-up-for-github/signing-up-for-a-new-github-account" + }, + { + "query": "signing up for a GitHub account", + "href": "/get-started/signing-up-for-github/signing-up-for-a-new-github-account" + }, + { + "query": "new account", + "href": "/get-started/signing-up-for-github/signing-up-for-a-new-github-account" + }, + { + "query": "create a GitHub account", + "href": "/get-started/signing-up-for-github/signing-up-for-a-new-github-account" + }, + { + "query": "apis", + "href": "/graphql" + }, + { + "query": "apis", + "href": "/rest" + }, + { + "query": "api", + "href": "/graphql" + }, + { + "query": "api", + "href": "/rest" + }, + { + "query": "create a new branch", + "href": "/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-and-deleting-branches-within-your-repository" + }, + { + "query": "fix merge conflict", + "href": "/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-using-the-command-line" + }, + { + "query": "conflicts", + "href": "/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-using-the-command-line" + }, + { + "query": "merge conflict", + "href": "/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-using-the-command-line" + }, + { + "query": "branch conflicts", + "href": "/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-using-the-command-line" + }, + { + "query": "conflicting files", + "href": "/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-using-the-command-line" + }, + { + "query": "resolve conflicts", + "href": "/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-using-the-command-line" + }, + { + "query": "fix merge conflict", + "href": "/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-on-github" + }, + { + "query": "conflicts", + "href": "/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-on-github" + }, + { + "query": "merge conflict", + "href": "/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-on-github" + }, + { + "query": "branch conflicts", + "href": "/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-on-github" + }, + { + "query": "conflicting files", + "href": "/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-on-github" + }, + { + "query": "resolve conflicts", + "href": "/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-on-github" + }, + { + "query": "actions billable minutes", + "href": "/billing/managing-billing-for-github-actions/about-billing-for-github-actions" + }, + { + "query": "actions trigger pull requests", + "href": "/actions/learn-github-actions/events-that-trigger-workflows" + }, + { + "query": "about teams", + "href": "/organizations/organizing-members-into-teams/about-teams" + }, + { + "query": "about organizations", + "href": "/organizations/collaborating-with-groups-in-organizations/about-organizations" + }, + { + "query": "create pages site", + "href": "/pages/getting-started-with-github-pages/creating-a-github-pages-site" + }, + { + "query": "create pages site", + "href": "/pages/setting-up-a-github-pages-site-with-jekyll/creating-a-github-pages-site-with-jekyll" + }, + { + "query": "make a team", + "href": "/organizations/organizing-members-into-teams/creating-a-team" + }, + { + "query": "new team", + "href": "/organizations/organizing-members-into-teams/creating-a-team" + }, + { + "query": "team", + "href": "/organizations/organizing-members-into-teams/about-teams" + }, + { + "query": "rest create issue", + "href": "/rest/reference/issues" + }, + { + "query": "fork", + "href": "/rest/reference/repos" + }, + { + "query": "commit email", + "href": "/account-and-profile/setting-up-and-managing-your-github-user-account/managing-email-preferences/setting-your-commit-email-address" + }, + { + "query": "graphql organization", + "href": "/graphql/reference/objects" + }, + { + "query": "device flow", + "href": "/developers/apps/building-oauth-apps/authorizing-oauth-apps" + }, + { + "query": "convert user", + "href": "/account-and-profile/setting-up-and-managing-your-github-user-account/managing-user-account-settings/converting-a-user-into-an-organization" + }, + { + "query": "add email", + "href": "/account-and-profile/setting-up-and-managing-your-github-user-account/managing-email-preferences/adding-an-email-address-to-your-github-account" + }, + { + "query": "transfer ownership", + "href": "/organizations/managing-organization-settings/transferring-organization-ownership" + }, + { + "query": "merge accounts", + "href": "/account-and-profile/setting-up-and-managing-your-github-user-account/managing-user-account-settings/merging-multiple-user-accounts" + }, + { + "query": "search syntax", + "href": "/search-github/getting-started-with-searching-on-github/understanding-the-search-syntax" + }, + { + "query": "scim okta", + "href": "/organizations/managing-saml-single-sign-on-for-your-organization/configuring-saml-single-sign-on-and-scim-using-okta" + }, + { + "query": "keeping your account and data secure", + "href": "/authentication/keeping-your-account-and-data-secure" + }, + { + "query": "ssh troubleshoot", + "href": "/authentication/troubleshooting-ssh" + } +] \ No newline at end of file diff --git a/script/search/search-qa-test.js b/script/search/search-qa-test.js new file mode 100755 index 000000000000..15476812d779 --- /dev/null +++ b/script/search/search-qa-test.js @@ -0,0 +1,93 @@ +#!/usr/bin/env node + +// [start-readme] +// +// This script is a quality assurance test for the Lunr search configuration. +// This test runs example queries and expects a specific page to land in the top +// 3 results. +// +// The data source used by this script is a JSON file `script/search/search-qa-data.json`, +// which is populated from spreadsheet data here: +// https://docs.google.com/spreadsheets/d/1Dt5JRVcmyAGWKBwGjwmXxi7Ww_vdfYLfZ-EFpu2S2CQ/edit?usp=sharing +// +// [end-readme] + +import loadLunrResults from '../../lib/search/lunr-search.js' +import { readFileSync } from 'fs' +import { join } from 'path' + +const queryData = JSON.parse(readFileSync(join(process.cwd(), 'script/search/search-qa-data.json'))) + +const version = 'dotcom' +const language = 'en' +const limit = 10 +const TOP_RANK = 3 + +main() + +async function main() { + const rankResults = [] + + for (const item in queryData) { + const { query, href } = queryData[item] + + try { + const results = await loadLunrResults({ + version, + language, + query, + limit, + }) + + const hrefs = results.map((result) => result.url.replace('/en', '')) + let rank = hrefs.indexOf(href) + // this allows us to sort the results by rank, including total misses + if (rank === -1) { + rank = limit + } + rankResults.push({ query, href, rank }) + } catch (err) { + console.error(err) + } + } + logResults(rankResults) +} + +async function logResults(results) { + results.sort((a, b) => a.rank - b.rank) + + let first = 0 + let top = 0 + let low = 0 + let miss = 0 + results.forEach((result) => { + const { query, href, rank } = result + if (rank === limit) { + miss++ + console.log(`🔴 query: ${query} - Expected href: ${href}\n`) + return + } + if (rank === 0) { + first++ + console.log(`⭐ Query: ${query} - Expected href: ${href}`) + return + } + if (rank < TOP_RANK) { + top++ + console.log(`🟢 Query: ${query} - Expected href: ${href}`) + return + } + low++ + console.log(`🟡 Query: ${query} - Expected href: ${href}`) + }) + + const firstPercentage = ((first / queryData.length) * 100).toFixed(1) + const topPercentage = ((top / queryData.length) * 100).toFixed(1) + const lowPercentage = ((low / queryData.length) * 100).toFixed(1) + const missPercentage = ((miss / queryData.length) * 100).toFixed(1) + + console.log(`\n⭐ First hit ${firstPercentage}%`) + console.log(`\n🟢 Top ${TOP_RANK} hit ${topPercentage}%`) + console.log(`\n🟡 Top ${limit} hit ${lowPercentage}%`) + console.log(`\n🔴 Miss ${missPercentage}%`) +} From c5df94c88bccbc1c7319ebea107f2ab720ca0bb1 Mon Sep 17 00:00:00 2001 From: Rachael Sewell Date: Thu, 4 Nov 2021 14:27:22 -0700 Subject: [PATCH 3/4] Crowdin broken liquid test (#22559) --- package-lock.json | 7 ++- package.json | 4 ++ script/i18n/test-html-pages.js | 80 ++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 4 deletions(-) create mode 100755 script/i18n/test-html-pages.js diff --git a/package-lock.json b/package-lock.json index ae664837dd8c..4365b5c8b75d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "accept-language-parser": "^1.5.0", "ajv": "^8.6.3", "ajv-formats": "^2.1.1", + "bottleneck": "^2.19.5", "browser-date-formatter": "^3.0.3", "change-case": "^4.1.2", "cheerio": "^1.0.0-rc.10", @@ -6134,8 +6135,7 @@ "node_modules/bottleneck": { "version": "2.19.5", "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", - "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", - "dev": true + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==" }, "node_modules/boxen": { "version": "5.1.2", @@ -27748,8 +27748,7 @@ "bottleneck": { "version": "2.19.5", "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", - "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", - "dev": true + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==" }, "boxen": { "version": "5.1.2", diff --git a/package.json b/package.json index 1a9703783b32..d9d5f13e677c 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "accept-language-parser": "^1.5.0", "ajv": "^8.6.3", "ajv-formats": "^2.1.1", + "bottleneck": "^2.19.5", "browser-date-formatter": "^3.0.3", "change-case": "^4.1.2", "cheerio": "^1.0.0-rc.10", @@ -219,6 +220,9 @@ "sync-search-ghes-release": "cross-env GHES_RELEASE=1 start-server-and-test sync-search-server 4002 sync-search-indices", "sync-search-indices": "script/sync-search-indices.js", "sync-search-server": "cross-env NODE_ENV=production WEB_CONCURRENCY=1 PORT=4002 node server.mjs", + "translation-check": "start-server-and-test translation-check-server 4002 translation-check-test", + "translation-check-server": "cross-env NODE_ENV=test PORT=4002 node server.mjs", + "translation-check-test": "script/i18n/test-html-pages.js", "test": "cross-env NODE_OPTIONS='--max_old_space_size=8192 --experimental-vm-modules' jest", "test-watch": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --watch --notify --notifyMode=change --coverage" }, diff --git a/script/i18n/test-html-pages.js b/script/i18n/test-html-pages.js new file mode 100755 index 000000000000..d10fb7588b12 --- /dev/null +++ b/script/i18n/test-html-pages.js @@ -0,0 +1,80 @@ +#!/usr/bin/env node +import dotenv from 'dotenv' +import got from 'got' +import Bottleneck from 'bottleneck' +import { loadPages } from '../../lib/page-data.js' +import { allVersions } from '../../lib/all-versions.js' +import languages from '../../lib/languages.js' +const port = 4002 + +dotenv.config() +/* + Good local testing values are MAX_CONCURRENT=30, MIN_TIME=20 +*/ +const MAX_CONCURRENT = parseInt(process.env.BUILD_RECORDS_MAX_CONCURRENT || '200', 10) +const MIN_TIME = parseInt(process.env.BUILD_RECORDS_MIN_TIME || '5', 10) +const languageCode = process.env.LANGUAGE +const singleVersion = process.env.VERSION + +main() + +async function main() { + const start = process.hrtime.bigint() + const opts = { + maxConcurrent: MAX_CONCURRENT, + minTime: MIN_TIME, + } + const limiter = new Bottleneck(opts) + const allPages = await loadPages() + const languageCodes = + [languageCode] || + Object.keys(languages) + .filter((language) => !language.wip && language !== 'en') + .map((language) => languages[language].code) + const versions = singleVersion ? [singleVersion] : Object.keys(allVersions) + + const allPermalinks = [] + for (const language of languageCodes) { + for (const version of versions) { + const pages = allPages.filter( + (page) => page.languageCode === language && page.applicableVersions.includes(version) + ) + + const permalinks = pages + .map((page) => { + return page.permalinks.find((permalink) => { + return permalink.languageCode === language && permalink.pageVersion === version + }) + }) + .map((permalink) => { + permalink.url = `http://localhost:${port}${permalink.href}` + return permalink + }) + allPermalinks.push(...permalinks) + } + } + allPermalinks.forEach((page) => { + limiter.schedule(getPage, page) + }) + + limiter + .on('idle', () => { + const end = process.hrtime.bigint() + console.log(`Took ${Number(end - start) / 1000000000}s`) + console.log('All done!') + }) + .on('error', (err) => { + console.log('error', err) + }) +} + +async function getPage(page) { + try { + const response = await got.get(page.url, { throwHttpErrors: false }) + if (response.statusCode !== 200) { + console.log('Status Code:', response.statusCode, 'Page: ', page.url) + } + } catch (err) { + console.error(err) + } +} From 116df3a328c47ad8c5a37b879bfac68acb924ba6 Mon Sep 17 00:00:00 2001 From: jmarlena <6732600+jmarlena@users.noreply.github.com> Date: Thu, 4 Nov 2021 14:40:33 -0700 Subject: [PATCH 4/4] GHES 2.2.2 release note update for releases page bug (#22629) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add first draft * Fix date of release note Co-authored-by: “jmarlena” <“jmarlena@github.com”> --- data/release-notes/enterprise-server/2-22/23.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 data/release-notes/enterprise-server/2-22/23.yml diff --git a/data/release-notes/enterprise-server/2-22/23.yml b/data/release-notes/enterprise-server/2-22/23.yml new file mode 100644 index 000000000000..78df9a1ccdb0 --- /dev/null +++ b/data/release-notes/enterprise-server/2-22/23.yml @@ -0,0 +1,13 @@ +date: '2021-11-04' +sections: + bugs: + - 'The {% data variables.product.prodname_github_connect %} configuration of the source instance was always restored to new instances even when the `--config` option for `ghe-restore` was not used. This would lead to a conflict with the {% data variables.product.prodname_github_connect %} connection and license synchronization if both the source and destination instances were online at the same time. {% comment %} https://github.com/github/github/pull/192247, https://github.com/github/github/pull/191951, https://github.com/github/enterprise2/pull/26870, https://github.com/github/backup-utils/pull/770, https://github.com/github/connected-enterprise/issues/208 {% endcomment %}' + - 'Fixes {% data variables.product.prodname_pages %} builds so they take into account the NO_PROXY setting of the appliance. This is relevant to appliances configured with an HTTP proxy only. {% comment %} https://github.com/github/github/pull/192380 {% endcomment %}' + known_issues: + - After saving a new release on a repository, the `/releases` page shows 500 error. A fix for this issue is expected to ship in 3.2.3. + - On a freshly set up {% data variables.product.prodname_ghe_server %} without any users, an attacker could create the first admin user. + - Custom firewall rules are removed during the upgrade process. + - Git LFS tracked files [uploaded through the web interface](https://github.com/blog/2105-upload-files-to-your-repositories) are incorrectly added directly to the repository. + - Issues cannot be closed if they contain a permalink to a blob in the same repository, where the blob's file path is longer than 255 characters. + - When "Users can search GitHub.com" is enabled with {% data variables.product.prodname_github_connect %}, issues in private and internal repositories are not included in GitHub.com search results. + - When a replica node is offline in a high availability configuration, {% data variables.product.product_name %} may still route {% data variables.product.prodname_pages %} requests to the offline node, reducing the availability of {% data variables.product.prodname_pages %} for users.